Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit eab7db3

Browse files
committed
Taught cPickle how to read pickles containing NEWOBJ. This won't get
exercised by the test suite before cPickle knows how to create NEWOBJ too. For now, it was just tried once by hand (via loading a NEWOBJ pickle created by pickle.py).
1 parent 7585229 commit eab7db3

1 file changed

Lines changed: 75 additions & 1 deletion

File tree

Modules/cPickle.c

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3698,6 +3698,53 @@ load_inst(Unpicklerobject *self)
36983698
return 0;
36993699
}
37003700

3701+
static int
3702+
load_newobj(Unpicklerobject *self)
3703+
{
3704+
PyObject *args = NULL;
3705+
PyObject *clsraw = NULL;
3706+
PyTypeObject *cls; /* clsraw cast to its true type */
3707+
PyObject *obj;
3708+
3709+
/* Stack is ... cls argtuple, and we want to call
3710+
* cls.__new__(cls, *argtuple).
3711+
*/
3712+
PDATA_POP(self->stack, args);
3713+
if (args == NULL) goto Fail;
3714+
if (! PyTuple_Check(args)) {
3715+
PyErr_SetString(UnpicklingError, "NEWOBJ expected an arg "
3716+
"tuple.");
3717+
goto Fail;
3718+
}
3719+
3720+
PDATA_POP(self->stack, clsraw);
3721+
cls = (PyTypeObject *)clsraw;
3722+
if (cls == NULL) goto Fail;
3723+
if (! PyType_Check(cls)) {
3724+
PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
3725+
"isn't a type object");
3726+
goto Fail;
3727+
}
3728+
if (cls->tp_new == NULL) {
3729+
PyErr_SetString(UnpicklingError, "NEWOBJ class argument "
3730+
"has NULL tp_new");
3731+
goto Fail;
3732+
}
3733+
3734+
/* Call __new__. */
3735+
obj = cls->tp_new(cls, args, NULL);
3736+
if (obj == NULL) goto Fail;
3737+
3738+
Py_DECREF(args);
3739+
Py_DECREF(clsraw);
3740+
PDATA_PUSH(self->stack, obj, -1);
3741+
return 0;
3742+
3743+
Fail:
3744+
Py_XDECREF(args);
3745+
Py_XDECREF(clsraw);
3746+
return -1;
3747+
}
37013748

37023749
static int
37033750
load_global(Unpicklerobject *self)
@@ -4461,6 +4508,11 @@ load(Unpicklerobject *self)
44614508
break;
44624509
continue;
44634510

4511+
case NEWOBJ:
4512+
if (load_newobj(self) < 0)
4513+
break;
4514+
continue;
4515+
44644516
case GLOBAL:
44654517
if (load_global(self) < 0)
44664518
break;
@@ -4638,10 +4690,27 @@ noload_inst(Unpicklerobject *self)
46384690
Pdata_clear(self->stack, i);
46394691
if (self->readline_func(self, &s) < 0) return -1;
46404692
if (self->readline_func(self, &s) < 0) return -1;
4641-
PDATA_APPEND(self->stack, Py_None,-1);
4693+
PDATA_APPEND(self->stack, Py_None, -1);
46424694
return 0;
46434695
}
46444696

4697+
static int
4698+
noload_newobj(Unpicklerobject *self)
4699+
{
4700+
PyObject *obj;
4701+
4702+
PDATA_POP(self->stack, obj); /* pop argtuple */
4703+
if (obj == NULL) return -1;
4704+
Py_DECREF(obj);
4705+
4706+
PDATA_POP(self->stack, obj); /* pop cls */
4707+
if (obj == NULL) return -1;
4708+
Py_DECREF(obj);
4709+
4710+
PDATA_APPEND(self->stack, Py_None, -1);
4711+
return 0;
4712+
}
4713+
46454714
static int
46464715
noload_global(Unpicklerobject *self)
46474716
{
@@ -4829,6 +4898,11 @@ noload(Unpicklerobject *self)
48294898
break;
48304899
continue;
48314900

4901+
case NEWOBJ:
4902+
if (noload_newobj(self) < 0)
4903+
break;
4904+
continue;
4905+
48324906
case GLOBAL:
48334907
if (noload_global(self) < 0)
48344908
break;

0 commit comments

Comments
 (0)