Visitar URL original
Stackless issue #268: Add magic number to pickled code objects · akruis/cpython@c753054 · GitHub
Skip to content

Commit c753054

Browse files
committed
Stackless issue python#268: Add magic number to pickled code objects
Enable unpickling code objects pickled by previous Stackless versions.
1 parent 25bb326 commit c753054

2 files changed

Lines changed: 25 additions & 10 deletions

File tree

‎Stackless/pickling/prickelpit.c‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,7 @@ slp_cannot_execute(PyCFrameObject *f, const char *exec_name, PyObject *retval)
381381
if (retval != NULL) {
382382
Py_DECREF(retval);
383383
PyErr_Format(PyExc_RuntimeError, "cannot execute invalid frame with "
384-
"'%.100s': frame had a C state that"
385-
" can't be restored.",
384+
"'%.100s': frame had a C state that can't be restored or an invalid code object.",
386385
exec_name);
387386
}
388387

@@ -663,24 +662,29 @@ code_reduce(PyCodeObject * co, PyObject *unused)
663662
static PyObject *
664663
code_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
665664
{
665+
long magic = 0;
666+
666667
if (0 >= bytecode_magic) {
667668
bytecode_magic = PyImport_GetMagicNumber();
668669
if (-1 == bytecode_magic)
669670
return NULL;
670671
}
671672

672673
assert(PyTuple_CheckExact(args));
673-
if (PyTuple_GET_SIZE(args) != sizeof(codetuplefmt)-1) {
674+
if (PyTuple_GET_SIZE(args) == sizeof(codetuplefmt) - 1) {
675+
/* */
676+
magic = PyLong_AsLong(PyTuple_GET_ITEM(args, 0));
677+
if (-1 == magic && PyErr_Occurred()) {
678+
return NULL;
679+
}
680+
args = PyTuple_GetSlice(args, 1, sizeof(codetuplefmt) - 1);
681+
} else if (PyTuple_GET_SIZE(args) == sizeof(codetuplefmt) - 2) {
682+
/* Format used by Stackless versions up to 3.7 */
683+
args = PyTuple_GetSlice(args, 0, sizeof(codetuplefmt) - 2);
684+
} else {
674685
PyErr_SetString(PyExc_IndexError, "Argument tuple has wrong size.");
675686
return NULL;
676687
}
677-
678-
long magic = PyLong_AsLong(PyTuple_GET_ITEM(args, 0));
679-
if (-1 == magic && PyErr_Occurred()) {
680-
return NULL;
681-
}
682-
683-
args = PyTuple_GetSlice(args, 1, sizeof(codetuplefmt)-1);
684688
if (NULL == args)
685689
return NULL;
686690

‎Stackless/unittests/test_pickle.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,17 @@ def test_new_with_wrong_magic_error(self):
13771377
warnings.simplefilter("error", RuntimeWarning)
13781378
reduced[0](*args)
13791379

1380+
def test_new_without_magic(self):
1381+
code = (lambda :None).__code__
1382+
reduce = stackless._stackless._wrap.code.__reduce__
1383+
reduced = reduce(code)
1384+
args = reduced[1][1:]
1385+
with self.assertRaisesRegex(RuntimeWarning, "Unpickling code object with invalid magic number 0"):
1386+
with stackless.atomic():
1387+
with warnings.catch_warnings():
1388+
warnings.simplefilter("error", RuntimeWarning)
1389+
reduced[0](*args)
1390+
13801391
def test_func_with_wrong_magic(self):
13811392
l = (lambda :None)
13821393
code = l.__code__

0 commit comments

Comments
 (0)