]> granicus.if.org Git - python/commitdiff
Removed calls to PyFloat_AsReprString.
authorEric Smith <eric@trueblade.com>
Mon, 19 Oct 2009 00:34:12 +0000 (00:34 +0000)
committerEric Smith <eric@trueblade.com>
Mon, 19 Oct 2009 00:34:12 +0000 (00:34 +0000)
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.

Python/marshal.c

index 1ef41b081b7a1dfda231d86edd9c0adfbe220dfb..ca2f9aa10f9bb8f2f53bdbd8afcfedddcb39e1e6 100644 (file)
 #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);