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.
This commit is contained in:
parent
282396f27a
commit
156692752d
105
Python/marshal.c
105
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);
|
||||
|
|
Loading…
Reference in New Issue