Commit 15669275 authored by Eric Smith's avatar Eric Smith

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.
parent 282396f2
...@@ -44,9 +44,14 @@ ...@@ -44,9 +44,14 @@
#define TYPE_SET '<' #define TYPE_SET '<'
#define TYPE_FROZENSET '>' #define TYPE_FROZENSET '>'
#define WFERR_OK 0
#define WFERR_UNMARSHALLABLE 1
#define WFERR_NESTEDTOODEEP 2
#define WFERR_NOMEMORY 3
typedef struct { typedef struct {
FILE *fp; FILE *fp;
int error; int error; /* see WFERR_* values */
int depth; int depth;
/* If fp == NULL, the following are valid: */ /* If fp == NULL, the following are valid: */
PyObject *str; PyObject *str;
...@@ -179,7 +184,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -179,7 +184,7 @@ w_object(PyObject *v, WFILE *p)
p->depth++; p->depth++;
if (p->depth > MAX_MARSHAL_STACK_DEPTH) { if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
p->error = 2; p->error = WFERR_NESTEDTOODEEP;
} }
else if (v == NULL) { else if (v == NULL) {
w_byte(TYPE_NULL, p); w_byte(TYPE_NULL, p);
...@@ -223,19 +228,24 @@ w_object(PyObject *v, WFILE *p) ...@@ -223,19 +228,24 @@ w_object(PyObject *v, WFILE *p)
unsigned char buf[8]; unsigned char buf[8];
if (_PyFloat_Pack8(PyFloat_AsDouble(v), if (_PyFloat_Pack8(PyFloat_AsDouble(v),
buf, 1) < 0) { buf, 1) < 0) {
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_byte(TYPE_BINARY_FLOAT, p); w_byte(TYPE_BINARY_FLOAT, p);
w_string((char*)buf, 8, p); w_string((char*)buf, 8, p);
} }
else { else {
char buf[256]; /* Plenty to format any double */ char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
PyFloat_AsReprString(buf, (PyFloatObject *)v); 'g', 17, 0, NULL);
if (!buf) {
p->error = WFERR_NOMEMORY;
return;
}
n = strlen(buf); n = strlen(buf);
w_byte(TYPE_FLOAT, p); w_byte(TYPE_FLOAT, p);
w_byte((int)n, p); w_byte((int)n, p);
w_string(buf, (int)n, p); w_string(buf, (int)n, p);
PyMem_Free(buf);
} }
} }
#ifndef WITHOUT_COMPLEX #ifndef WITHOUT_COMPLEX
...@@ -244,44 +254,41 @@ w_object(PyObject *v, WFILE *p) ...@@ -244,44 +254,41 @@ w_object(PyObject *v, WFILE *p)
unsigned char buf[8]; unsigned char buf[8];
if (_PyFloat_Pack8(PyComplex_RealAsDouble(v), if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
buf, 1) < 0) { buf, 1) < 0) {
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_byte(TYPE_BINARY_COMPLEX, p); w_byte(TYPE_BINARY_COMPLEX, p);
w_string((char*)buf, 8, p); w_string((char*)buf, 8, p);
if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
buf, 1) < 0) { buf, 1) < 0) {
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_string((char*)buf, 8, p); w_string((char*)buf, 8, p);
} }
else { else {
char buf[256]; /* Plenty to format any double */ char *buf;
PyFloatObject *temp;
w_byte(TYPE_COMPLEX, p); w_byte(TYPE_COMPLEX, p);
temp = (PyFloatObject*)PyFloat_FromDouble( buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
PyComplex_RealAsDouble(v)); 'g', 17, 0, NULL);
if (!temp) { if (!buf) {
p->error = 1; p->error = WFERR_NOMEMORY;
return; return;
} }
PyFloat_AsReprString(buf, temp);
Py_DECREF(temp);
n = strlen(buf); n = strlen(buf);
w_byte((int)n, p); w_byte((int)n, p);
w_string(buf, (int)n, p); w_string(buf, (int)n, p);
temp = (PyFloatObject*)PyFloat_FromDouble( PyMem_Free(buf);
PyComplex_ImagAsDouble(v)); buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
if (!temp) { 'g', 17, 0, NULL);
p->error = 1; if (!buf) {
p->error = WFERR_NOMEMORY;
return; return;
} }
PyFloat_AsReprString(buf, temp);
Py_DECREF(temp);
n = strlen(buf); n = strlen(buf);
w_byte((int)n, p); w_byte((int)n, p);
w_string(buf, (int)n, p); w_string(buf, (int)n, p);
PyMem_Free(buf);
} }
} }
#endif #endif
...@@ -302,7 +309,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -302,7 +309,7 @@ w_object(PyObject *v, WFILE *p)
Py_XDECREF(o); Py_XDECREF(o);
if (!ok) { if (!ok) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_byte(TYPE_INTERNED, p); w_byte(TYPE_INTERNED, p);
...@@ -315,7 +322,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -315,7 +322,7 @@ w_object(PyObject *v, WFILE *p)
if (n > INT_MAX) { if (n > INT_MAX) {
/* huge strings are not supported */ /* huge strings are not supported */
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_long((long)n, p); w_long((long)n, p);
...@@ -327,14 +334,14 @@ w_object(PyObject *v, WFILE *p) ...@@ -327,14 +334,14 @@ w_object(PyObject *v, WFILE *p)
utf8 = PyUnicode_AsUTF8String(v); utf8 = PyUnicode_AsUTF8String(v);
if (utf8 == NULL) { if (utf8 == NULL) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_byte(TYPE_UNICODE, p); w_byte(TYPE_UNICODE, p);
n = PyString_GET_SIZE(utf8); n = PyString_GET_SIZE(utf8);
if (n > INT_MAX) { if (n > INT_MAX) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_long((long)n, p); w_long((long)n, p);
...@@ -380,14 +387,14 @@ w_object(PyObject *v, WFILE *p) ...@@ -380,14 +387,14 @@ w_object(PyObject *v, WFILE *p)
n = PyObject_Size(v); n = PyObject_Size(v);
if (n == -1) { if (n == -1) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_long((long)n, p); w_long((long)n, p);
it = PyObject_GetIter(v); it = PyObject_GetIter(v);
if (it == NULL) { if (it == NULL) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
while ((value = PyIter_Next(it)) != NULL) { while ((value = PyIter_Next(it)) != NULL) {
...@@ -397,7 +404,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -397,7 +404,7 @@ w_object(PyObject *v, WFILE *p)
Py_DECREF(it); Py_DECREF(it);
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
} }
...@@ -427,7 +434,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -427,7 +434,7 @@ w_object(PyObject *v, WFILE *p)
n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s); n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
if (n > INT_MAX) { if (n > INT_MAX) {
p->depth--; p->depth--;
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
return; return;
} }
w_long((long)n, p); w_long((long)n, p);
...@@ -435,7 +442,7 @@ w_object(PyObject *v, WFILE *p) ...@@ -435,7 +442,7 @@ w_object(PyObject *v, WFILE *p)
} }
else { else {
w_byte(TYPE_UNKNOWN, p); w_byte(TYPE_UNKNOWN, p);
p->error = 1; p->error = WFERR_UNMARSHALLABLE;
} }
exit: exit:
p->depth--; p->depth--;
...@@ -447,7 +454,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version) ...@@ -447,7 +454,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
{ {
WFILE wf; WFILE wf;
wf.fp = fp; wf.fp = fp;
wf.error = 0; wf.error = WFERR_OK;
wf.depth = 0; wf.depth = 0;
wf.strings = NULL; wf.strings = NULL;
wf.version = version; wf.version = version;
...@@ -459,7 +466,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version) ...@@ -459,7 +466,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
{ {
WFILE wf; WFILE wf;
wf.fp = fp; wf.fp = fp;
wf.error = 0; wf.error = WFERR_OK;
wf.depth = 0; wf.depth = 0;
wf.strings = (version > 0) ? PyDict_New() : NULL; wf.strings = (version > 0) ? PyDict_New() : NULL;
wf.version = version; wf.version = version;
...@@ -1184,6 +1191,24 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len) ...@@ -1184,6 +1191,24 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
return result; 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 * PyObject *
PyMarshal_WriteObjectToString(PyObject *x, int version) PyMarshal_WriteObjectToString(PyObject *x, int version)
{ {
...@@ -1194,7 +1219,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) ...@@ -1194,7 +1219,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
return NULL; return NULL;
wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str); wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
wf.end = wf.ptr + PyString_Size(wf.str); wf.end = wf.ptr + PyString_Size(wf.str);
wf.error = 0; wf.error = WFERR_OK;
wf.depth = 0; wf.depth = 0;
wf.version = version; wf.version = version;
wf.strings = (version > 0) ? PyDict_New() : NULL; wf.strings = (version > 0) ? PyDict_New() : NULL;
...@@ -1210,11 +1235,9 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) ...@@ -1210,11 +1235,9 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
} }
_PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)); _PyString_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base));
} }
if (wf.error) { if (wf.error != WFERR_OK) {
Py_XDECREF(wf.str); Py_XDECREF(wf.str);
PyErr_SetString(PyExc_ValueError, set_error(wf.error);
(wf.error==1)?"unmarshallable object"
:"object too deeply nested to marshal");
return NULL; return NULL;
} }
return wf.str; return wf.str;
...@@ -1239,16 +1262,14 @@ marshal_dump(PyObject *self, PyObject *args) ...@@ -1239,16 +1262,14 @@ marshal_dump(PyObject *self, PyObject *args)
wf.fp = PyFile_AsFile(f); wf.fp = PyFile_AsFile(f);
wf.str = NULL; wf.str = NULL;
wf.ptr = wf.end = NULL; wf.ptr = wf.end = NULL;
wf.error = 0; wf.error = WFERR_OK;
wf.depth = 0; wf.depth = 0;
wf.strings = (version > 0) ? PyDict_New() : 0; wf.strings = (version > 0) ? PyDict_New() : 0;
wf.version = version; wf.version = version;
w_object(x, &wf); w_object(x, &wf);
Py_XDECREF(wf.strings); Py_XDECREF(wf.strings);
if (wf.error) { if (wf.error != WFERR_OK) {
PyErr_SetString(PyExc_ValueError, set_error(wf.error);
(wf.error==1)?"unmarshallable object"
:"object too deeply nested to marshal");
return NULL; return NULL;
} }
Py_INCREF(Py_None); Py_INCREF(Py_None);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment