summaryrefslogtreecommitdiff
path: root/Python/marshal.c
diff options
context:
space:
mode:
authorEric Smith <eric@trueblade.com>2009-10-19 00:34:12 +0000
committerEric Smith <eric@trueblade.com>2009-10-19 00:34:12 +0000
commit2af0b6cc2b280eb210c38d9567ab6a82a1b4d059 (patch)
treee9ea106be102de8ac37d0d5bda3622bf1ae1b226 /Python/marshal.c
parent5d5f8fa71264839366baa0d693335c129c3b4d63 (diff)
downloadcpython-2af0b6cc2b280eb210c38d9567ab6a82a1b4d059.tar.gz
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/marshal.c')
-rw-r--r--Python/marshal.c105
1 files changed, 63 insertions, 42 deletions
diff --git a/Python/marshal.c b/Python/marshal.c
index 1ef41b081b..ca2f9aa10f 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);