Fix bug in marshal where bad data would cause a segfault due to
lack of an infinite recursion check. Contributed by Damien Miller at Google.
This commit is contained in:
parent
f1135f30f8
commit
b1a9b37aa8
|
@ -220,6 +220,10 @@ class BugsTestCase(unittest.TestCase):
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def test_recursion(self):
|
||||||
|
s = 'c' + ('X' * 4*4) + '{' * 2**20
|
||||||
|
self.assertRaises(ValueError, marshal.loads, s)
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
test_support.run_unittest(IntTestCase,
|
test_support.run_unittest(IntTestCase,
|
||||||
FloatTestCase,
|
FloatTestCase,
|
||||||
|
|
|
@ -429,6 +429,7 @@ Dieter Maurer
|
||||||
Greg McFarlane
|
Greg McFarlane
|
||||||
Michael McLay
|
Michael McLay
|
||||||
Gordon McMillan
|
Gordon McMillan
|
||||||
|
Damien Miller
|
||||||
Jay T. Miller
|
Jay T. Miller
|
||||||
Chris McDonough
|
Chris McDonough
|
||||||
Andrew McNamara
|
Andrew McNamara
|
||||||
|
|
|
@ -207,6 +207,9 @@ Core and builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Fix bug in marshal where bad data would cause a segfault due to
|
||||||
|
lack of an infinite recursion check.
|
||||||
|
|
||||||
- Removed plat-freebsd2 and plat-freebsd3 directories (and IN.py in
|
- Removed plat-freebsd2 and plat-freebsd3 directories (and IN.py in
|
||||||
the directories).
|
the directories).
|
||||||
|
|
||||||
|
|
225
Python/marshal.c
225
Python/marshal.c
|
@ -246,9 +246,16 @@ w_object(PyObject *v, WFILE *p)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int ok;
|
||||||
o = PyInt_FromSsize_t(PyDict_Size(p->strings));
|
o = PyInt_FromSsize_t(PyDict_Size(p->strings));
|
||||||
PyDict_SetItem(p->strings, v, o);
|
ok = o &&
|
||||||
Py_DECREF(o);
|
PyDict_SetItem(p->strings, v, o) >= 0;
|
||||||
|
Py_XDECREF(o);
|
||||||
|
if (!ok) {
|
||||||
|
p->depth--;
|
||||||
|
p->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
w_byte(TYPE_INTERNED, p);
|
w_byte(TYPE_INTERNED, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,7 +420,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
|
||||||
|
|
||||||
typedef WFILE RFILE; /* Same struct with different invariants */
|
typedef WFILE RFILE; /* Same struct with different invariants */
|
||||||
|
|
||||||
#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
|
#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
|
||||||
|
|
||||||
#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
|
#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
|
||||||
|
|
||||||
|
@ -504,42 +511,60 @@ r_object(RFILE *p)
|
||||||
PyObject *v, *v2, *v3;
|
PyObject *v, *v2, *v3;
|
||||||
long i, n;
|
long i, n;
|
||||||
int type = r_byte(p);
|
int type = r_byte(p);
|
||||||
|
PyObject *retval;
|
||||||
|
|
||||||
|
p->depth++;
|
||||||
|
|
||||||
|
if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
|
||||||
|
p->depth--;
|
||||||
|
PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
||||||
case EOF:
|
case EOF:
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_NULL:
|
case TYPE_NULL:
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_NONE:
|
case TYPE_NONE:
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
retval = Py_None;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_STOPITER:
|
case TYPE_STOPITER:
|
||||||
Py_INCREF(PyExc_StopIteration);
|
Py_INCREF(PyExc_StopIteration);
|
||||||
return PyExc_StopIteration;
|
retval = PyExc_StopIteration;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_ELLIPSIS:
|
case TYPE_ELLIPSIS:
|
||||||
Py_INCREF(Py_Ellipsis);
|
Py_INCREF(Py_Ellipsis);
|
||||||
return Py_Ellipsis;
|
retval = Py_Ellipsis;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_FALSE:
|
case TYPE_FALSE:
|
||||||
Py_INCREF(Py_False);
|
Py_INCREF(Py_False);
|
||||||
return Py_False;
|
retval = Py_False;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_TRUE:
|
case TYPE_TRUE:
|
||||||
Py_INCREF(Py_True);
|
Py_INCREF(Py_True);
|
||||||
return Py_True;
|
retval = Py_True;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
return PyInt_FromLong(r_long(p));
|
retval = PyInt_FromLong(r_long(p));
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_INT64:
|
case TYPE_INT64:
|
||||||
return r_long64(p);
|
retval = r_long64(p);
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_LONG:
|
case TYPE_LONG:
|
||||||
{
|
{
|
||||||
|
@ -549,12 +574,15 @@ r_object(RFILE *p)
|
||||||
if (n < -INT_MAX || n > INT_MAX) {
|
if (n < -INT_MAX || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"bad marshal data");
|
"bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
size = n<0 ? -n : n;
|
size = n<0 ? -n : n;
|
||||||
ob = _PyLong_New(size);
|
ob = _PyLong_New(size);
|
||||||
if (ob == NULL)
|
if (ob == NULL) {
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
ob->ob_size = n;
|
ob->ob_size = n;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
int digit = r_short(p);
|
int digit = r_short(p);
|
||||||
|
@ -562,11 +590,14 @@ r_object(RFILE *p)
|
||||||
Py_DECREF(ob);
|
Py_DECREF(ob);
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"bad marshal data");
|
"bad marshal data");
|
||||||
return NULL;
|
ob = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
ob->ob_digit[i] = digit;
|
if (ob != NULL)
|
||||||
|
ob->ob_digit[i] = digit;
|
||||||
}
|
}
|
||||||
return (PyObject *)ob;
|
retval = (PyObject *)ob;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
|
@ -577,13 +608,16 @@ r_object(RFILE *p)
|
||||||
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
PyFPE_START_PROTECT("atof", return 0)
|
retval = NULL;
|
||||||
|
PyFPE_START_PROTECT("atof", break)
|
||||||
dx = PyOS_ascii_atof(buf);
|
dx = PyOS_ascii_atof(buf);
|
||||||
PyFPE_END_PROTECT(dx)
|
PyFPE_END_PROTECT(dx)
|
||||||
return PyFloat_FromDouble(dx);
|
retval = PyFloat_FromDouble(dx);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_BINARY_FLOAT:
|
case TYPE_BINARY_FLOAT:
|
||||||
|
@ -593,13 +627,16 @@ r_object(RFILE *p)
|
||||||
if (r_string((char*)buf, 8, p) != 8) {
|
if (r_string((char*)buf, 8, p) != 8) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
x = _PyFloat_Unpack8(buf, 1);
|
x = _PyFloat_Unpack8(buf, 1);
|
||||||
if (x == -1.0 && PyErr_Occurred()) {
|
if (x == -1.0 && PyErr_Occurred()) {
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return PyFloat_FromDouble(x);
|
retval = PyFloat_FromDouble(x);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WITHOUT_COMPLEX
|
#ifndef WITHOUT_COMPLEX
|
||||||
|
@ -611,23 +648,27 @@ r_object(RFILE *p)
|
||||||
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
PyFPE_START_PROTECT("atof", return 0)
|
retval = NULL;
|
||||||
|
PyFPE_START_PROTECT("atof", break;)
|
||||||
c.real = PyOS_ascii_atof(buf);
|
c.real = PyOS_ascii_atof(buf);
|
||||||
PyFPE_END_PROTECT(c)
|
PyFPE_END_PROTECT(c)
|
||||||
n = r_byte(p);
|
n = r_byte(p);
|
||||||
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
if (n == EOF || r_string(buf, (int)n, p) != n) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
PyFPE_START_PROTECT("atof", return 0)
|
PyFPE_START_PROTECT("atof", break)
|
||||||
c.imag = PyOS_ascii_atof(buf);
|
c.imag = PyOS_ascii_atof(buf);
|
||||||
PyFPE_END_PROTECT(c)
|
PyFPE_END_PROTECT(c)
|
||||||
return PyComplex_FromCComplex(c);
|
retval = PyComplex_FromCComplex(c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TYPE_BINARY_COMPLEX:
|
case TYPE_BINARY_COMPLEX:
|
||||||
|
@ -637,22 +678,27 @@ r_object(RFILE *p)
|
||||||
if (r_string((char*)buf, 8, p) != 8) {
|
if (r_string((char*)buf, 8, p) != 8) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
c.real = _PyFloat_Unpack8(buf, 1);
|
c.real = _PyFloat_Unpack8(buf, 1);
|
||||||
if (c.real == -1.0 && PyErr_Occurred()) {
|
if (c.real == -1.0 && PyErr_Occurred()) {
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (r_string((char*)buf, 8, p) != 8) {
|
if (r_string((char*)buf, 8, p) != 8) {
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
c.imag = _PyFloat_Unpack8(buf, 1);
|
c.imag = _PyFloat_Unpack8(buf, 1);
|
||||||
if (c.imag == -1.0 && PyErr_Occurred()) {
|
if (c.imag == -1.0 && PyErr_Occurred()) {
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return PyComplex_FromCComplex(c);
|
retval = PyComplex_FromCComplex(c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -661,32 +707,42 @@ r_object(RFILE *p)
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0 || n > INT_MAX) {
|
if (n < 0 || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyString_FromStringAndSize((char *)NULL, n);
|
v = PyString_FromStringAndSize((char *)NULL, n);
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return v;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
|
if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (type == TYPE_INTERNED) {
|
if (type == TYPE_INTERNED) {
|
||||||
PyString_InternInPlace(&v);
|
PyString_InternInPlace(&v);
|
||||||
PyList_Append(p->strings, v);
|
if (PyList_Append(p->strings, v) < 0) {
|
||||||
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_STRINGREF:
|
case TYPE_STRINGREF:
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
|
if (n < 0 || n >= PyList_GET_SIZE(p->strings)) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyList_GET_ITEM(p->strings, n);
|
v = PyList_GET_ITEM(p->strings, n);
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
#ifdef Py_USING_UNICODE
|
#ifdef Py_USING_UNICODE
|
||||||
case TYPE_UNICODE:
|
case TYPE_UNICODE:
|
||||||
|
@ -696,20 +752,25 @@ r_object(RFILE *p)
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0 || n > INT_MAX) {
|
if (n < 0 || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
buffer = PyMem_NEW(char, n);
|
buffer = PyMem_NEW(char, n);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL) {
|
||||||
return PyErr_NoMemory();
|
retval = PyErr_NoMemory();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (r_string(buffer, (int)n, p) != n) {
|
if (r_string(buffer, (int)n, p) != n) {
|
||||||
PyMem_DEL(buffer);
|
PyMem_DEL(buffer);
|
||||||
PyErr_SetString(PyExc_EOFError,
|
PyErr_SetString(PyExc_EOFError,
|
||||||
"EOF read where object expected");
|
"EOF read where object expected");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyUnicode_DecodeUTF8(buffer, n, NULL);
|
v = PyUnicode_DecodeUTF8(buffer, n, NULL);
|
||||||
PyMem_DEL(buffer);
|
PyMem_DEL(buffer);
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -717,11 +778,14 @@ r_object(RFILE *p)
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0 || n > INT_MAX) {
|
if (n < 0 || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyTuple_New((int)n);
|
v = PyTuple_New((int)n);
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return v;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
v2 = r_object(p);
|
v2 = r_object(p);
|
||||||
if ( v2 == NULL ) {
|
if ( v2 == NULL ) {
|
||||||
|
@ -734,17 +798,21 @@ r_object(RFILE *p)
|
||||||
}
|
}
|
||||||
PyTuple_SET_ITEM(v, (int)i, v2);
|
PyTuple_SET_ITEM(v, (int)i, v2);
|
||||||
}
|
}
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0 || n > INT_MAX) {
|
if (n < 0 || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyList_New((int)n);
|
v = PyList_New((int)n);
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return v;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
v2 = r_object(p);
|
v2 = r_object(p);
|
||||||
if ( v2 == NULL ) {
|
if ( v2 == NULL ) {
|
||||||
|
@ -755,14 +823,17 @@ r_object(RFILE *p)
|
||||||
v = NULL;
|
v = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PyList_SetItem(v, (int)i, v2);
|
PyList_SET_ITEM(v, (int)i, v2);
|
||||||
}
|
}
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_DICT:
|
case TYPE_DICT:
|
||||||
v = PyDict_New();
|
v = PyDict_New();
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
PyObject *key, *val;
|
PyObject *key, *val;
|
||||||
key = r_object(p);
|
key = r_object(p);
|
||||||
|
@ -778,18 +849,22 @@ r_object(RFILE *p)
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
v = NULL;
|
v = NULL;
|
||||||
}
|
}
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_SET:
|
case TYPE_SET:
|
||||||
case TYPE_FROZENSET:
|
case TYPE_FROZENSET:
|
||||||
n = r_long(p);
|
n = r_long(p);
|
||||||
if (n < 0) {
|
if (n < 0 || n > INT_MAX) {
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
v = PyTuple_New((int)n);
|
v = PyTuple_New((int)n);
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return v;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
v2 = r_object(p);
|
v2 = r_object(p);
|
||||||
if ( v2 == NULL ) {
|
if ( v2 == NULL ) {
|
||||||
|
@ -802,21 +877,25 @@ r_object(RFILE *p)
|
||||||
}
|
}
|
||||||
PyTuple_SET_ITEM(v, (int)i, v2);
|
PyTuple_SET_ITEM(v, (int)i, v2);
|
||||||
}
|
}
|
||||||
if (v == NULL)
|
if (v == NULL) {
|
||||||
return v;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (type == TYPE_SET)
|
if (type == TYPE_SET)
|
||||||
v3 = PySet_New(v);
|
v3 = PySet_New(v);
|
||||||
else
|
else
|
||||||
v3 = PyFrozenSet_New(v);
|
v3 = PyFrozenSet_New(v);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return v3;
|
retval = v3;
|
||||||
|
break;
|
||||||
|
|
||||||
case TYPE_CODE:
|
case TYPE_CODE:
|
||||||
if (PyEval_GetRestricted()) {
|
if (PyEval_GetRestricted()) {
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
PyErr_SetString(PyExc_RuntimeError,
|
||||||
"cannot unmarshal code objects in "
|
"cannot unmarshal code objects in "
|
||||||
"restricted execution mode");
|
"restricted execution mode");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int argcount;
|
int argcount;
|
||||||
|
@ -888,15 +967,19 @@ r_object(RFILE *p)
|
||||||
Py_XDECREF(lnotab);
|
Py_XDECREF(lnotab);
|
||||||
|
|
||||||
}
|
}
|
||||||
return v;
|
retval = v;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Bogus data got written, which isn't ideal.
|
/* Bogus data got written, which isn't ideal.
|
||||||
This will let you keep working and recover. */
|
This will let you keep working and recover. */
|
||||||
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
PyErr_SetString(PyExc_ValueError, "bad marshal data");
|
||||||
return NULL;
|
retval = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
p->depth--;
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -1002,6 +1085,7 @@ PyMarshal_ReadObjectFromFile(FILE *fp)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
rf.fp = fp;
|
rf.fp = fp;
|
||||||
rf.strings = PyList_New(0);
|
rf.strings = PyList_New(0);
|
||||||
|
rf.depth = 0;
|
||||||
result = r_object(&rf);
|
result = r_object(&rf);
|
||||||
Py_DECREF(rf.strings);
|
Py_DECREF(rf.strings);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1016,6 +1100,7 @@ PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
|
||||||
rf.ptr = str;
|
rf.ptr = str;
|
||||||
rf.end = str + len;
|
rf.end = str + len;
|
||||||
rf.strings = PyList_New(0);
|
rf.strings = PyList_New(0);
|
||||||
|
rf.depth = 0;
|
||||||
result = r_object(&rf);
|
result = r_object(&rf);
|
||||||
Py_DECREF(rf.strings);
|
Py_DECREF(rf.strings);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1104,6 +1189,7 @@ marshal_load(PyObject *self, PyObject *f)
|
||||||
}
|
}
|
||||||
rf.fp = PyFile_AsFile(f);
|
rf.fp = PyFile_AsFile(f);
|
||||||
rf.strings = PyList_New(0);
|
rf.strings = PyList_New(0);
|
||||||
|
rf.depth = 0;
|
||||||
result = read_object(&rf);
|
result = read_object(&rf);
|
||||||
Py_DECREF(rf.strings);
|
Py_DECREF(rf.strings);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1132,6 +1218,7 @@ marshal_loads(PyObject *self, PyObject *args)
|
||||||
rf.ptr = s;
|
rf.ptr = s;
|
||||||
rf.end = s + n;
|
rf.end = s + n;
|
||||||
rf.strings = PyList_New(0);
|
rf.strings = PyList_New(0);
|
||||||
|
rf.depth = 0;
|
||||||
result = read_object(&rf);
|
result = read_object(&rf);
|
||||||
Py_DECREF(rf.strings);
|
Py_DECREF(rf.strings);
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in New Issue