diff options
author | Eric Smith <eric@trueblade.com> | 2009-10-19 00:34:12 (GMT) |
---|---|---|
committer | Eric Smith <eric@trueblade.com> | 2009-10-19 00:34:12 (GMT) |
commit | 156692752db98a2e31c4e00f59072b9f221eb9a9 (patch) | |
tree | eff88be00feaa48b35b3e54c376fb5758a5fb26f /Python | |
parent | 282396f27addf4ae6586865ccf449f60753a106c (diff) | |
download | cpython-156692752db98a2e31c4e00f59072b9f221eb9a9.zip cpython-156692752db98a2e31c4e00f59072b9f221eb9a9.tar.gz cpython-156692752db98a2e31c4e00f59072b9f221eb9a9.tar.bz2 |
Removed calls to PyFloat_AsReprString.
This is in anticipation of possibly implementing issue 7117 (short float repr).
This removes the last calls to PyFloat_AsString, PyFloat_AsReprString, and
PyFloat_AsStringEx, which are unsafe.
Also, switch to defines for error values to bring this code more in line
with the py3k branch.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/marshal.c | 105 |
1 files changed, 63 insertions, 42 deletions
diff --git a/Python/marshal.c b/Python/marshal.c index 1ef41b0..ca2f9aa 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -44,9 +44,14 @@ #define TYPE_SET '<' #define TYPE_FROZENSET '>' +#define WFERR_OK 0 +#define WFERR_UNMARSHALLABLE 1 +#define WFERR_NESTEDTOODEEP 2 +#define WFERR_NOMEMORY 3 + typedef struct { FILE *fp; - int error; + int error; /* see WFERR_* values */ int depth; /* If fp == NULL, the following are valid: */ PyObject *str; @@ -179,7 +184,7 @@ w_object(PyObject *v, WFILE *p) p->depth++; if (p->depth > MAX_MARSHAL_STACK_DEPTH) { - p->error = 2; + p->error = WFERR_NESTEDTOODEEP; } else if (v == NULL) { w_byte(TYPE_NULL, p); @@ -223,19 +228,24 @@ w_object(PyObject *v, WFILE *p) unsigned char buf[8]; if (_PyFloat_Pack8(PyFloat_AsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_BINARY_FLOAT, p); w_string((char*)buf, 8, p); } else { - char buf[256]; /* Plenty to format any double */ - PyFloat_AsReprString(buf, (PyFloatObject *)v); + char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v), + 'g', 17, 0, NULL); + if (!buf) { + p->error = WFERR_NOMEMORY; + return; + } n = strlen(buf); w_byte(TYPE_FLOAT, p); w_byte((int)n, p); w_string(buf, (int)n, p); + PyMem_Free(buf); } } #ifndef WITHOUT_COMPLEX @@ -244,44 +254,41 @@ w_object(PyObject *v, WFILE *p) unsigned char buf[8]; if (_PyFloat_Pack8(PyComplex_RealAsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_BINARY_COMPLEX, p); w_string((char*)buf, 8, p); if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), buf, 1) < 0) { - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_string((char*)buf, 8, p); } else { - char buf[256]; /* Plenty to format any double */ - PyFloatObject *temp; + char *buf; w_byte(TYPE_COMPLEX, p); - temp = (PyFloatObject*)PyFloat_FromDouble( - PyComplex_RealAsDouble(v)); - if (!temp) { - p->error = 1; + buf = PyOS_double_to_string(PyComplex_RealAsDouble(v), + 'g', 17, 0, NULL); + if (!buf) { + p->error = WFERR_NOMEMORY; return; } - PyFloat_AsReprString(buf, temp); - Py_DECREF(temp); n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); - temp = (PyFloatObject*)PyFloat_FromDouble( - PyComplex_ImagAsDouble(v)); - if (!temp) { - p->error = 1; + PyMem_Free(buf); + buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v), + 'g', 17, 0, NULL); + if (!buf) { + p->error = WFERR_NOMEMORY; return; } - PyFloat_AsReprString(buf, temp); - Py_DECREF(temp); n = strlen(buf); w_byte((int)n, p); w_string(buf, (int)n, p); + PyMem_Free(buf); } } #endif @@ -302,7 +309,7 @@ w_object(PyObject *v, WFILE *p) Py_XDECREF(o); if (!ok) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_INTERNED, p); @@ -315,7 +322,7 @@ w_object(PyObject *v, WFILE *p) if (n > INT_MAX) { /* huge strings are not supported */ p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -327,14 +334,14 @@ w_object(PyObject *v, WFILE *p) utf8 = PyUnicode_AsUTF8String(v); if (utf8 == NULL) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_byte(TYPE_UNICODE, p); n = PyString_GET_SIZE(utf8); if (n > INT_MAX) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -380,14 +387,14 @@ w_object(PyObject *v, WFILE *p) n = PyObject_Size(v); if (n == -1) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); it = PyObject_GetIter(v); if (it == NULL) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } while ((value = PyIter_Next(it)) != NULL) { @@ -397,7 +404,7 @@ w_object(PyObject *v, WFILE *p) Py_DECREF(it); if (PyErr_Occurred()) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } } @@ -427,7 +434,7 @@ w_object(PyObject *v, WFILE *p) n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s); if (n > INT_MAX) { p->depth--; - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; return; } w_long((long)n, p); @@ -435,7 +442,7 @@ w_object(PyObject *v, WFILE *p) } else { w_byte(TYPE_UNKNOWN, p); - p->error = 1; + p->error = WFERR_UNMARSHALLABLE; } exit: p->depth--; @@ -447,7 +454,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version) { WFILE wf; wf.fp = fp; - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.strings = NULL; wf.version = version; @@ -459,7 +466,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) { WFILE wf; wf.fp = fp; - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.strings = (version > 0) ? PyDict_New() : NULL; wf.version = version; @@ -1184,6 +1191,24 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len) return result; } +static void +set_error(int error) +{ + switch (error) { + case WFERR_NOMEMORY: + PyErr_NoMemory(); + break; + case WFERR_UNMARSHALLABLE: + PyErr_SetString(PyExc_ValueError, "unmarshallable object"); + break; + case WFERR_NESTEDTOODEEP: + default: + PyErr_SetString(PyExc_ValueError, + "object too deeply nested to marshal"); + break; + } +} + PyObject * PyMarshal_WriteObjectToString(PyObject *x, int version) { @@ -1194,7 +1219,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) return NULL; wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str); wf.end = wf.ptr + PyString_Size(wf.str); - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.version = version; wf.strings = (version > 0) ? PyDict_New() : NULL; @@ -1210,11 +1235,9 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) } _PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)); } - if (wf.error) { + if (wf.error != WFERR_OK) { Py_XDECREF(wf.str); - PyErr_SetString(PyExc_ValueError, - (wf.error==1)?"unmarshallable object" - :"object too deeply nested to marshal"); + set_error(wf.error); return NULL; } return wf.str; @@ -1239,16 +1262,14 @@ marshal_dump(PyObject *self, PyObject *args) wf.fp = PyFile_AsFile(f); wf.str = NULL; wf.ptr = wf.end = NULL; - wf.error = 0; + wf.error = WFERR_OK; wf.depth = 0; wf.strings = (version > 0) ? PyDict_New() : 0; wf.version = version; w_object(x, &wf); Py_XDECREF(wf.strings); - if (wf.error) { - PyErr_SetString(PyExc_ValueError, - (wf.error==1)?"unmarshallable object" - :"object too deeply nested to marshal"); + if (wf.error != WFERR_OK) { + set_error(wf.error); return NULL; } Py_INCREF(Py_None); |