Kaydet (Commit) 763d309b authored tarafından Facundo Batista's avatar Facundo Batista

Fix #2702, with a correct accounting of recursion.

üst 1e022689
...@@ -94,23 +94,19 @@ class Node(object): ...@@ -94,23 +94,19 @@ class Node(object):
pass pass
class cPickleDeepRecursive(unittest.TestCase): class cPickleDeepRecursive(unittest.TestCase):
# I commented out, because the patch that fixes this was reverted, as def test_issue2702(self):
# it broke the next test case. Check the issues for full history. # This should raise a RecursionLimit but in some
# def test_issue2702(self): # platforms (FreeBSD, win32) sometimes raises KeyError instead,
# '''This should raise a RecursionLimit but in some # or just silently terminates the interpreter (=crashes).
# platforms (FreeBSD, win32) sometimes raises KeyError instead, nodes = [Node() for i in range(500)]
# or just silently terminates the interpreter (=crashes). for n in nodes:
# ''' n.connections = list(nodes)
# nodes = [Node() for i in range(500)] n.connections.remove(n)
# for n in nodes: self.assertRaises(RuntimeError, cPickle.dumps, n)
# n.connections = list(nodes)
# n.connections.remove(n)
# self.assertRaises(RuntimeError, cPickle.dumps, n)
def test_issue3179(self): def test_issue3179(self):
'''Safe test, because of I broken this case when fixing the # Safe test, because I broke this case when fixing the
behaviour for the previous test. # behaviour for the previous test.
'''
res=[] res=[]
for x in range(1,2000): for x in range(1,2000):
res.append(dict(doc=x, similar=[])) res.append(dict(doc=x, similar=[]))
......
...@@ -339,7 +339,6 @@ typedef struct Picklerobject { ...@@ -339,7 +339,6 @@ typedef struct Picklerobject {
int bin; int bin;
int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ int fast; /* Fast mode doesn't save in memo, don't use if circ ref */
int nesting;
int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t); int (*write_func)(struct Picklerobject *, const char *, Py_ssize_t);
char *write_buf; char *write_buf;
int buf_size; int buf_size;
...@@ -1630,7 +1629,12 @@ save_list(Picklerobject *self, PyObject *args) ...@@ -1630,7 +1629,12 @@ save_list(Picklerobject *self, PyObject *args)
iter = PyObject_GetIter(args); iter = PyObject_GetIter(args);
if (iter == NULL) if (iter == NULL)
goto finally; goto finally;
res = batch_list(self, iter);
if (Py_EnterRecursiveCall(" while pickling an object") == 0)
{
res = batch_list(self, iter);
Py_LeaveRecursiveCall();
}
Py_DECREF(iter); Py_DECREF(iter);
finally: finally:
...@@ -1786,7 +1790,11 @@ save_dict(Picklerobject *self, PyObject *args) ...@@ -1786,7 +1790,11 @@ save_dict(Picklerobject *self, PyObject *args)
iter = PyObject_CallMethod(args, "iteritems", "()"); iter = PyObject_CallMethod(args, "iteritems", "()");
if (iter == NULL) if (iter == NULL)
goto finally; goto finally;
res = batch_dict(self, iter); if (Py_EnterRecursiveCall(" while pickling an object") == 0)
{
res = batch_dict(self, iter);
Py_LeaveRecursiveCall();
}
Py_DECREF(iter); Py_DECREF(iter);
finally: finally:
...@@ -2306,11 +2314,8 @@ save(Picklerobject *self, PyObject *args, int pers_save) ...@@ -2306,11 +2314,8 @@ save(Picklerobject *self, PyObject *args, int pers_save)
int res = -1; int res = -1;
int tmp, size; int tmp, size;
if (self->nesting++ > Py_GetRecursionLimit()){ if (Py_EnterRecursiveCall(" while pickling an object"))
PyErr_SetString(PyExc_RuntimeError, return -1;
"maximum recursion depth exceeded");
goto finally;
}
if (!pers_save && self->pers_func) { if (!pers_save && self->pers_func) {
if ((tmp = save_pers(self, args, self->pers_func)) != 0) { if ((tmp = save_pers(self, args, self->pers_func)) != 0) {
...@@ -2559,7 +2564,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) ...@@ -2559,7 +2564,7 @@ save(Picklerobject *self, PyObject *args, int pers_save)
res = save_reduce(self, t, args); res = save_reduce(self, t, args);
finally: finally:
self->nesting--; Py_LeaveRecursiveCall();
Py_XDECREF(py_ob_id); Py_XDECREF(py_ob_id);
Py_XDECREF(__reduce__); Py_XDECREF(__reduce__);
Py_XDECREF(t); Py_XDECREF(t);
...@@ -2801,7 +2806,6 @@ newPicklerobject(PyObject *file, int proto) ...@@ -2801,7 +2806,6 @@ newPicklerobject(PyObject *file, int proto)
self->inst_pers_func = NULL; self->inst_pers_func = NULL;
self->write_buf = NULL; self->write_buf = NULL;
self->fast = 0; self->fast = 0;
self->nesting = 0;
self->fast_container = 0; self->fast_container = 0;
self->fast_memo = NULL; self->fast_memo = NULL;
self->buf_size = 0; self->buf_size = 0;
......
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