Branch data Line data Source code
1 : : /* pickle accelerator C extensor: _pickle module.
2 : : *
3 : : * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows
4 : : * and as an extension module (Py_BUILD_CORE_MODULE define) on other
5 : : * platforms. */
6 : :
7 : : #ifndef Py_BUILD_CORE_BUILTIN
8 : : # define Py_BUILD_CORE_MODULE 1
9 : : #endif
10 : :
11 : : #include "Python.h"
12 : : #include "pycore_ceval.h" // _Py_EnterRecursiveCall()
13 : : #include "pycore_moduleobject.h" // _PyModule_GetState()
14 : : #include "pycore_runtime.h" // _Py_ID()
15 : : #include "pycore_pystate.h" // _PyThreadState_GET()
16 : : #include "structmember.h" // PyMemberDef
17 : :
18 : : #include <stdlib.h> // strtol()
19 : :
20 : : PyDoc_STRVAR(pickle_module_doc,
21 : : "Optimized C implementation for the Python pickle module.");
22 : :
23 : : /*[clinic input]
24 : : module _pickle
25 : : class _pickle.Pickler "PicklerObject *" "&Pickler_Type"
26 : : class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType"
27 : : class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type"
28 : : class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType"
29 : : [clinic start generated code]*/
30 : : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b3e113468a58e6c]*/
31 : :
32 : : /* Bump HIGHEST_PROTOCOL when new opcodes are added to the pickle protocol.
33 : : Bump DEFAULT_PROTOCOL only when the oldest still supported version of Python
34 : : already includes it. */
35 : : enum {
36 : : HIGHEST_PROTOCOL = 5,
37 : : DEFAULT_PROTOCOL = 4
38 : : };
39 : :
40 : : #ifdef MS_WINDOWS
41 : : // These are already typedefs from windows.h, pulled in via pycore_runtime.h.
42 : : #define FLOAT FLOAT_
43 : : #define INT INT_
44 : : #define LONG LONG_
45 : :
46 : : /* This can already be defined on Windows to set the character set
47 : : the Windows header files treat as default */
48 : : #ifdef UNICODE
49 : : #undef UNICODE
50 : : #endif
51 : : #endif
52 : :
53 : : /* Pickle opcodes. These must be kept updated with pickle.py.
54 : : Extensive docs are in pickletools.py. */
55 : : enum opcode {
56 : : MARK = '(',
57 : : STOP = '.',
58 : : POP = '0',
59 : : POP_MARK = '1',
60 : : DUP = '2',
61 : : FLOAT = 'F',
62 : : INT = 'I',
63 : : BININT = 'J',
64 : : BININT1 = 'K',
65 : : LONG = 'L',
66 : : BININT2 = 'M',
67 : : NONE = 'N',
68 : : PERSID = 'P',
69 : : BINPERSID = 'Q',
70 : : REDUCE = 'R',
71 : : STRING = 'S',
72 : : BINSTRING = 'T',
73 : : SHORT_BINSTRING = 'U',
74 : : UNICODE = 'V',
75 : : BINUNICODE = 'X',
76 : : APPEND = 'a',
77 : : BUILD = 'b',
78 : : GLOBAL = 'c',
79 : : DICT = 'd',
80 : : EMPTY_DICT = '}',
81 : : APPENDS = 'e',
82 : : GET = 'g',
83 : : BINGET = 'h',
84 : : INST = 'i',
85 : : LONG_BINGET = 'j',
86 : : LIST = 'l',
87 : : EMPTY_LIST = ']',
88 : : OBJ = 'o',
89 : : PUT = 'p',
90 : : BINPUT = 'q',
91 : : LONG_BINPUT = 'r',
92 : : SETITEM = 's',
93 : : TUPLE = 't',
94 : : EMPTY_TUPLE = ')',
95 : : SETITEMS = 'u',
96 : : BINFLOAT = 'G',
97 : :
98 : : /* Protocol 2. */
99 : : PROTO = '\x80',
100 : : NEWOBJ = '\x81',
101 : : EXT1 = '\x82',
102 : : EXT2 = '\x83',
103 : : EXT4 = '\x84',
104 : : TUPLE1 = '\x85',
105 : : TUPLE2 = '\x86',
106 : : TUPLE3 = '\x87',
107 : : NEWTRUE = '\x88',
108 : : NEWFALSE = '\x89',
109 : : LONG1 = '\x8a',
110 : : LONG4 = '\x8b',
111 : :
112 : : /* Protocol 3 (Python 3.x) */
113 : : BINBYTES = 'B',
114 : : SHORT_BINBYTES = 'C',
115 : :
116 : : /* Protocol 4 */
117 : : SHORT_BINUNICODE = '\x8c',
118 : : BINUNICODE8 = '\x8d',
119 : : BINBYTES8 = '\x8e',
120 : : EMPTY_SET = '\x8f',
121 : : ADDITEMS = '\x90',
122 : : FROZENSET = '\x91',
123 : : NEWOBJ_EX = '\x92',
124 : : STACK_GLOBAL = '\x93',
125 : : MEMOIZE = '\x94',
126 : : FRAME = '\x95',
127 : :
128 : : /* Protocol 5 */
129 : : BYTEARRAY8 = '\x96',
130 : : NEXT_BUFFER = '\x97',
131 : : READONLY_BUFFER = '\x98'
132 : : };
133 : :
134 : : enum {
135 : : /* Keep in synch with pickle.Pickler._BATCHSIZE. This is how many elements
136 : : batch_list/dict() pumps out before doing APPENDS/SETITEMS. Nothing will
137 : : break if this gets out of synch with pickle.py, but it's unclear that would
138 : : help anything either. */
139 : : BATCHSIZE = 1000,
140 : :
141 : : /* Nesting limit until Pickler, when running in "fast mode", starts
142 : : checking for self-referential data-structures. */
143 : : FAST_NESTING_LIMIT = 50,
144 : :
145 : : /* Initial size of the write buffer of Pickler. */
146 : : WRITE_BUF_SIZE = 4096,
147 : :
148 : : /* Prefetch size when unpickling (disabled on unpeekable streams) */
149 : : PREFETCH = 8192 * 16,
150 : :
151 : : FRAME_SIZE_MIN = 4,
152 : : FRAME_SIZE_TARGET = 64 * 1024,
153 : : FRAME_HEADER_SIZE = 9
154 : : };
155 : :
156 : : /*************************************************************************/
157 : :
158 : : /* State of the pickle module, per PEP 3121. */
159 : : typedef struct {
160 : : /* Exception classes for pickle. */
161 : : PyObject *PickleError;
162 : : PyObject *PicklingError;
163 : : PyObject *UnpicklingError;
164 : :
165 : : /* copyreg.dispatch_table, {type_object: pickling_function} */
166 : : PyObject *dispatch_table;
167 : :
168 : : /* For the extension opcodes EXT1, EXT2 and EXT4. */
169 : :
170 : : /* copyreg._extension_registry, {(module_name, function_name): code} */
171 : : PyObject *extension_registry;
172 : : /* copyreg._extension_cache, {code: object} */
173 : : PyObject *extension_cache;
174 : : /* copyreg._inverted_registry, {code: (module_name, function_name)} */
175 : : PyObject *inverted_registry;
176 : :
177 : : /* Import mappings for compatibility with Python 2.x */
178 : :
179 : : /* _compat_pickle.NAME_MAPPING,
180 : : {(oldmodule, oldname): (newmodule, newname)} */
181 : : PyObject *name_mapping_2to3;
182 : : /* _compat_pickle.IMPORT_MAPPING, {oldmodule: newmodule} */
183 : : PyObject *import_mapping_2to3;
184 : : /* Same, but with REVERSE_NAME_MAPPING / REVERSE_IMPORT_MAPPING */
185 : : PyObject *name_mapping_3to2;
186 : : PyObject *import_mapping_3to2;
187 : :
188 : : /* codecs.encode, used for saving bytes in older protocols */
189 : : PyObject *codecs_encode;
190 : : /* builtins.getattr, used for saving nested names with protocol < 4 */
191 : : PyObject *getattr;
192 : : /* functools.partial, used for implementing __newobj_ex__ with protocols
193 : : 2 and 3 */
194 : : PyObject *partial;
195 : : } PickleState;
196 : :
197 : : /* Forward declaration of the _pickle module definition. */
198 : : static struct PyModuleDef _picklemodule;
199 : :
200 : : /* Given a module object, get its per-module state. */
201 : : static PickleState *
202 : 10 : _Pickle_GetState(PyObject *module)
203 : : {
204 : 10 : return (PickleState *)_PyModule_GetState(module);
205 : : }
206 : :
207 : : /* Find the module instance imported in the currently running sub-interpreter
208 : : and get its state. */
209 : : static PickleState *
210 : 0 : _Pickle_GetGlobalState(void)
211 : : {
212 : 0 : return _Pickle_GetState(PyState_FindModule(&_picklemodule));
213 : : }
214 : :
215 : : /* Clear the given pickle module state. */
216 : : static void
217 : 1 : _Pickle_ClearState(PickleState *st)
218 : : {
219 [ + - ]: 1 : Py_CLEAR(st->PickleError);
220 [ + - ]: 1 : Py_CLEAR(st->PicklingError);
221 [ + - ]: 1 : Py_CLEAR(st->UnpicklingError);
222 [ + - ]: 1 : Py_CLEAR(st->dispatch_table);
223 [ + - ]: 1 : Py_CLEAR(st->extension_registry);
224 [ + - ]: 1 : Py_CLEAR(st->extension_cache);
225 [ + - ]: 1 : Py_CLEAR(st->inverted_registry);
226 [ + - ]: 1 : Py_CLEAR(st->name_mapping_2to3);
227 [ + - ]: 1 : Py_CLEAR(st->import_mapping_2to3);
228 [ + - ]: 1 : Py_CLEAR(st->name_mapping_3to2);
229 [ + - ]: 1 : Py_CLEAR(st->import_mapping_3to2);
230 [ + - ]: 1 : Py_CLEAR(st->codecs_encode);
231 [ + - ]: 1 : Py_CLEAR(st->getattr);
232 [ + - ]: 1 : Py_CLEAR(st->partial);
233 : 1 : }
234 : :
235 : : /* Initialize the given pickle module state. */
236 : : static int
237 : 1 : _Pickle_InitState(PickleState *st)
238 : : {
239 : 1 : PyObject *copyreg = NULL;
240 : 1 : PyObject *compat_pickle = NULL;
241 : :
242 : 1 : st->getattr = _PyEval_GetBuiltin(&_Py_ID(getattr));
243 [ - + ]: 1 : if (st->getattr == NULL)
244 : 0 : goto error;
245 : :
246 : 1 : copyreg = PyImport_ImportModule("copyreg");
247 [ - + ]: 1 : if (!copyreg)
248 : 0 : goto error;
249 : 1 : st->dispatch_table = PyObject_GetAttrString(copyreg, "dispatch_table");
250 [ - + ]: 1 : if (!st->dispatch_table)
251 : 0 : goto error;
252 [ - + ]: 1 : if (!PyDict_CheckExact(st->dispatch_table)) {
253 : 0 : PyErr_Format(PyExc_RuntimeError,
254 : : "copyreg.dispatch_table should be a dict, not %.200s",
255 : 0 : Py_TYPE(st->dispatch_table)->tp_name);
256 : 0 : goto error;
257 : : }
258 : 1 : st->extension_registry = \
259 : 1 : PyObject_GetAttrString(copyreg, "_extension_registry");
260 [ - + ]: 1 : if (!st->extension_registry)
261 : 0 : goto error;
262 [ - + ]: 1 : if (!PyDict_CheckExact(st->extension_registry)) {
263 : 0 : PyErr_Format(PyExc_RuntimeError,
264 : : "copyreg._extension_registry should be a dict, "
265 : 0 : "not %.200s", Py_TYPE(st->extension_registry)->tp_name);
266 : 0 : goto error;
267 : : }
268 : 1 : st->inverted_registry = \
269 : 1 : PyObject_GetAttrString(copyreg, "_inverted_registry");
270 [ - + ]: 1 : if (!st->inverted_registry)
271 : 0 : goto error;
272 [ - + ]: 1 : if (!PyDict_CheckExact(st->inverted_registry)) {
273 : 0 : PyErr_Format(PyExc_RuntimeError,
274 : : "copyreg._inverted_registry should be a dict, "
275 : 0 : "not %.200s", Py_TYPE(st->inverted_registry)->tp_name);
276 : 0 : goto error;
277 : : }
278 : 1 : st->extension_cache = PyObject_GetAttrString(copyreg, "_extension_cache");
279 [ - + ]: 1 : if (!st->extension_cache)
280 : 0 : goto error;
281 [ - + ]: 1 : if (!PyDict_CheckExact(st->extension_cache)) {
282 : 0 : PyErr_Format(PyExc_RuntimeError,
283 : : "copyreg._extension_cache should be a dict, "
284 : 0 : "not %.200s", Py_TYPE(st->extension_cache)->tp_name);
285 : 0 : goto error;
286 : : }
287 [ + - ]: 1 : Py_CLEAR(copyreg);
288 : :
289 : : /* Load the 2.x -> 3.x stdlib module mapping tables */
290 : 1 : compat_pickle = PyImport_ImportModule("_compat_pickle");
291 [ - + ]: 1 : if (!compat_pickle)
292 : 0 : goto error;
293 : 1 : st->name_mapping_2to3 = \
294 : 1 : PyObject_GetAttrString(compat_pickle, "NAME_MAPPING");
295 [ - + ]: 1 : if (!st->name_mapping_2to3)
296 : 0 : goto error;
297 [ - + ]: 1 : if (!PyDict_CheckExact(st->name_mapping_2to3)) {
298 : 0 : PyErr_Format(PyExc_RuntimeError,
299 : : "_compat_pickle.NAME_MAPPING should be a dict, not %.200s",
300 : 0 : Py_TYPE(st->name_mapping_2to3)->tp_name);
301 : 0 : goto error;
302 : : }
303 : 1 : st->import_mapping_2to3 = \
304 : 1 : PyObject_GetAttrString(compat_pickle, "IMPORT_MAPPING");
305 [ - + ]: 1 : if (!st->import_mapping_2to3)
306 : 0 : goto error;
307 [ - + ]: 1 : if (!PyDict_CheckExact(st->import_mapping_2to3)) {
308 : 0 : PyErr_Format(PyExc_RuntimeError,
309 : : "_compat_pickle.IMPORT_MAPPING should be a dict, "
310 : 0 : "not %.200s", Py_TYPE(st->import_mapping_2to3)->tp_name);
311 : 0 : goto error;
312 : : }
313 : : /* ... and the 3.x -> 2.x mapping tables */
314 : 1 : st->name_mapping_3to2 = \
315 : 1 : PyObject_GetAttrString(compat_pickle, "REVERSE_NAME_MAPPING");
316 [ - + ]: 1 : if (!st->name_mapping_3to2)
317 : 0 : goto error;
318 [ - + ]: 1 : if (!PyDict_CheckExact(st->name_mapping_3to2)) {
319 : 0 : PyErr_Format(PyExc_RuntimeError,
320 : : "_compat_pickle.REVERSE_NAME_MAPPING should be a dict, "
321 : 0 : "not %.200s", Py_TYPE(st->name_mapping_3to2)->tp_name);
322 : 0 : goto error;
323 : : }
324 : 1 : st->import_mapping_3to2 = \
325 : 1 : PyObject_GetAttrString(compat_pickle, "REVERSE_IMPORT_MAPPING");
326 [ - + ]: 1 : if (!st->import_mapping_3to2)
327 : 0 : goto error;
328 [ - + ]: 1 : if (!PyDict_CheckExact(st->import_mapping_3to2)) {
329 : 0 : PyErr_Format(PyExc_RuntimeError,
330 : : "_compat_pickle.REVERSE_IMPORT_MAPPING should be a dict, "
331 : 0 : "not %.200s", Py_TYPE(st->import_mapping_3to2)->tp_name);
332 : 0 : goto error;
333 : : }
334 [ + - ]: 1 : Py_CLEAR(compat_pickle);
335 : :
336 : 1 : st->codecs_encode = _PyImport_GetModuleAttrString("codecs", "encode");
337 [ - + ]: 1 : if (st->codecs_encode == NULL) {
338 : 0 : goto error;
339 : : }
340 [ - + ]: 1 : if (!PyCallable_Check(st->codecs_encode)) {
341 : 0 : PyErr_Format(PyExc_RuntimeError,
342 : : "codecs.encode should be a callable, not %.200s",
343 : 0 : Py_TYPE(st->codecs_encode)->tp_name);
344 : 0 : goto error;
345 : : }
346 : :
347 : 1 : st->partial = _PyImport_GetModuleAttrString("functools", "partial");
348 [ - + ]: 1 : if (!st->partial)
349 : 0 : goto error;
350 : :
351 : 1 : return 0;
352 : :
353 : 0 : error:
354 [ # # ]: 0 : Py_CLEAR(copyreg);
355 [ # # ]: 0 : Py_CLEAR(compat_pickle);
356 : 0 : _Pickle_ClearState(st);
357 : 0 : return -1;
358 : : }
359 : :
360 : : /* Helper for calling a function with a single argument quickly.
361 : :
362 : : This function steals the reference of the given argument. */
363 : : static PyObject *
364 : 0 : _Pickle_FastCall(PyObject *func, PyObject *obj)
365 : : {
366 : : PyObject *result;
367 : :
368 : 0 : result = PyObject_CallOneArg(func, obj);
369 : 0 : Py_DECREF(obj);
370 : 0 : return result;
371 : : }
372 : :
373 : : /*************************************************************************/
374 : :
375 : : /* Retrieve and deconstruct a method for avoiding a reference cycle
376 : : (pickler -> bound method of pickler -> pickler) */
377 : : static int
378 : 0 : init_method_ref(PyObject *self, PyObject *name,
379 : : PyObject **method_func, PyObject **method_self)
380 : : {
381 : : PyObject *func, *func2;
382 : : int ret;
383 : :
384 : : /* *method_func and *method_self should be consistent. All refcount decrements
385 : : should be occurred after setting *method_self and *method_func. */
386 : 0 : ret = _PyObject_LookupAttr(self, name, &func);
387 [ # # ]: 0 : if (func == NULL) {
388 : 0 : *method_self = NULL;
389 [ # # ]: 0 : Py_CLEAR(*method_func);
390 : 0 : return ret;
391 : : }
392 : :
393 [ # # # # ]: 0 : if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) {
394 : : /* Deconstruct a bound Python method */
395 : 0 : *method_self = self; /* borrowed */
396 : 0 : func2 = PyMethod_GET_FUNCTION(func);
397 : 0 : Py_XSETREF(*method_func, Py_NewRef(func2));
398 : 0 : Py_DECREF(func);
399 : 0 : return 0;
400 : : }
401 : : else {
402 : 0 : *method_self = NULL;
403 : 0 : Py_XSETREF(*method_func, func);
404 : 0 : return 0;
405 : : }
406 : : }
407 : :
408 : : /* Bind a method if it was deconstructed */
409 : : static PyObject *
410 : 0 : reconstruct_method(PyObject *func, PyObject *self)
411 : : {
412 [ # # ]: 0 : if (self) {
413 : 0 : return PyMethod_New(func, self);
414 : : }
415 : : else {
416 : 0 : return Py_NewRef(func);
417 : : }
418 : : }
419 : :
420 : : static PyObject *
421 : 0 : call_method(PyObject *func, PyObject *self, PyObject *obj)
422 : : {
423 [ # # ]: 0 : if (self) {
424 : 0 : return PyObject_CallFunctionObjArgs(func, self, obj, NULL);
425 : : }
426 : : else {
427 : 0 : return PyObject_CallOneArg(func, obj);
428 : : }
429 : : }
430 : :
431 : : /*************************************************************************/
432 : :
433 : : /* Internal data type used as the unpickling stack. */
434 : : typedef struct {
435 : : PyObject_VAR_HEAD
436 : : PyObject **data;
437 : : int mark_set; /* is MARK set? */
438 : : Py_ssize_t fence; /* position of top MARK or 0 */
439 : : Py_ssize_t allocated; /* number of slots in data allocated */
440 : : } Pdata;
441 : :
442 : : static void
443 : 0 : Pdata_dealloc(Pdata *self)
444 : : {
445 : 0 : Py_ssize_t i = Py_SIZE(self);
446 [ # # ]: 0 : while (--i >= 0) {
447 : 0 : Py_DECREF(self->data[i]);
448 : : }
449 : 0 : PyMem_Free(self->data);
450 : 0 : PyObject_Free(self);
451 : 0 : }
452 : :
453 : : static PyTypeObject Pdata_Type = {
454 : : PyVarObject_HEAD_INIT(NULL, 0)
455 : : "_pickle.Pdata", /*tp_name*/
456 : : sizeof(Pdata), /*tp_basicsize*/
457 : : sizeof(PyObject *), /*tp_itemsize*/
458 : : (destructor)Pdata_dealloc, /*tp_dealloc*/
459 : : };
460 : :
461 : : static PyObject *
462 : 0 : Pdata_New(void)
463 : : {
464 : : Pdata *self;
465 : :
466 [ # # ]: 0 : if (!(self = PyObject_New(Pdata, &Pdata_Type)))
467 : 0 : return NULL;
468 : 0 : Py_SET_SIZE(self, 0);
469 : 0 : self->mark_set = 0;
470 : 0 : self->fence = 0;
471 : 0 : self->allocated = 8;
472 : 0 : self->data = PyMem_Malloc(self->allocated * sizeof(PyObject *));
473 [ # # ]: 0 : if (self->data)
474 : 0 : return (PyObject *)self;
475 : 0 : Py_DECREF(self);
476 : 0 : return PyErr_NoMemory();
477 : : }
478 : :
479 : :
480 : : /* Retain only the initial clearto items. If clearto >= the current
481 : : * number of items, this is a (non-erroneous) NOP.
482 : : */
483 : : static int
484 : 0 : Pdata_clear(Pdata *self, Py_ssize_t clearto)
485 : : {
486 : 0 : Py_ssize_t i = Py_SIZE(self);
487 : :
488 : : assert(clearto >= self->fence);
489 [ # # ]: 0 : if (clearto >= i)
490 : 0 : return 0;
491 : :
492 [ # # ]: 0 : while (--i >= clearto) {
493 [ # # ]: 0 : Py_CLEAR(self->data[i]);
494 : : }
495 : 0 : Py_SET_SIZE(self, clearto);
496 : 0 : return 0;
497 : : }
498 : :
499 : : static int
500 : 0 : Pdata_grow(Pdata *self)
501 : : {
502 : 0 : PyObject **data = self->data;
503 : 0 : size_t allocated = (size_t)self->allocated;
504 : : size_t new_allocated;
505 : :
506 : 0 : new_allocated = (allocated >> 3) + 6;
507 : : /* check for integer overflow */
508 [ # # ]: 0 : if (new_allocated > (size_t)PY_SSIZE_T_MAX - allocated)
509 : 0 : goto nomemory;
510 : 0 : new_allocated += allocated;
511 [ # # ]: 0 : PyMem_RESIZE(data, PyObject *, new_allocated);
512 [ # # ]: 0 : if (data == NULL)
513 : 0 : goto nomemory;
514 : :
515 : 0 : self->data = data;
516 : 0 : self->allocated = (Py_ssize_t)new_allocated;
517 : 0 : return 0;
518 : :
519 : 0 : nomemory:
520 : 0 : PyErr_NoMemory();
521 : 0 : return -1;
522 : : }
523 : :
524 : : static int
525 : 0 : Pdata_stack_underflow(Pdata *self)
526 : : {
527 : 0 : PickleState *st = _Pickle_GetGlobalState();
528 : 0 : PyErr_SetString(st->UnpicklingError,
529 [ # # ]: 0 : self->mark_set ?
530 : : "unexpected MARK found" :
531 : : "unpickling stack underflow");
532 : 0 : return -1;
533 : : }
534 : :
535 : : /* D is a Pdata*. Pop the topmost element and store it into V, which
536 : : * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError
537 : : * is raised and V is set to NULL.
538 : : */
539 : : static PyObject *
540 : 0 : Pdata_pop(Pdata *self)
541 : : {
542 [ # # ]: 0 : if (Py_SIZE(self) <= self->fence) {
543 : 0 : Pdata_stack_underflow(self);
544 : 0 : return NULL;
545 : : }
546 : 0 : Py_SET_SIZE(self, Py_SIZE(self) - 1);
547 : 0 : return self->data[Py_SIZE(self)];
548 : : }
549 : : #define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
550 : :
551 : : static int
552 : 0 : Pdata_push(Pdata *self, PyObject *obj)
553 : : {
554 [ # # # # ]: 0 : if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) {
555 : 0 : return -1;
556 : : }
557 : 0 : self->data[Py_SIZE(self)] = obj;
558 : 0 : Py_SET_SIZE(self, Py_SIZE(self) + 1);
559 : 0 : return 0;
560 : : }
561 : :
562 : : /* Push an object on stack, transferring its ownership to the stack. */
563 : : #define PDATA_PUSH(D, O, ER) do { \
564 : : if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
565 : :
566 : : /* Push an object on stack, adding a new reference to the object. */
567 : : #define PDATA_APPEND(D, O, ER) do { \
568 : : Py_INCREF((O)); \
569 : : if (Pdata_push((D), (O)) < 0) return (ER); } while(0)
570 : :
571 : : static PyObject *
572 : 0 : Pdata_poptuple(Pdata *self, Py_ssize_t start)
573 : : {
574 : : PyObject *tuple;
575 : : Py_ssize_t len, i, j;
576 : :
577 [ # # ]: 0 : if (start < self->fence) {
578 : 0 : Pdata_stack_underflow(self);
579 : 0 : return NULL;
580 : : }
581 : 0 : len = Py_SIZE(self) - start;
582 : 0 : tuple = PyTuple_New(len);
583 [ # # ]: 0 : if (tuple == NULL)
584 : 0 : return NULL;
585 [ # # ]: 0 : for (i = start, j = 0; j < len; i++, j++)
586 : 0 : PyTuple_SET_ITEM(tuple, j, self->data[i]);
587 : :
588 : 0 : Py_SET_SIZE(self, start);
589 : 0 : return tuple;
590 : : }
591 : :
592 : : static PyObject *
593 : 0 : Pdata_poplist(Pdata *self, Py_ssize_t start)
594 : : {
595 : : PyObject *list;
596 : : Py_ssize_t len, i, j;
597 : :
598 : 0 : len = Py_SIZE(self) - start;
599 : 0 : list = PyList_New(len);
600 [ # # ]: 0 : if (list == NULL)
601 : 0 : return NULL;
602 [ # # ]: 0 : for (i = start, j = 0; j < len; i++, j++)
603 : 0 : PyList_SET_ITEM(list, j, self->data[i]);
604 : :
605 : 0 : Py_SET_SIZE(self, start);
606 : 0 : return list;
607 : : }
608 : :
609 : : typedef struct {
610 : : PyObject *me_key;
611 : : Py_ssize_t me_value;
612 : : } PyMemoEntry;
613 : :
614 : : typedef struct {
615 : : size_t mt_mask;
616 : : size_t mt_used;
617 : : size_t mt_allocated;
618 : : PyMemoEntry *mt_table;
619 : : } PyMemoTable;
620 : :
621 : : typedef struct PicklerObject {
622 : : PyObject_HEAD
623 : : PyMemoTable *memo; /* Memo table, keep track of the seen
624 : : objects to support self-referential objects
625 : : pickling. */
626 : : PyObject *pers_func; /* persistent_id() method, can be NULL */
627 : : PyObject *pers_func_self; /* borrowed reference to self if pers_func
628 : : is an unbound method, NULL otherwise */
629 : : PyObject *dispatch_table; /* private dispatch_table, can be NULL */
630 : : PyObject *reducer_override; /* hook for invoking user-defined callbacks
631 : : instead of save_global when pickling
632 : : functions and classes*/
633 : :
634 : : PyObject *write; /* write() method of the output stream. */
635 : : PyObject *output_buffer; /* Write into a local bytearray buffer before
636 : : flushing to the stream. */
637 : : Py_ssize_t output_len; /* Length of output_buffer. */
638 : : Py_ssize_t max_output_len; /* Allocation size of output_buffer. */
639 : : int proto; /* Pickle protocol number, >= 0 */
640 : : int bin; /* Boolean, true if proto > 0 */
641 : : int framing; /* True when framing is enabled, proto >= 4 */
642 : : Py_ssize_t frame_start; /* Position in output_buffer where the
643 : : current frame begins. -1 if there
644 : : is no frame currently open. */
645 : :
646 : : Py_ssize_t buf_size; /* Size of the current buffered pickle data */
647 : : int fast; /* Enable fast mode if set to a true value.
648 : : The fast mode disable the usage of memo,
649 : : therefore speeding the pickling process by
650 : : not generating superfluous PUT opcodes. It
651 : : should not be used if with self-referential
652 : : objects. */
653 : : int fast_nesting;
654 : : int fix_imports; /* Indicate whether Pickler should fix
655 : : the name of globals for Python 2.x. */
656 : : PyObject *fast_memo;
657 : : PyObject *buffer_callback; /* Callback for out-of-band buffers, or NULL */
658 : : } PicklerObject;
659 : :
660 : : typedef struct UnpicklerObject {
661 : : PyObject_HEAD
662 : : Pdata *stack; /* Pickle data stack, store unpickled objects. */
663 : :
664 : : /* The unpickler memo is just an array of PyObject *s. Using a dict
665 : : is unnecessary, since the keys are contiguous ints. */
666 : : PyObject **memo;
667 : : size_t memo_size; /* Capacity of the memo array */
668 : : size_t memo_len; /* Number of objects in the memo */
669 : :
670 : : PyObject *pers_func; /* persistent_load() method, can be NULL. */
671 : : PyObject *pers_func_self; /* borrowed reference to self if pers_func
672 : : is an unbound method, NULL otherwise */
673 : :
674 : : Py_buffer buffer;
675 : : char *input_buffer;
676 : : char *input_line;
677 : : Py_ssize_t input_len;
678 : : Py_ssize_t next_read_idx;
679 : : Py_ssize_t prefetched_idx; /* index of first prefetched byte */
680 : :
681 : : PyObject *read; /* read() method of the input stream. */
682 : : PyObject *readinto; /* readinto() method of the input stream. */
683 : : PyObject *readline; /* readline() method of the input stream. */
684 : : PyObject *peek; /* peek() method of the input stream, or NULL */
685 : : PyObject *buffers; /* iterable of out-of-band buffers, or NULL */
686 : :
687 : : char *encoding; /* Name of the encoding to be used for
688 : : decoding strings pickled using Python
689 : : 2.x. The default value is "ASCII" */
690 : : char *errors; /* Name of errors handling scheme to used when
691 : : decoding strings. The default value is
692 : : "strict". */
693 : : Py_ssize_t *marks; /* Mark stack, used for unpickling container
694 : : objects. */
695 : : Py_ssize_t num_marks; /* Number of marks in the mark stack. */
696 : : Py_ssize_t marks_size; /* Current allocated size of the mark stack. */
697 : : int proto; /* Protocol of the pickle loaded. */
698 : : int fix_imports; /* Indicate whether Unpickler should fix
699 : : the name of globals pickled by Python 2.x. */
700 : : } UnpicklerObject;
701 : :
702 : : typedef struct {
703 : : PyObject_HEAD
704 : : PicklerObject *pickler; /* Pickler whose memo table we're proxying. */
705 : : } PicklerMemoProxyObject;
706 : :
707 : : typedef struct {
708 : : PyObject_HEAD
709 : : UnpicklerObject *unpickler;
710 : : } UnpicklerMemoProxyObject;
711 : :
712 : : /* Forward declarations */
713 : : static int save(PicklerObject *, PyObject *, int);
714 : : static int save_reduce(PicklerObject *, PyObject *, PyObject *);
715 : : static PyTypeObject Pickler_Type;
716 : : static PyTypeObject Unpickler_Type;
717 : :
718 : : #include "clinic/_pickle.c.h"
719 : :
720 : : /*************************************************************************
721 : : A custom hashtable mapping void* to Python ints. This is used by the pickler
722 : : for memoization. Using a custom hashtable rather than PyDict allows us to skip
723 : : a bunch of unnecessary object creation. This makes a huge performance
724 : : difference. */
725 : :
726 : : #define MT_MINSIZE 8
727 : : #define PERTURB_SHIFT 5
728 : :
729 : :
730 : : static PyMemoTable *
731 : 0 : PyMemoTable_New(void)
732 : : {
733 : 0 : PyMemoTable *memo = PyMem_Malloc(sizeof(PyMemoTable));
734 [ # # ]: 0 : if (memo == NULL) {
735 : 0 : PyErr_NoMemory();
736 : 0 : return NULL;
737 : : }
738 : :
739 : 0 : memo->mt_used = 0;
740 : 0 : memo->mt_allocated = MT_MINSIZE;
741 : 0 : memo->mt_mask = MT_MINSIZE - 1;
742 : 0 : memo->mt_table = PyMem_Malloc(MT_MINSIZE * sizeof(PyMemoEntry));
743 [ # # ]: 0 : if (memo->mt_table == NULL) {
744 : 0 : PyMem_Free(memo);
745 : 0 : PyErr_NoMemory();
746 : 0 : return NULL;
747 : : }
748 : 0 : memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry));
749 : :
750 : 0 : return memo;
751 : : }
752 : :
753 : : static PyMemoTable *
754 : 0 : PyMemoTable_Copy(PyMemoTable *self)
755 : : {
756 : 0 : PyMemoTable *new = PyMemoTable_New();
757 [ # # ]: 0 : if (new == NULL)
758 : 0 : return NULL;
759 : :
760 : 0 : new->mt_used = self->mt_used;
761 : 0 : new->mt_allocated = self->mt_allocated;
762 : 0 : new->mt_mask = self->mt_mask;
763 : : /* The table we get from _New() is probably smaller than we wanted.
764 : : Free it and allocate one that's the right size. */
765 : 0 : PyMem_Free(new->mt_table);
766 [ # # ]: 0 : new->mt_table = PyMem_NEW(PyMemoEntry, self->mt_allocated);
767 [ # # ]: 0 : if (new->mt_table == NULL) {
768 : 0 : PyMem_Free(new);
769 : 0 : PyErr_NoMemory();
770 : 0 : return NULL;
771 : : }
772 [ # # ]: 0 : for (size_t i = 0; i < self->mt_allocated; i++) {
773 : 0 : Py_XINCREF(self->mt_table[i].me_key);
774 : : }
775 : 0 : memcpy(new->mt_table, self->mt_table,
776 : 0 : sizeof(PyMemoEntry) * self->mt_allocated);
777 : :
778 : 0 : return new;
779 : : }
780 : :
781 : : static Py_ssize_t
782 : 0 : PyMemoTable_Size(PyMemoTable *self)
783 : : {
784 : 0 : return self->mt_used;
785 : : }
786 : :
787 : : static int
788 : 0 : PyMemoTable_Clear(PyMemoTable *self)
789 : : {
790 : 0 : Py_ssize_t i = self->mt_allocated;
791 : :
792 [ # # ]: 0 : while (--i >= 0) {
793 : 0 : Py_XDECREF(self->mt_table[i].me_key);
794 : : }
795 : 0 : self->mt_used = 0;
796 : 0 : memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry));
797 : 0 : return 0;
798 : : }
799 : :
800 : : static void
801 : 0 : PyMemoTable_Del(PyMemoTable *self)
802 : : {
803 [ # # ]: 0 : if (self == NULL)
804 : 0 : return;
805 : 0 : PyMemoTable_Clear(self);
806 : :
807 : 0 : PyMem_Free(self->mt_table);
808 : 0 : PyMem_Free(self);
809 : : }
810 : :
811 : : /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup()
812 : : can be considerably simpler than dictobject.c's lookdict(). */
813 : : static PyMemoEntry *
814 : 0 : _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
815 : : {
816 : : size_t i;
817 : : size_t perturb;
818 : 0 : size_t mask = self->mt_mask;
819 : 0 : PyMemoEntry *table = self->mt_table;
820 : : PyMemoEntry *entry;
821 : 0 : Py_hash_t hash = (Py_hash_t)key >> 3;
822 : :
823 : 0 : i = hash & mask;
824 : 0 : entry = &table[i];
825 [ # # # # ]: 0 : if (entry->me_key == NULL || entry->me_key == key)
826 : 0 : return entry;
827 : :
828 : 0 : for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
829 : 0 : i = (i << 2) + i + perturb + 1;
830 : 0 : entry = &table[i & mask];
831 [ # # # # ]: 0 : if (entry->me_key == NULL || entry->me_key == key)
832 : 0 : return entry;
833 : : }
834 : : Py_UNREACHABLE();
835 : : }
836 : :
837 : : /* Returns -1 on failure, 0 on success. */
838 : : static int
839 : 0 : _PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size)
840 : : {
841 : 0 : PyMemoEntry *oldtable = NULL;
842 : : PyMemoEntry *oldentry, *newentry;
843 : 0 : size_t new_size = MT_MINSIZE;
844 : : size_t to_process;
845 : :
846 : : assert(min_size > 0);
847 : :
848 [ # # ]: 0 : if (min_size > PY_SSIZE_T_MAX) {
849 : 0 : PyErr_NoMemory();
850 : 0 : return -1;
851 : : }
852 : :
853 : : /* Find the smallest valid table size >= min_size. */
854 [ # # ]: 0 : while (new_size < min_size) {
855 : 0 : new_size <<= 1;
856 : : }
857 : : /* new_size needs to be a power of two. */
858 : : assert((new_size & (new_size - 1)) == 0);
859 : :
860 : : /* Allocate new table. */
861 : 0 : oldtable = self->mt_table;
862 [ # # ]: 0 : self->mt_table = PyMem_NEW(PyMemoEntry, new_size);
863 [ # # ]: 0 : if (self->mt_table == NULL) {
864 : 0 : self->mt_table = oldtable;
865 : 0 : PyErr_NoMemory();
866 : 0 : return -1;
867 : : }
868 : 0 : self->mt_allocated = new_size;
869 : 0 : self->mt_mask = new_size - 1;
870 : 0 : memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size);
871 : :
872 : : /* Copy entries from the old table. */
873 : 0 : to_process = self->mt_used;
874 [ # # ]: 0 : for (oldentry = oldtable; to_process > 0; oldentry++) {
875 [ # # ]: 0 : if (oldentry->me_key != NULL) {
876 : 0 : to_process--;
877 : : /* newentry is a pointer to a chunk of the new
878 : : mt_table, so we're setting the key:value pair
879 : : in-place. */
880 : 0 : newentry = _PyMemoTable_Lookup(self, oldentry->me_key);
881 : 0 : newentry->me_key = oldentry->me_key;
882 : 0 : newentry->me_value = oldentry->me_value;
883 : : }
884 : : }
885 : :
886 : : /* Deallocate the old table. */
887 : 0 : PyMem_Free(oldtable);
888 : 0 : return 0;
889 : : }
890 : :
891 : : /* Returns NULL on failure, a pointer to the value otherwise. */
892 : : static Py_ssize_t *
893 : 0 : PyMemoTable_Get(PyMemoTable *self, PyObject *key)
894 : : {
895 : 0 : PyMemoEntry *entry = _PyMemoTable_Lookup(self, key);
896 [ # # ]: 0 : if (entry->me_key == NULL)
897 : 0 : return NULL;
898 : 0 : return &entry->me_value;
899 : : }
900 : :
901 : : /* Returns -1 on failure, 0 on success. */
902 : : static int
903 : 0 : PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value)
904 : : {
905 : : PyMemoEntry *entry;
906 : :
907 : : assert(key != NULL);
908 : :
909 : 0 : entry = _PyMemoTable_Lookup(self, key);
910 [ # # ]: 0 : if (entry->me_key != NULL) {
911 : 0 : entry->me_value = value;
912 : 0 : return 0;
913 : : }
914 : 0 : entry->me_key = Py_NewRef(key);
915 : 0 : entry->me_value = value;
916 : 0 : self->mt_used++;
917 : :
918 : : /* If we added a key, we can safely resize. Otherwise just return!
919 : : * If used >= 2/3 size, adjust size. Normally, this quaduples the size.
920 : : *
921 : : * Quadrupling the size improves average table sparseness
922 : : * (reducing collisions) at the cost of some memory. It also halves
923 : : * the number of expensive resize operations in a growing memo table.
924 : : *
925 : : * Very large memo tables (over 50K items) use doubling instead.
926 : : * This may help applications with severe memory constraints.
927 : : */
928 [ # # # # ]: 0 : if (SIZE_MAX / 3 >= self->mt_used && self->mt_used * 3 < self->mt_allocated * 2) {
929 : 0 : return 0;
930 : : }
931 : : // self->mt_used is always < PY_SSIZE_T_MAX, so this can't overflow.
932 [ # # ]: 0 : size_t desired_size = (self->mt_used > 50000 ? 2 : 4) * self->mt_used;
933 : 0 : return _PyMemoTable_ResizeTable(self, desired_size);
934 : : }
935 : :
936 : : #undef MT_MINSIZE
937 : : #undef PERTURB_SHIFT
938 : :
939 : : /*************************************************************************/
940 : :
941 : :
942 : : static int
943 : 0 : _Pickler_ClearBuffer(PicklerObject *self)
944 : : {
945 : 0 : Py_XSETREF(self->output_buffer,
946 : : PyBytes_FromStringAndSize(NULL, self->max_output_len));
947 [ # # ]: 0 : if (self->output_buffer == NULL)
948 : 0 : return -1;
949 : 0 : self->output_len = 0;
950 : 0 : self->frame_start = -1;
951 : 0 : return 0;
952 : : }
953 : :
954 : : static void
955 : 0 : _write_size64(char *out, size_t value)
956 : : {
957 : : size_t i;
958 : :
959 : : static_assert(sizeof(size_t) <= 8, "size_t is larger than 64-bit");
960 : :
961 [ # # ]: 0 : for (i = 0; i < sizeof(size_t); i++) {
962 : 0 : out[i] = (unsigned char)((value >> (8 * i)) & 0xff);
963 : : }
964 [ # # ]: 0 : for (i = sizeof(size_t); i < 8; i++) {
965 : 0 : out[i] = 0;
966 : : }
967 : 0 : }
968 : :
969 : : static int
970 : 0 : _Pickler_CommitFrame(PicklerObject *self)
971 : : {
972 : : size_t frame_len;
973 : : char *qdata;
974 : :
975 [ # # # # ]: 0 : if (!self->framing || self->frame_start == -1)
976 : 0 : return 0;
977 : 0 : frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE;
978 : 0 : qdata = PyBytes_AS_STRING(self->output_buffer) + self->frame_start;
979 [ # # ]: 0 : if (frame_len >= FRAME_SIZE_MIN) {
980 : 0 : qdata[0] = FRAME;
981 : 0 : _write_size64(qdata + 1, frame_len);
982 : : }
983 : : else {
984 : 0 : memmove(qdata, qdata + FRAME_HEADER_SIZE, frame_len);
985 : 0 : self->output_len -= FRAME_HEADER_SIZE;
986 : : }
987 : 0 : self->frame_start = -1;
988 : 0 : return 0;
989 : : }
990 : :
991 : : static PyObject *
992 : 0 : _Pickler_GetString(PicklerObject *self)
993 : : {
994 : 0 : PyObject *output_buffer = self->output_buffer;
995 : :
996 : : assert(self->output_buffer != NULL);
997 : :
998 [ # # ]: 0 : if (_Pickler_CommitFrame(self))
999 : 0 : return NULL;
1000 : :
1001 : 0 : self->output_buffer = NULL;
1002 : : /* Resize down to exact size */
1003 [ # # ]: 0 : if (_PyBytes_Resize(&output_buffer, self->output_len) < 0)
1004 : 0 : return NULL;
1005 : 0 : return output_buffer;
1006 : : }
1007 : :
1008 : : static int
1009 : 0 : _Pickler_FlushToFile(PicklerObject *self)
1010 : : {
1011 : : PyObject *output, *result;
1012 : :
1013 : : assert(self->write != NULL);
1014 : :
1015 : : /* This will commit the frame first */
1016 : 0 : output = _Pickler_GetString(self);
1017 [ # # ]: 0 : if (output == NULL)
1018 : 0 : return -1;
1019 : :
1020 : 0 : result = _Pickle_FastCall(self->write, output);
1021 : 0 : Py_XDECREF(result);
1022 [ # # ]: 0 : return (result == NULL) ? -1 : 0;
1023 : : }
1024 : :
1025 : : static int
1026 : 0 : _Pickler_OpcodeBoundary(PicklerObject *self)
1027 : : {
1028 : : Py_ssize_t frame_len;
1029 : :
1030 [ # # # # ]: 0 : if (!self->framing || self->frame_start == -1) {
1031 : 0 : return 0;
1032 : : }
1033 : 0 : frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE;
1034 [ # # ]: 0 : if (frame_len >= FRAME_SIZE_TARGET) {
1035 [ # # ]: 0 : if(_Pickler_CommitFrame(self)) {
1036 : 0 : return -1;
1037 : : }
1038 : : /* Flush the content of the committed frame to the underlying
1039 : : * file and reuse the pickler buffer for the next frame so as
1040 : : * to limit memory usage when dumping large complex objects to
1041 : : * a file.
1042 : : *
1043 : : * self->write is NULL when called via dumps.
1044 : : */
1045 [ # # ]: 0 : if (self->write != NULL) {
1046 [ # # ]: 0 : if (_Pickler_FlushToFile(self) < 0) {
1047 : 0 : return -1;
1048 : : }
1049 [ # # ]: 0 : if (_Pickler_ClearBuffer(self) < 0) {
1050 : 0 : return -1;
1051 : : }
1052 : : }
1053 : : }
1054 : 0 : return 0;
1055 : : }
1056 : :
1057 : : static Py_ssize_t
1058 : 0 : _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len)
1059 : : {
1060 : : Py_ssize_t i, n, required;
1061 : : char *buffer;
1062 : : int need_new_frame;
1063 : :
1064 : : assert(s != NULL);
1065 [ # # # # ]: 0 : need_new_frame = (self->framing && self->frame_start == -1);
1066 : :
1067 [ # # ]: 0 : if (need_new_frame)
1068 : 0 : n = data_len + FRAME_HEADER_SIZE;
1069 : : else
1070 : 0 : n = data_len;
1071 : :
1072 : 0 : required = self->output_len + n;
1073 [ # # ]: 0 : if (required > self->max_output_len) {
1074 : : /* Make place in buffer for the pickle chunk */
1075 [ # # ]: 0 : if (self->output_len >= PY_SSIZE_T_MAX / 2 - n) {
1076 : 0 : PyErr_NoMemory();
1077 : 0 : return -1;
1078 : : }
1079 : 0 : self->max_output_len = (self->output_len + n) / 2 * 3;
1080 [ # # ]: 0 : if (_PyBytes_Resize(&self->output_buffer, self->max_output_len) < 0)
1081 : 0 : return -1;
1082 : : }
1083 : 0 : buffer = PyBytes_AS_STRING(self->output_buffer);
1084 [ # # ]: 0 : if (need_new_frame) {
1085 : : /* Setup new frame */
1086 : 0 : Py_ssize_t frame_start = self->output_len;
1087 : 0 : self->frame_start = frame_start;
1088 [ # # ]: 0 : for (i = 0; i < FRAME_HEADER_SIZE; i++) {
1089 : : /* Write an invalid value, for debugging */
1090 : 0 : buffer[frame_start + i] = 0xFE;
1091 : : }
1092 : 0 : self->output_len += FRAME_HEADER_SIZE;
1093 : : }
1094 [ # # ]: 0 : if (data_len < 8) {
1095 : : /* This is faster than memcpy when the string is short. */
1096 [ # # ]: 0 : for (i = 0; i < data_len; i++) {
1097 : 0 : buffer[self->output_len + i] = s[i];
1098 : : }
1099 : : }
1100 : : else {
1101 : 0 : memcpy(buffer + self->output_len, s, data_len);
1102 : : }
1103 : 0 : self->output_len += data_len;
1104 : 0 : return data_len;
1105 : : }
1106 : :
1107 : : static PicklerObject *
1108 : 0 : _Pickler_New(void)
1109 : : {
1110 : : PicklerObject *self;
1111 : :
1112 : 0 : self = PyObject_GC_New(PicklerObject, &Pickler_Type);
1113 [ # # ]: 0 : if (self == NULL)
1114 : 0 : return NULL;
1115 : :
1116 : 0 : self->pers_func = NULL;
1117 : 0 : self->dispatch_table = NULL;
1118 : 0 : self->buffer_callback = NULL;
1119 : 0 : self->write = NULL;
1120 : 0 : self->proto = 0;
1121 : 0 : self->bin = 0;
1122 : 0 : self->framing = 0;
1123 : 0 : self->frame_start = -1;
1124 : 0 : self->fast = 0;
1125 : 0 : self->fast_nesting = 0;
1126 : 0 : self->fix_imports = 0;
1127 : 0 : self->fast_memo = NULL;
1128 : 0 : self->max_output_len = WRITE_BUF_SIZE;
1129 : 0 : self->output_len = 0;
1130 : 0 : self->reducer_override = NULL;
1131 : :
1132 : 0 : self->memo = PyMemoTable_New();
1133 : 0 : self->output_buffer = PyBytes_FromStringAndSize(NULL,
1134 : : self->max_output_len);
1135 : :
1136 [ # # # # ]: 0 : if (self->memo == NULL || self->output_buffer == NULL) {
1137 : 0 : Py_DECREF(self);
1138 : 0 : return NULL;
1139 : : }
1140 : :
1141 : 0 : PyObject_GC_Track(self);
1142 : 0 : return self;
1143 : : }
1144 : :
1145 : : static int
1146 : 0 : _Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports)
1147 : : {
1148 : : long proto;
1149 : :
1150 [ # # ]: 0 : if (protocol == Py_None) {
1151 : 0 : proto = DEFAULT_PROTOCOL;
1152 : : }
1153 : : else {
1154 : 0 : proto = PyLong_AsLong(protocol);
1155 [ # # ]: 0 : if (proto < 0) {
1156 [ # # # # ]: 0 : if (proto == -1 && PyErr_Occurred())
1157 : 0 : return -1;
1158 : 0 : proto = HIGHEST_PROTOCOL;
1159 : : }
1160 [ # # ]: 0 : else if (proto > HIGHEST_PROTOCOL) {
1161 : 0 : PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
1162 : : HIGHEST_PROTOCOL);
1163 : 0 : return -1;
1164 : : }
1165 : : }
1166 : 0 : self->proto = (int)proto;
1167 : 0 : self->bin = proto > 0;
1168 [ # # # # ]: 0 : self->fix_imports = fix_imports && proto < 3;
1169 : 0 : return 0;
1170 : : }
1171 : :
1172 : : /* Returns -1 (with an exception set) on failure, 0 on success. This may
1173 : : be called once on a freshly created Pickler. */
1174 : : static int
1175 : 0 : _Pickler_SetOutputStream(PicklerObject *self, PyObject *file)
1176 : : {
1177 : : assert(file != NULL);
1178 [ # # ]: 0 : if (_PyObject_LookupAttr(file, &_Py_ID(write), &self->write) < 0) {
1179 : 0 : return -1;
1180 : : }
1181 [ # # ]: 0 : if (self->write == NULL) {
1182 : 0 : PyErr_SetString(PyExc_TypeError,
1183 : : "file must have a 'write' attribute");
1184 : 0 : return -1;
1185 : : }
1186 : :
1187 : 0 : return 0;
1188 : : }
1189 : :
1190 : : static int
1191 : 0 : _Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback)
1192 : : {
1193 [ # # ]: 0 : if (buffer_callback == Py_None) {
1194 : 0 : buffer_callback = NULL;
1195 : : }
1196 [ # # # # ]: 0 : if (buffer_callback != NULL && self->proto < 5) {
1197 : 0 : PyErr_SetString(PyExc_ValueError,
1198 : : "buffer_callback needs protocol >= 5");
1199 : 0 : return -1;
1200 : : }
1201 : :
1202 : 0 : self->buffer_callback = Py_XNewRef(buffer_callback);
1203 : 0 : return 0;
1204 : : }
1205 : :
1206 : : /* Returns the size of the input on success, -1 on failure. This takes its
1207 : : own reference to `input`. */
1208 : : static Py_ssize_t
1209 : 0 : _Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input)
1210 : : {
1211 [ # # ]: 0 : if (self->buffer.buf != NULL)
1212 : 0 : PyBuffer_Release(&self->buffer);
1213 [ # # ]: 0 : if (PyObject_GetBuffer(input, &self->buffer, PyBUF_CONTIG_RO) < 0)
1214 : 0 : return -1;
1215 : 0 : self->input_buffer = self->buffer.buf;
1216 : 0 : self->input_len = self->buffer.len;
1217 : 0 : self->next_read_idx = 0;
1218 : 0 : self->prefetched_idx = self->input_len;
1219 : 0 : return self->input_len;
1220 : : }
1221 : :
1222 : : static int
1223 : 0 : bad_readline(void)
1224 : : {
1225 : 0 : PickleState *st = _Pickle_GetGlobalState();
1226 : 0 : PyErr_SetString(st->UnpicklingError, "pickle data was truncated");
1227 : 0 : return -1;
1228 : : }
1229 : :
1230 : : /* Skip any consumed data that was only prefetched using peek() */
1231 : : static int
1232 : 0 : _Unpickler_SkipConsumed(UnpicklerObject *self)
1233 : : {
1234 : : Py_ssize_t consumed;
1235 : : PyObject *r;
1236 : :
1237 : 0 : consumed = self->next_read_idx - self->prefetched_idx;
1238 [ # # ]: 0 : if (consumed <= 0)
1239 : 0 : return 0;
1240 : :
1241 : : assert(self->peek); /* otherwise we did something wrong */
1242 : : /* This makes a useless copy... */
1243 : 0 : r = PyObject_CallFunction(self->read, "n", consumed);
1244 [ # # ]: 0 : if (r == NULL)
1245 : 0 : return -1;
1246 : 0 : Py_DECREF(r);
1247 : :
1248 : 0 : self->prefetched_idx = self->next_read_idx;
1249 : 0 : return 0;
1250 : : }
1251 : :
1252 : : static const Py_ssize_t READ_WHOLE_LINE = -1;
1253 : :
1254 : : /* If reading from a file, we need to only pull the bytes we need, since there
1255 : : may be multiple pickle objects arranged contiguously in the same input
1256 : : buffer.
1257 : :
1258 : : If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n`
1259 : : bytes from the input stream/buffer.
1260 : :
1261 : : Update the unpickler's input buffer with the newly-read data. Returns -1 on
1262 : : failure; on success, returns the number of bytes read from the file.
1263 : :
1264 : : On success, self->input_len will be 0; this is intentional so that when
1265 : : unpickling from a file, the "we've run out of data" code paths will trigger,
1266 : : causing the Unpickler to go back to the file for more data. Use the returned
1267 : : size to tell you how much data you can process. */
1268 : : static Py_ssize_t
1269 : 0 : _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
1270 : : {
1271 : : PyObject *data;
1272 : : Py_ssize_t read_size;
1273 : :
1274 : : assert(self->read != NULL);
1275 : :
1276 [ # # ]: 0 : if (_Unpickler_SkipConsumed(self) < 0)
1277 : 0 : return -1;
1278 : :
1279 [ # # ]: 0 : if (n == READ_WHOLE_LINE) {
1280 : 0 : data = PyObject_CallNoArgs(self->readline);
1281 : : }
1282 : : else {
1283 : : PyObject *len;
1284 : : /* Prefetch some data without advancing the file pointer, if possible */
1285 [ # # # # ]: 0 : if (self->peek && n < PREFETCH) {
1286 : 0 : len = PyLong_FromSsize_t(PREFETCH);
1287 [ # # ]: 0 : if (len == NULL)
1288 : 0 : return -1;
1289 : 0 : data = _Pickle_FastCall(self->peek, len);
1290 [ # # ]: 0 : if (data == NULL) {
1291 [ # # ]: 0 : if (!PyErr_ExceptionMatches(PyExc_NotImplementedError))
1292 : 0 : return -1;
1293 : : /* peek() is probably not supported by the given file object */
1294 : 0 : PyErr_Clear();
1295 [ # # ]: 0 : Py_CLEAR(self->peek);
1296 : : }
1297 : : else {
1298 : 0 : read_size = _Unpickler_SetStringInput(self, data);
1299 : 0 : Py_DECREF(data);
1300 : 0 : self->prefetched_idx = 0;
1301 [ # # ]: 0 : if (n <= read_size)
1302 : 0 : return n;
1303 : : }
1304 : : }
1305 : 0 : len = PyLong_FromSsize_t(n);
1306 [ # # ]: 0 : if (len == NULL)
1307 : 0 : return -1;
1308 : 0 : data = _Pickle_FastCall(self->read, len);
1309 : : }
1310 [ # # ]: 0 : if (data == NULL)
1311 : 0 : return -1;
1312 : :
1313 : 0 : read_size = _Unpickler_SetStringInput(self, data);
1314 : 0 : Py_DECREF(data);
1315 : 0 : return read_size;
1316 : : }
1317 : :
1318 : : /* Don't call it directly: use _Unpickler_Read() */
1319 : : static Py_ssize_t
1320 : 0 : _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n)
1321 : : {
1322 : : Py_ssize_t num_read;
1323 : :
1324 : 0 : *s = NULL;
1325 [ # # ]: 0 : if (self->next_read_idx > PY_SSIZE_T_MAX - n) {
1326 : 0 : PickleState *st = _Pickle_GetGlobalState();
1327 : 0 : PyErr_SetString(st->UnpicklingError,
1328 : : "read would overflow (invalid bytecode)");
1329 : 0 : return -1;
1330 : : }
1331 : :
1332 : : /* This case is handled by the _Unpickler_Read() macro for efficiency */
1333 : : assert(self->next_read_idx + n > self->input_len);
1334 : :
1335 [ # # ]: 0 : if (!self->read)
1336 : 0 : return bad_readline();
1337 : :
1338 : : /* Extend the buffer to satisfy desired size */
1339 : 0 : num_read = _Unpickler_ReadFromFile(self, n);
1340 [ # # ]: 0 : if (num_read < 0)
1341 : 0 : return -1;
1342 [ # # ]: 0 : if (num_read < n)
1343 : 0 : return bad_readline();
1344 : 0 : *s = self->input_buffer;
1345 : 0 : self->next_read_idx = n;
1346 : 0 : return n;
1347 : : }
1348 : :
1349 : : /* Read `n` bytes from the unpickler's data source, storing the result in `buf`.
1350 : : *
1351 : : * This should only be used for non-small data reads where potentially
1352 : : * avoiding a copy is beneficial. This method does not try to prefetch
1353 : : * more data into the input buffer.
1354 : : *
1355 : : * _Unpickler_Read() is recommended in most cases.
1356 : : */
1357 : : static Py_ssize_t
1358 : 0 : _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n)
1359 : : {
1360 : : assert(n != READ_WHOLE_LINE);
1361 : :
1362 : : /* Read from available buffer data, if any */
1363 : 0 : Py_ssize_t in_buffer = self->input_len - self->next_read_idx;
1364 [ # # ]: 0 : if (in_buffer > 0) {
1365 : 0 : Py_ssize_t to_read = Py_MIN(in_buffer, n);
1366 : 0 : memcpy(buf, self->input_buffer + self->next_read_idx, to_read);
1367 : 0 : self->next_read_idx += to_read;
1368 : 0 : buf += to_read;
1369 : 0 : n -= to_read;
1370 [ # # ]: 0 : if (n == 0) {
1371 : : /* Entire read was satisfied from buffer */
1372 : 0 : return n;
1373 : : }
1374 : : }
1375 : :
1376 : : /* Read from file */
1377 [ # # ]: 0 : if (!self->read) {
1378 : : /* We're unpickling memory, this means the input is truncated */
1379 : 0 : return bad_readline();
1380 : : }
1381 [ # # ]: 0 : if (_Unpickler_SkipConsumed(self) < 0) {
1382 : 0 : return -1;
1383 : : }
1384 : :
1385 [ # # ]: 0 : if (!self->readinto) {
1386 : : /* readinto() not supported on file-like object, fall back to read()
1387 : : * and copy into destination buffer (bpo-39681) */
1388 : 0 : PyObject* len = PyLong_FromSsize_t(n);
1389 [ # # ]: 0 : if (len == NULL) {
1390 : 0 : return -1;
1391 : : }
1392 : 0 : PyObject* data = _Pickle_FastCall(self->read, len);
1393 [ # # ]: 0 : if (data == NULL) {
1394 : 0 : return -1;
1395 : : }
1396 [ # # ]: 0 : if (!PyBytes_Check(data)) {
1397 : 0 : PyErr_Format(PyExc_ValueError,
1398 : : "read() returned non-bytes object (%R)",
1399 : : Py_TYPE(data));
1400 : 0 : Py_DECREF(data);
1401 : 0 : return -1;
1402 : : }
1403 : 0 : Py_ssize_t read_size = PyBytes_GET_SIZE(data);
1404 [ # # ]: 0 : if (read_size < n) {
1405 : 0 : Py_DECREF(data);
1406 : 0 : return bad_readline();
1407 : : }
1408 : 0 : memcpy(buf, PyBytes_AS_STRING(data), n);
1409 : 0 : Py_DECREF(data);
1410 : 0 : return n;
1411 : : }
1412 : :
1413 : : /* Call readinto() into user buffer */
1414 : 0 : PyObject *buf_obj = PyMemoryView_FromMemory(buf, n, PyBUF_WRITE);
1415 [ # # ]: 0 : if (buf_obj == NULL) {
1416 : 0 : return -1;
1417 : : }
1418 : 0 : PyObject *read_size_obj = _Pickle_FastCall(self->readinto, buf_obj);
1419 [ # # ]: 0 : if (read_size_obj == NULL) {
1420 : 0 : return -1;
1421 : : }
1422 : 0 : Py_ssize_t read_size = PyLong_AsSsize_t(read_size_obj);
1423 : 0 : Py_DECREF(read_size_obj);
1424 : :
1425 [ # # ]: 0 : if (read_size < 0) {
1426 [ # # ]: 0 : if (!PyErr_Occurred()) {
1427 : 0 : PyErr_SetString(PyExc_ValueError,
1428 : : "readinto() returned negative size");
1429 : : }
1430 : 0 : return -1;
1431 : : }
1432 [ # # ]: 0 : if (read_size < n) {
1433 : 0 : return bad_readline();
1434 : : }
1435 : 0 : return n;
1436 : : }
1437 : :
1438 : : /* Read `n` bytes from the unpickler's data source, storing the result in `*s`.
1439 : :
1440 : : This should be used for all data reads, rather than accessing the unpickler's
1441 : : input buffer directly. This method deals correctly with reading from input
1442 : : streams, which the input buffer doesn't deal with.
1443 : :
1444 : : Note that when reading from a file-like object, self->next_read_idx won't
1445 : : be updated (it should remain at 0 for the entire unpickling process). You
1446 : : should use this function's return value to know how many bytes you can
1447 : : consume.
1448 : :
1449 : : Returns -1 (with an exception set) on failure. On success, return the
1450 : : number of chars read. */
1451 : : #define _Unpickler_Read(self, s, n) \
1452 : : (((n) <= (self)->input_len - (self)->next_read_idx) \
1453 : : ? (*(s) = (self)->input_buffer + (self)->next_read_idx, \
1454 : : (self)->next_read_idx += (n), \
1455 : : (n)) \
1456 : : : _Unpickler_ReadImpl(self, (s), (n)))
1457 : :
1458 : : static Py_ssize_t
1459 : 0 : _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len,
1460 : : char **result)
1461 : : {
1462 : 0 : char *input_line = PyMem_Realloc(self->input_line, len + 1);
1463 [ # # ]: 0 : if (input_line == NULL) {
1464 : 0 : PyErr_NoMemory();
1465 : 0 : return -1;
1466 : : }
1467 : :
1468 : 0 : memcpy(input_line, line, len);
1469 : 0 : input_line[len] = '\0';
1470 : 0 : self->input_line = input_line;
1471 : 0 : *result = self->input_line;
1472 : 0 : return len;
1473 : : }
1474 : :
1475 : : /* Read a line from the input stream/buffer. If we run off the end of the input
1476 : : before hitting \n, raise an error.
1477 : :
1478 : : Returns the number of chars read, or -1 on failure. */
1479 : : static Py_ssize_t
1480 : 0 : _Unpickler_Readline(UnpicklerObject *self, char **result)
1481 : : {
1482 : : Py_ssize_t i, num_read;
1483 : :
1484 [ # # ]: 0 : for (i = self->next_read_idx; i < self->input_len; i++) {
1485 [ # # ]: 0 : if (self->input_buffer[i] == '\n') {
1486 : 0 : char *line_start = self->input_buffer + self->next_read_idx;
1487 : 0 : num_read = i - self->next_read_idx + 1;
1488 : 0 : self->next_read_idx = i + 1;
1489 : 0 : return _Unpickler_CopyLine(self, line_start, num_read, result);
1490 : : }
1491 : : }
1492 [ # # ]: 0 : if (!self->read)
1493 : 0 : return bad_readline();
1494 : :
1495 : 0 : num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE);
1496 [ # # ]: 0 : if (num_read < 0)
1497 : 0 : return -1;
1498 [ # # # # ]: 0 : if (num_read == 0 || self->input_buffer[num_read - 1] != '\n')
1499 : 0 : return bad_readline();
1500 : 0 : self->next_read_idx = num_read;
1501 : 0 : return _Unpickler_CopyLine(self, self->input_buffer, num_read, result);
1502 : : }
1503 : :
1504 : : /* Returns -1 (with an exception set) on failure, 0 on success. The memo array
1505 : : will be modified in place. */
1506 : : static int
1507 : 0 : _Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size)
1508 : : {
1509 : : size_t i;
1510 : :
1511 : : assert(new_size > self->memo_size);
1512 : :
1513 : 0 : PyObject **memo_new = self->memo;
1514 [ # # ]: 0 : PyMem_RESIZE(memo_new, PyObject *, new_size);
1515 [ # # ]: 0 : if (memo_new == NULL) {
1516 : 0 : PyErr_NoMemory();
1517 : 0 : return -1;
1518 : : }
1519 : 0 : self->memo = memo_new;
1520 [ # # ]: 0 : for (i = self->memo_size; i < new_size; i++)
1521 : 0 : self->memo[i] = NULL;
1522 : 0 : self->memo_size = new_size;
1523 : 0 : return 0;
1524 : : }
1525 : :
1526 : : /* Returns NULL if idx is out of bounds. */
1527 : : static PyObject *
1528 : 0 : _Unpickler_MemoGet(UnpicklerObject *self, size_t idx)
1529 : : {
1530 [ # # ]: 0 : if (idx >= self->memo_size)
1531 : 0 : return NULL;
1532 : :
1533 : 0 : return self->memo[idx];
1534 : : }
1535 : :
1536 : : /* Returns -1 (with an exception set) on failure, 0 on success.
1537 : : This takes its own reference to `value`. */
1538 : : static int
1539 : 0 : _Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value)
1540 : : {
1541 : : PyObject *old_item;
1542 : :
1543 [ # # ]: 0 : if (idx >= self->memo_size) {
1544 [ # # ]: 0 : if (_Unpickler_ResizeMemoList(self, idx * 2) < 0)
1545 : 0 : return -1;
1546 : : assert(idx < self->memo_size);
1547 : : }
1548 : 0 : old_item = self->memo[idx];
1549 : 0 : self->memo[idx] = Py_NewRef(value);
1550 [ # # ]: 0 : if (old_item != NULL) {
1551 : 0 : Py_DECREF(old_item);
1552 : : }
1553 : : else {
1554 : 0 : self->memo_len++;
1555 : : }
1556 : 0 : return 0;
1557 : : }
1558 : :
1559 : : static PyObject **
1560 : 0 : _Unpickler_NewMemo(Py_ssize_t new_size)
1561 : : {
1562 [ # # ]: 0 : PyObject **memo = PyMem_NEW(PyObject *, new_size);
1563 [ # # ]: 0 : if (memo == NULL) {
1564 : 0 : PyErr_NoMemory();
1565 : 0 : return NULL;
1566 : : }
1567 : 0 : memset(memo, 0, new_size * sizeof(PyObject *));
1568 : 0 : return memo;
1569 : : }
1570 : :
1571 : : /* Free the unpickler's memo, taking care to decref any items left in it. */
1572 : : static void
1573 : 0 : _Unpickler_MemoCleanup(UnpicklerObject *self)
1574 : : {
1575 : : Py_ssize_t i;
1576 : 0 : PyObject **memo = self->memo;
1577 : :
1578 [ # # ]: 0 : if (self->memo == NULL)
1579 : 0 : return;
1580 : 0 : self->memo = NULL;
1581 : 0 : i = self->memo_size;
1582 [ # # ]: 0 : while (--i >= 0) {
1583 : 0 : Py_XDECREF(memo[i]);
1584 : : }
1585 : 0 : PyMem_Free(memo);
1586 : : }
1587 : :
1588 : : static UnpicklerObject *
1589 : 0 : _Unpickler_New(void)
1590 : : {
1591 : : UnpicklerObject *self;
1592 : :
1593 : 0 : self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
1594 [ # # ]: 0 : if (self == NULL)
1595 : 0 : return NULL;
1596 : :
1597 : 0 : self->pers_func = NULL;
1598 : 0 : self->input_buffer = NULL;
1599 : 0 : self->input_line = NULL;
1600 : 0 : self->input_len = 0;
1601 : 0 : self->next_read_idx = 0;
1602 : 0 : self->prefetched_idx = 0;
1603 : 0 : self->read = NULL;
1604 : 0 : self->readinto = NULL;
1605 : 0 : self->readline = NULL;
1606 : 0 : self->peek = NULL;
1607 : 0 : self->buffers = NULL;
1608 : 0 : self->encoding = NULL;
1609 : 0 : self->errors = NULL;
1610 : 0 : self->marks = NULL;
1611 : 0 : self->num_marks = 0;
1612 : 0 : self->marks_size = 0;
1613 : 0 : self->proto = 0;
1614 : 0 : self->fix_imports = 0;
1615 : 0 : memset(&self->buffer, 0, sizeof(Py_buffer));
1616 : 0 : self->memo_size = 32;
1617 : 0 : self->memo_len = 0;
1618 : 0 : self->memo = _Unpickler_NewMemo(self->memo_size);
1619 : 0 : self->stack = (Pdata *)Pdata_New();
1620 : :
1621 [ # # # # ]: 0 : if (self->memo == NULL || self->stack == NULL) {
1622 : 0 : Py_DECREF(self);
1623 : 0 : return NULL;
1624 : : }
1625 : :
1626 : 0 : PyObject_GC_Track(self);
1627 : 0 : return self;
1628 : : }
1629 : :
1630 : : /* Returns -1 (with an exception set) on failure, 0 on success. This may
1631 : : be called once on a freshly created Unpickler. */
1632 : : static int
1633 : 0 : _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
1634 : : {
1635 : : /* Optional file methods */
1636 [ # # ]: 0 : if (_PyObject_LookupAttr(file, &_Py_ID(peek), &self->peek) < 0) {
1637 : 0 : return -1;
1638 : : }
1639 [ # # ]: 0 : if (_PyObject_LookupAttr(file, &_Py_ID(readinto), &self->readinto) < 0) {
1640 : 0 : return -1;
1641 : : }
1642 : 0 : (void)_PyObject_LookupAttr(file, &_Py_ID(read), &self->read);
1643 : 0 : (void)_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline);
1644 [ # # # # ]: 0 : if (!self->readline || !self->read) {
1645 [ # # ]: 0 : if (!PyErr_Occurred()) {
1646 : 0 : PyErr_SetString(PyExc_TypeError,
1647 : : "file must have 'read' and 'readline' attributes");
1648 : : }
1649 [ # # ]: 0 : Py_CLEAR(self->read);
1650 [ # # ]: 0 : Py_CLEAR(self->readinto);
1651 [ # # ]: 0 : Py_CLEAR(self->readline);
1652 [ # # ]: 0 : Py_CLEAR(self->peek);
1653 : 0 : return -1;
1654 : : }
1655 : 0 : return 0;
1656 : : }
1657 : :
1658 : : /* Returns -1 (with an exception set) on failure, 0 on success. This may
1659 : : be called once on a freshly created Unpickler. */
1660 : : static int
1661 : 0 : _Unpickler_SetInputEncoding(UnpicklerObject *self,
1662 : : const char *encoding,
1663 : : const char *errors)
1664 : : {
1665 [ # # ]: 0 : if (encoding == NULL)
1666 : 0 : encoding = "ASCII";
1667 [ # # ]: 0 : if (errors == NULL)
1668 : 0 : errors = "strict";
1669 : :
1670 : 0 : self->encoding = _PyMem_Strdup(encoding);
1671 : 0 : self->errors = _PyMem_Strdup(errors);
1672 [ # # # # ]: 0 : if (self->encoding == NULL || self->errors == NULL) {
1673 : 0 : PyErr_NoMemory();
1674 : 0 : return -1;
1675 : : }
1676 : 0 : return 0;
1677 : : }
1678 : :
1679 : : /* Returns -1 (with an exception set) on failure, 0 on success. This may
1680 : : be called once on a freshly created Unpickler. */
1681 : : static int
1682 : 0 : _Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers)
1683 : : {
1684 [ # # # # ]: 0 : if (buffers == NULL || buffers == Py_None) {
1685 : 0 : self->buffers = NULL;
1686 : : }
1687 : : else {
1688 : 0 : self->buffers = PyObject_GetIter(buffers);
1689 [ # # ]: 0 : if (self->buffers == NULL) {
1690 : 0 : return -1;
1691 : : }
1692 : : }
1693 : 0 : return 0;
1694 : : }
1695 : :
1696 : : /* Generate a GET opcode for an object stored in the memo. */
1697 : : static int
1698 : 0 : memo_get(PicklerObject *self, PyObject *key)
1699 : : {
1700 : : Py_ssize_t *value;
1701 : : char pdata[30];
1702 : : Py_ssize_t len;
1703 : :
1704 : 0 : value = PyMemoTable_Get(self->memo, key);
1705 [ # # ]: 0 : if (value == NULL) {
1706 : 0 : PyErr_SetObject(PyExc_KeyError, key);
1707 : 0 : return -1;
1708 : : }
1709 : :
1710 [ # # ]: 0 : if (!self->bin) {
1711 : 0 : pdata[0] = GET;
1712 : 0 : PyOS_snprintf(pdata + 1, sizeof(pdata) - 1,
1713 : : "%zd\n", *value);
1714 : 0 : len = strlen(pdata);
1715 : : }
1716 : : else {
1717 [ # # ]: 0 : if (*value < 256) {
1718 : 0 : pdata[0] = BINGET;
1719 : 0 : pdata[1] = (unsigned char)(*value & 0xff);
1720 : 0 : len = 2;
1721 : : }
1722 [ # # ]: 0 : else if ((size_t)*value <= 0xffffffffUL) {
1723 : 0 : pdata[0] = LONG_BINGET;
1724 : 0 : pdata[1] = (unsigned char)(*value & 0xff);
1725 : 0 : pdata[2] = (unsigned char)((*value >> 8) & 0xff);
1726 : 0 : pdata[3] = (unsigned char)((*value >> 16) & 0xff);
1727 : 0 : pdata[4] = (unsigned char)((*value >> 24) & 0xff);
1728 : 0 : len = 5;
1729 : : }
1730 : : else { /* unlikely */
1731 : 0 : PickleState *st = _Pickle_GetGlobalState();
1732 : 0 : PyErr_SetString(st->PicklingError,
1733 : : "memo id too large for LONG_BINGET");
1734 : 0 : return -1;
1735 : : }
1736 : : }
1737 : :
1738 [ # # ]: 0 : if (_Pickler_Write(self, pdata, len) < 0)
1739 : 0 : return -1;
1740 : :
1741 : 0 : return 0;
1742 : : }
1743 : :
1744 : : /* Store an object in the memo, assign it a new unique ID based on the number
1745 : : of objects currently stored in the memo and generate a PUT opcode. */
1746 : : static int
1747 : 0 : memo_put(PicklerObject *self, PyObject *obj)
1748 : : {
1749 : : char pdata[30];
1750 : : Py_ssize_t len;
1751 : : Py_ssize_t idx;
1752 : :
1753 : 0 : const char memoize_op = MEMOIZE;
1754 : :
1755 [ # # ]: 0 : if (self->fast)
1756 : 0 : return 0;
1757 : :
1758 : 0 : idx = PyMemoTable_Size(self->memo);
1759 [ # # ]: 0 : if (PyMemoTable_Set(self->memo, obj, idx) < 0)
1760 : 0 : return -1;
1761 : :
1762 [ # # ]: 0 : if (self->proto >= 4) {
1763 [ # # ]: 0 : if (_Pickler_Write(self, &memoize_op, 1) < 0)
1764 : 0 : return -1;
1765 : 0 : return 0;
1766 : : }
1767 [ # # ]: 0 : else if (!self->bin) {
1768 : 0 : pdata[0] = PUT;
1769 : 0 : PyOS_snprintf(pdata + 1, sizeof(pdata) - 1,
1770 : : "%zd\n", idx);
1771 : 0 : len = strlen(pdata);
1772 : : }
1773 : : else {
1774 [ # # ]: 0 : if (idx < 256) {
1775 : 0 : pdata[0] = BINPUT;
1776 : 0 : pdata[1] = (unsigned char)idx;
1777 : 0 : len = 2;
1778 : : }
1779 [ # # ]: 0 : else if ((size_t)idx <= 0xffffffffUL) {
1780 : 0 : pdata[0] = LONG_BINPUT;
1781 : 0 : pdata[1] = (unsigned char)(idx & 0xff);
1782 : 0 : pdata[2] = (unsigned char)((idx >> 8) & 0xff);
1783 : 0 : pdata[3] = (unsigned char)((idx >> 16) & 0xff);
1784 : 0 : pdata[4] = (unsigned char)((idx >> 24) & 0xff);
1785 : 0 : len = 5;
1786 : : }
1787 : : else { /* unlikely */
1788 : 0 : PickleState *st = _Pickle_GetGlobalState();
1789 : 0 : PyErr_SetString(st->PicklingError,
1790 : : "memo id too large for LONG_BINPUT");
1791 : 0 : return -1;
1792 : : }
1793 : : }
1794 [ # # ]: 0 : if (_Pickler_Write(self, pdata, len) < 0)
1795 : 0 : return -1;
1796 : :
1797 : 0 : return 0;
1798 : : }
1799 : :
1800 : : static PyObject *
1801 : 0 : get_dotted_path(PyObject *obj, PyObject *name)
1802 : : {
1803 : : PyObject *dotted_path;
1804 : : Py_ssize_t i, n;
1805 : : _Py_DECLARE_STR(dot, ".");
1806 : 0 : dotted_path = PyUnicode_Split(name, &_Py_STR(dot), -1);
1807 [ # # ]: 0 : if (dotted_path == NULL)
1808 : 0 : return NULL;
1809 : 0 : n = PyList_GET_SIZE(dotted_path);
1810 : : assert(n >= 1);
1811 [ # # ]: 0 : for (i = 0; i < n; i++) {
1812 : 0 : PyObject *subpath = PyList_GET_ITEM(dotted_path, i);
1813 [ # # ]: 0 : if (_PyUnicode_EqualToASCIIString(subpath, "<locals>")) {
1814 [ # # ]: 0 : if (obj == NULL)
1815 : 0 : PyErr_Format(PyExc_AttributeError,
1816 : : "Can't pickle local object %R", name);
1817 : : else
1818 : 0 : PyErr_Format(PyExc_AttributeError,
1819 : : "Can't pickle local attribute %R on %R", name, obj);
1820 : 0 : Py_DECREF(dotted_path);
1821 : 0 : return NULL;
1822 : : }
1823 : : }
1824 : 0 : return dotted_path;
1825 : : }
1826 : :
1827 : : static PyObject *
1828 : 0 : get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
1829 : : {
1830 : : Py_ssize_t i, n;
1831 : 0 : PyObject *parent = NULL;
1832 : :
1833 : : assert(PyList_CheckExact(names));
1834 : 0 : Py_INCREF(obj);
1835 : 0 : n = PyList_GET_SIZE(names);
1836 [ # # ]: 0 : for (i = 0; i < n; i++) {
1837 : 0 : PyObject *name = PyList_GET_ITEM(names, i);
1838 : 0 : Py_XSETREF(parent, obj);
1839 : 0 : (void)_PyObject_LookupAttr(parent, name, &obj);
1840 [ # # ]: 0 : if (obj == NULL) {
1841 : 0 : Py_DECREF(parent);
1842 : 0 : return NULL;
1843 : : }
1844 : : }
1845 [ # # ]: 0 : if (pparent != NULL)
1846 : 0 : *pparent = parent;
1847 : : else
1848 : 0 : Py_XDECREF(parent);
1849 : 0 : return obj;
1850 : : }
1851 : :
1852 : :
1853 : : static PyObject *
1854 : 0 : getattribute(PyObject *obj, PyObject *name, int allow_qualname)
1855 : : {
1856 : : PyObject *dotted_path, *attr;
1857 : :
1858 [ # # ]: 0 : if (allow_qualname) {
1859 : 0 : dotted_path = get_dotted_path(obj, name);
1860 [ # # ]: 0 : if (dotted_path == NULL)
1861 : 0 : return NULL;
1862 : 0 : attr = get_deep_attribute(obj, dotted_path, NULL);
1863 : 0 : Py_DECREF(dotted_path);
1864 : : }
1865 : : else {
1866 : 0 : (void)_PyObject_LookupAttr(obj, name, &attr);
1867 : : }
1868 [ # # # # ]: 0 : if (attr == NULL && !PyErr_Occurred()) {
1869 : 0 : PyErr_Format(PyExc_AttributeError,
1870 : : "Can't get attribute %R on %R", name, obj);
1871 : : }
1872 : 0 : return attr;
1873 : : }
1874 : :
1875 : : static int
1876 : 0 : _checkmodule(PyObject *module_name, PyObject *module,
1877 : : PyObject *global, PyObject *dotted_path)
1878 : : {
1879 [ # # ]: 0 : if (module == Py_None) {
1880 : 0 : return -1;
1881 : : }
1882 [ # # # # ]: 0 : if (PyUnicode_Check(module_name) &&
1883 : 0 : _PyUnicode_EqualToASCIIString(module_name, "__main__")) {
1884 : 0 : return -1;
1885 : : }
1886 : :
1887 : 0 : PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);
1888 [ # # ]: 0 : if (candidate == NULL) {
1889 : 0 : return -1;
1890 : : }
1891 [ # # ]: 0 : if (candidate != global) {
1892 : 0 : Py_DECREF(candidate);
1893 : 0 : return -1;
1894 : : }
1895 : 0 : Py_DECREF(candidate);
1896 : 0 : return 0;
1897 : : }
1898 : :
1899 : : static PyObject *
1900 : 0 : whichmodule(PyObject *global, PyObject *dotted_path)
1901 : : {
1902 : : PyObject *module_name;
1903 : 0 : PyObject *module = NULL;
1904 : : Py_ssize_t i;
1905 : : PyObject *modules;
1906 : :
1907 [ # # ]: 0 : if (_PyObject_LookupAttr(global, &_Py_ID(__module__), &module_name) < 0) {
1908 : 0 : return NULL;
1909 : : }
1910 [ # # ]: 0 : if (module_name) {
1911 : : /* In some rare cases (e.g., bound methods of extension types),
1912 : : __module__ can be None. If it is so, then search sys.modules for
1913 : : the module of global. */
1914 [ # # ]: 0 : if (module_name != Py_None)
1915 : 0 : return module_name;
1916 [ # # ]: 0 : Py_CLEAR(module_name);
1917 : : }
1918 : : assert(module_name == NULL);
1919 : :
1920 : : /* Fallback on walking sys.modules */
1921 : 0 : PyThreadState *tstate = _PyThreadState_GET();
1922 : 0 : modules = _PySys_GetAttr(tstate, &_Py_ID(modules));
1923 [ # # ]: 0 : if (modules == NULL) {
1924 : 0 : PyErr_SetString(PyExc_RuntimeError, "unable to get sys.modules");
1925 : 0 : return NULL;
1926 : : }
1927 [ # # ]: 0 : if (PyDict_CheckExact(modules)) {
1928 : 0 : i = 0;
1929 [ # # ]: 0 : while (PyDict_Next(modules, &i, &module_name, &module)) {
1930 [ # # ]: 0 : if (_checkmodule(module_name, module, global, dotted_path) == 0) {
1931 : 0 : return Py_NewRef(module_name);
1932 : : }
1933 [ # # ]: 0 : if (PyErr_Occurred()) {
1934 : 0 : return NULL;
1935 : : }
1936 : : }
1937 : : }
1938 : : else {
1939 : 0 : PyObject *iterator = PyObject_GetIter(modules);
1940 [ # # ]: 0 : if (iterator == NULL) {
1941 : 0 : return NULL;
1942 : : }
1943 [ # # ]: 0 : while ((module_name = PyIter_Next(iterator))) {
1944 : 0 : module = PyObject_GetItem(modules, module_name);
1945 [ # # ]: 0 : if (module == NULL) {
1946 : 0 : Py_DECREF(module_name);
1947 : 0 : Py_DECREF(iterator);
1948 : 0 : return NULL;
1949 : : }
1950 [ # # ]: 0 : if (_checkmodule(module_name, module, global, dotted_path) == 0) {
1951 : 0 : Py_DECREF(module);
1952 : 0 : Py_DECREF(iterator);
1953 : 0 : return module_name;
1954 : : }
1955 : 0 : Py_DECREF(module);
1956 : 0 : Py_DECREF(module_name);
1957 [ # # ]: 0 : if (PyErr_Occurred()) {
1958 : 0 : Py_DECREF(iterator);
1959 : 0 : return NULL;
1960 : : }
1961 : : }
1962 : 0 : Py_DECREF(iterator);
1963 : : }
1964 : :
1965 : : /* If no module is found, use __main__. */
1966 : 0 : module_name = &_Py_ID(__main__);
1967 : 0 : return Py_NewRef(module_name);
1968 : : }
1969 : :
1970 : : /* fast_save_enter() and fast_save_leave() are guards against recursive
1971 : : objects when Pickler is used with the "fast mode" (i.e., with object
1972 : : memoization disabled). If the nesting of a list or dict object exceed
1973 : : FAST_NESTING_LIMIT, these guards will start keeping an internal
1974 : : reference to the seen list or dict objects and check whether these objects
1975 : : are recursive. These are not strictly necessary, since save() has a
1976 : : hard-coded recursion limit, but they give a nicer error message than the
1977 : : typical RuntimeError. */
1978 : : static int
1979 : 0 : fast_save_enter(PicklerObject *self, PyObject *obj)
1980 : : {
1981 : : /* if fast_nesting < 0, we're doing an error exit. */
1982 [ # # ]: 0 : if (++self->fast_nesting >= FAST_NESTING_LIMIT) {
1983 : 0 : PyObject *key = NULL;
1984 [ # # ]: 0 : if (self->fast_memo == NULL) {
1985 : 0 : self->fast_memo = PyDict_New();
1986 [ # # ]: 0 : if (self->fast_memo == NULL) {
1987 : 0 : self->fast_nesting = -1;
1988 : 0 : return 0;
1989 : : }
1990 : : }
1991 : 0 : key = PyLong_FromVoidPtr(obj);
1992 [ # # ]: 0 : if (key == NULL) {
1993 : 0 : self->fast_nesting = -1;
1994 : 0 : return 0;
1995 : : }
1996 : 0 : int r = PyDict_Contains(self->fast_memo, key);
1997 [ # # ]: 0 : if (r > 0) {
1998 : 0 : PyErr_Format(PyExc_ValueError,
1999 : : "fast mode: can't pickle cyclic objects "
2000 : : "including object type %.200s at %p",
2001 : 0 : Py_TYPE(obj)->tp_name, obj);
2002 : : }
2003 [ # # ]: 0 : else if (r == 0) {
2004 : 0 : r = PyDict_SetItem(self->fast_memo, key, Py_None);
2005 : : }
2006 : 0 : Py_DECREF(key);
2007 [ # # ]: 0 : if (r != 0) {
2008 : 0 : self->fast_nesting = -1;
2009 : 0 : return 0;
2010 : : }
2011 : : }
2012 : 0 : return 1;
2013 : : }
2014 : :
2015 : : static int
2016 : 0 : fast_save_leave(PicklerObject *self, PyObject *obj)
2017 : : {
2018 [ # # ]: 0 : if (self->fast_nesting-- >= FAST_NESTING_LIMIT) {
2019 : 0 : PyObject *key = PyLong_FromVoidPtr(obj);
2020 [ # # ]: 0 : if (key == NULL)
2021 : 0 : return 0;
2022 [ # # ]: 0 : if (PyDict_DelItem(self->fast_memo, key) < 0) {
2023 : 0 : Py_DECREF(key);
2024 : 0 : return 0;
2025 : : }
2026 : 0 : Py_DECREF(key);
2027 : : }
2028 : 0 : return 1;
2029 : : }
2030 : :
2031 : : static int
2032 : 0 : save_none(PicklerObject *self, PyObject *obj)
2033 : : {
2034 : 0 : const char none_op = NONE;
2035 [ # # ]: 0 : if (_Pickler_Write(self, &none_op, 1) < 0)
2036 : 0 : return -1;
2037 : :
2038 : 0 : return 0;
2039 : : }
2040 : :
2041 : : static int
2042 : 0 : save_bool(PicklerObject *self, PyObject *obj)
2043 : : {
2044 [ # # ]: 0 : if (self->proto >= 2) {
2045 [ # # ]: 0 : const char bool_op = (obj == Py_True) ? NEWTRUE : NEWFALSE;
2046 [ # # ]: 0 : if (_Pickler_Write(self, &bool_op, 1) < 0)
2047 : 0 : return -1;
2048 : : }
2049 : : else {
2050 : : /* These aren't opcodes -- they're ways to pickle bools before protocol 2
2051 : : * so that unpicklers written before bools were introduced unpickle them
2052 : : * as ints, but unpicklers after can recognize that bools were intended.
2053 : : * Note that protocol 2 added direct ways to pickle bools.
2054 : : */
2055 [ # # ]: 0 : const char *bool_str = (obj == Py_True) ? "I01\n" : "I00\n";
2056 [ # # ]: 0 : if (_Pickler_Write(self, bool_str, strlen(bool_str)) < 0)
2057 : 0 : return -1;
2058 : : }
2059 : 0 : return 0;
2060 : : }
2061 : :
2062 : : static int
2063 : 0 : save_long(PicklerObject *self, PyObject *obj)
2064 : : {
2065 : 0 : PyObject *repr = NULL;
2066 : : Py_ssize_t size;
2067 : : long val;
2068 : : int overflow;
2069 : 0 : int status = 0;
2070 : :
2071 : 0 : val= PyLong_AsLongAndOverflow(obj, &overflow);
2072 [ # # # # : 0 : if (!overflow && (sizeof(long) <= 4 ||
# # ]
2073 : : (val <= 0x7fffffffL && val >= (-0x7fffffffL - 1))))
2074 : : {
2075 : : /* result fits in a signed 4-byte integer.
2076 : :
2077 : : Note: we can't use -0x80000000L in the above condition because some
2078 : : compilers (e.g., MSVC) will promote 0x80000000L to an unsigned type
2079 : : before applying the unary minus when sizeof(long) <= 4. The
2080 : : resulting value stays unsigned which is commonly not what we want,
2081 : : so MSVC happily warns us about it. However, that result would have
2082 : : been fine because we guard for sizeof(long) <= 4 which turns the
2083 : : condition true in that particular case. */
2084 : : char pdata[32];
2085 : 0 : Py_ssize_t len = 0;
2086 : :
2087 [ # # ]: 0 : if (self->bin) {
2088 : 0 : pdata[1] = (unsigned char)(val & 0xff);
2089 : 0 : pdata[2] = (unsigned char)((val >> 8) & 0xff);
2090 : 0 : pdata[3] = (unsigned char)((val >> 16) & 0xff);
2091 : 0 : pdata[4] = (unsigned char)((val >> 24) & 0xff);
2092 : :
2093 [ # # # # ]: 0 : if ((pdata[4] != 0) || (pdata[3] != 0)) {
2094 : 0 : pdata[0] = BININT;
2095 : 0 : len = 5;
2096 : : }
2097 [ # # ]: 0 : else if (pdata[2] != 0) {
2098 : 0 : pdata[0] = BININT2;
2099 : 0 : len = 3;
2100 : : }
2101 : : else {
2102 : 0 : pdata[0] = BININT1;
2103 : 0 : len = 2;
2104 : : }
2105 : : }
2106 : : else {
2107 : 0 : sprintf(pdata, "%c%ld\n", INT, val);
2108 : 0 : len = strlen(pdata);
2109 : : }
2110 [ # # ]: 0 : if (_Pickler_Write(self, pdata, len) < 0)
2111 : 0 : return -1;
2112 : :
2113 : 0 : return 0;
2114 : : }
2115 : : assert(!PyErr_Occurred());
2116 : :
2117 [ # # ]: 0 : if (self->proto >= 2) {
2118 : : /* Linear-time pickling. */
2119 : : size_t nbits;
2120 : : size_t nbytes;
2121 : : unsigned char *pdata;
2122 : : char header[5];
2123 : : int i;
2124 : 0 : int sign = _PyLong_Sign(obj);
2125 : :
2126 [ # # ]: 0 : if (sign == 0) {
2127 : 0 : header[0] = LONG1;
2128 : 0 : header[1] = 0; /* It's 0 -- an empty bytestring. */
2129 [ # # ]: 0 : if (_Pickler_Write(self, header, 2) < 0)
2130 : 0 : goto error;
2131 : 0 : return 0;
2132 : : }
2133 : 0 : nbits = _PyLong_NumBits(obj);
2134 [ # # # # ]: 0 : if (nbits == (size_t)-1 && PyErr_Occurred())
2135 : 0 : goto error;
2136 : : /* How many bytes do we need? There are nbits >> 3 full
2137 : : * bytes of data, and nbits & 7 leftover bits. If there
2138 : : * are any leftover bits, then we clearly need another
2139 : : * byte. What's not so obvious is that we *probably*
2140 : : * need another byte even if there aren't any leftovers:
2141 : : * the most-significant bit of the most-significant byte
2142 : : * acts like a sign bit, and it's usually got a sense
2143 : : * opposite of the one we need. The exception is ints
2144 : : * of the form -(2**(8*j-1)) for j > 0. Such an int is
2145 : : * its own 256's-complement, so has the right sign bit
2146 : : * even without the extra byte. That's a pain to check
2147 : : * for in advance, though, so we always grab an extra
2148 : : * byte at the start, and cut it back later if possible.
2149 : : */
2150 : 0 : nbytes = (nbits >> 3) + 1;
2151 [ # # ]: 0 : if (nbytes > 0x7fffffffL) {
2152 : 0 : PyErr_SetString(PyExc_OverflowError,
2153 : : "int too large to pickle");
2154 : 0 : goto error;
2155 : : }
2156 : 0 : repr = PyBytes_FromStringAndSize(NULL, (Py_ssize_t)nbytes);
2157 [ # # ]: 0 : if (repr == NULL)
2158 : 0 : goto error;
2159 : 0 : pdata = (unsigned char *)PyBytes_AS_STRING(repr);
2160 : 0 : i = _PyLong_AsByteArray((PyLongObject *)obj,
2161 : : pdata, nbytes,
2162 : : 1 /* little endian */ , 1 /* signed */ );
2163 [ # # ]: 0 : if (i < 0)
2164 : 0 : goto error;
2165 : : /* If the int is negative, this may be a byte more than
2166 : : * needed. This is so iff the MSB is all redundant sign
2167 : : * bits.
2168 : : */
2169 [ # # # # ]: 0 : if (sign < 0 &&
2170 : 0 : nbytes > 1 &&
2171 [ # # ]: 0 : pdata[nbytes - 1] == 0xff &&
2172 [ # # ]: 0 : (pdata[nbytes - 2] & 0x80) != 0) {
2173 : 0 : nbytes--;
2174 : : }
2175 : :
2176 [ # # ]: 0 : if (nbytes < 256) {
2177 : 0 : header[0] = LONG1;
2178 : 0 : header[1] = (unsigned char)nbytes;
2179 : 0 : size = 2;
2180 : : }
2181 : : else {
2182 : 0 : header[0] = LONG4;
2183 : 0 : size = (Py_ssize_t) nbytes;
2184 [ # # ]: 0 : for (i = 1; i < 5; i++) {
2185 : 0 : header[i] = (unsigned char)(size & 0xff);
2186 : 0 : size >>= 8;
2187 : : }
2188 : 0 : size = 5;
2189 : : }
2190 [ # # # # ]: 0 : if (_Pickler_Write(self, header, size) < 0 ||
2191 : 0 : _Pickler_Write(self, (char *)pdata, (int)nbytes) < 0)
2192 : 0 : goto error;
2193 : : }
2194 : : else {
2195 : 0 : const char long_op = LONG;
2196 : : const char *string;
2197 : :
2198 : : /* proto < 2: write the repr and newline. This is quadratic-time (in
2199 : : the number of digits), in both directions. We add a trailing 'L'
2200 : : to the repr, for compatibility with Python 2.x. */
2201 : :
2202 : 0 : repr = PyObject_Repr(obj);
2203 [ # # ]: 0 : if (repr == NULL)
2204 : 0 : goto error;
2205 : :
2206 : 0 : string = PyUnicode_AsUTF8AndSize(repr, &size);
2207 [ # # ]: 0 : if (string == NULL)
2208 : 0 : goto error;
2209 : :
2210 [ # # # # ]: 0 : if (_Pickler_Write(self, &long_op, 1) < 0 ||
2211 [ # # ]: 0 : _Pickler_Write(self, string, size) < 0 ||
2212 : 0 : _Pickler_Write(self, "L\n", 2) < 0)
2213 : 0 : goto error;
2214 : : }
2215 : :
2216 : : if (0) {
2217 : 0 : error:
2218 : 0 : status = -1;
2219 : : }
2220 : 0 : Py_XDECREF(repr);
2221 : :
2222 : 0 : return status;
2223 : : }
2224 : :
2225 : : static int
2226 : 0 : save_float(PicklerObject *self, PyObject *obj)
2227 : : {
2228 : 0 : double x = PyFloat_AS_DOUBLE((PyFloatObject *)obj);
2229 : :
2230 [ # # ]: 0 : if (self->bin) {
2231 : : char pdata[9];
2232 : 0 : pdata[0] = BINFLOAT;
2233 [ # # ]: 0 : if (PyFloat_Pack8(x, &pdata[1], 0) < 0)
2234 : 0 : return -1;
2235 [ # # ]: 0 : if (_Pickler_Write(self, pdata, 9) < 0)
2236 : 0 : return -1;
2237 : : }
2238 : : else {
2239 : 0 : int result = -1;
2240 : 0 : char *buf = NULL;
2241 : 0 : char op = FLOAT;
2242 : :
2243 [ # # ]: 0 : if (_Pickler_Write(self, &op, 1) < 0)
2244 : 0 : goto done;
2245 : :
2246 : 0 : buf = PyOS_double_to_string(x, 'r', 0, Py_DTSF_ADD_DOT_0, NULL);
2247 [ # # ]: 0 : if (!buf) {
2248 : 0 : PyErr_NoMemory();
2249 : 0 : goto done;
2250 : : }
2251 : :
2252 [ # # ]: 0 : if (_Pickler_Write(self, buf, strlen(buf)) < 0)
2253 : 0 : goto done;
2254 : :
2255 [ # # ]: 0 : if (_Pickler_Write(self, "\n", 1) < 0)
2256 : 0 : goto done;
2257 : :
2258 : 0 : result = 0;
2259 : 0 : done:
2260 : 0 : PyMem_Free(buf);
2261 : 0 : return result;
2262 : : }
2263 : :
2264 : 0 : return 0;
2265 : : }
2266 : :
2267 : : /* Perform direct write of the header and payload of the binary object.
2268 : :
2269 : : The large contiguous data is written directly into the underlying file
2270 : : object, bypassing the output_buffer of the Pickler. We intentionally
2271 : : do not insert a protocol 4 frame opcode to make it possible to optimize
2272 : : file.read calls in the loader.
2273 : : */
2274 : : static int
2275 : 0 : _Pickler_write_bytes(PicklerObject *self,
2276 : : const char *header, Py_ssize_t header_size,
2277 : : const char *data, Py_ssize_t data_size,
2278 : : PyObject *payload)
2279 : : {
2280 : 0 : int bypass_buffer = (data_size >= FRAME_SIZE_TARGET);
2281 : 0 : int framing = self->framing;
2282 : :
2283 [ # # ]: 0 : if (bypass_buffer) {
2284 : : assert(self->output_buffer != NULL);
2285 : : /* Commit the previous frame. */
2286 [ # # ]: 0 : if (_Pickler_CommitFrame(self)) {
2287 : 0 : return -1;
2288 : : }
2289 : : /* Disable framing temporarily */
2290 : 0 : self->framing = 0;
2291 : : }
2292 : :
2293 [ # # ]: 0 : if (_Pickler_Write(self, header, header_size) < 0) {
2294 : 0 : return -1;
2295 : : }
2296 : :
2297 [ # # # # ]: 0 : if (bypass_buffer && self->write != NULL) {
2298 : : /* Bypass the in-memory buffer to directly stream large data
2299 : : into the underlying file object. */
2300 : 0 : PyObject *result, *mem = NULL;
2301 : : /* Dump the output buffer to the file. */
2302 [ # # ]: 0 : if (_Pickler_FlushToFile(self) < 0) {
2303 : 0 : return -1;
2304 : : }
2305 : :
2306 : : /* Stream write the payload into the file without going through the
2307 : : output buffer. */
2308 [ # # ]: 0 : if (payload == NULL) {
2309 : : /* TODO: It would be better to use a memoryview with a linked
2310 : : original string if this is possible. */
2311 : 0 : payload = mem = PyBytes_FromStringAndSize(data, data_size);
2312 [ # # ]: 0 : if (payload == NULL) {
2313 : 0 : return -1;
2314 : : }
2315 : : }
2316 : 0 : result = PyObject_CallOneArg(self->write, payload);
2317 : 0 : Py_XDECREF(mem);
2318 [ # # ]: 0 : if (result == NULL) {
2319 : 0 : return -1;
2320 : : }
2321 : 0 : Py_DECREF(result);
2322 : :
2323 : : /* Reinitialize the buffer for subsequent calls to _Pickler_Write. */
2324 [ # # ]: 0 : if (_Pickler_ClearBuffer(self) < 0) {
2325 : 0 : return -1;
2326 : : }
2327 : : }
2328 : : else {
2329 [ # # ]: 0 : if (_Pickler_Write(self, data, data_size) < 0) {
2330 : 0 : return -1;
2331 : : }
2332 : : }
2333 : :
2334 : : /* Re-enable framing for subsequent calls to _Pickler_Write. */
2335 : 0 : self->framing = framing;
2336 : :
2337 : 0 : return 0;
2338 : : }
2339 : :
2340 : : static int
2341 : 0 : _save_bytes_data(PicklerObject *self, PyObject *obj, const char *data,
2342 : : Py_ssize_t size)
2343 : : {
2344 : : assert(self->proto >= 3);
2345 : :
2346 : : char header[9];
2347 : : Py_ssize_t len;
2348 : :
2349 [ # # ]: 0 : if (size < 0)
2350 : 0 : return -1;
2351 : :
2352 [ # # ]: 0 : if (size <= 0xff) {
2353 : 0 : header[0] = SHORT_BINBYTES;
2354 : 0 : header[1] = (unsigned char)size;
2355 : 0 : len = 2;
2356 : : }
2357 [ # # ]: 0 : else if ((size_t)size <= 0xffffffffUL) {
2358 : 0 : header[0] = BINBYTES;
2359 : 0 : header[1] = (unsigned char)(size & 0xff);
2360 : 0 : header[2] = (unsigned char)((size >> 8) & 0xff);
2361 : 0 : header[3] = (unsigned char)((size >> 16) & 0xff);
2362 : 0 : header[4] = (unsigned char)((size >> 24) & 0xff);
2363 : 0 : len = 5;
2364 : : }
2365 [ # # ]: 0 : else if (self->proto >= 4) {
2366 : 0 : header[0] = BINBYTES8;
2367 : 0 : _write_size64(header + 1, size);
2368 : 0 : len = 9;
2369 : : }
2370 : : else {
2371 : 0 : PyErr_SetString(PyExc_OverflowError,
2372 : : "serializing a bytes object larger than 4 GiB "
2373 : : "requires pickle protocol 4 or higher");
2374 : 0 : return -1;
2375 : : }
2376 : :
2377 [ # # ]: 0 : if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) {
2378 : 0 : return -1;
2379 : : }
2380 : :
2381 [ # # ]: 0 : if (memo_put(self, obj) < 0) {
2382 : 0 : return -1;
2383 : : }
2384 : :
2385 : 0 : return 0;
2386 : : }
2387 : :
2388 : : static int
2389 : 0 : save_bytes(PicklerObject *self, PyObject *obj)
2390 : : {
2391 [ # # ]: 0 : if (self->proto < 3) {
2392 : : /* Older pickle protocols do not have an opcode for pickling bytes
2393 : : objects. Therefore, we need to fake the copy protocol (i.e.,
2394 : : the __reduce__ method) to permit bytes object unpickling.
2395 : :
2396 : : Here we use a hack to be compatible with Python 2. Since in Python
2397 : : 2 'bytes' is just an alias for 'str' (which has different
2398 : : parameters than the actual bytes object), we use codecs.encode
2399 : : to create the appropriate 'str' object when unpickled using
2400 : : Python 2 *and* the appropriate 'bytes' object when unpickled
2401 : : using Python 3. Again this is a hack and we don't need to do this
2402 : : with newer protocols. */
2403 : : PyObject *reduce_value;
2404 : : int status;
2405 : :
2406 [ # # ]: 0 : if (PyBytes_GET_SIZE(obj) == 0) {
2407 : 0 : reduce_value = Py_BuildValue("(O())", (PyObject*)&PyBytes_Type);
2408 : : }
2409 : : else {
2410 : 0 : PickleState *st = _Pickle_GetGlobalState();
2411 : : PyObject *unicode_str =
2412 : 0 : PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj),
2413 : : PyBytes_GET_SIZE(obj),
2414 : : "strict");
2415 : :
2416 [ # # ]: 0 : if (unicode_str == NULL)
2417 : 0 : return -1;
2418 : 0 : reduce_value = Py_BuildValue("(O(OO))",
2419 : : st->codecs_encode, unicode_str,
2420 : : &_Py_ID(latin1));
2421 : 0 : Py_DECREF(unicode_str);
2422 : : }
2423 : :
2424 [ # # ]: 0 : if (reduce_value == NULL)
2425 : 0 : return -1;
2426 : :
2427 : : /* save_reduce() will memoize the object automatically. */
2428 : 0 : status = save_reduce(self, reduce_value, obj);
2429 : 0 : Py_DECREF(reduce_value);
2430 : 0 : return status;
2431 : : }
2432 : : else {
2433 : 0 : return _save_bytes_data(self, obj, PyBytes_AS_STRING(obj),
2434 : : PyBytes_GET_SIZE(obj));
2435 : : }
2436 : : }
2437 : :
2438 : : static int
2439 : 0 : _save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data,
2440 : : Py_ssize_t size)
2441 : : {
2442 : : assert(self->proto >= 5);
2443 : :
2444 : : char header[9];
2445 : : Py_ssize_t len;
2446 : :
2447 [ # # ]: 0 : if (size < 0)
2448 : 0 : return -1;
2449 : :
2450 : 0 : header[0] = BYTEARRAY8;
2451 : 0 : _write_size64(header + 1, size);
2452 : 0 : len = 9;
2453 : :
2454 [ # # ]: 0 : if (_Pickler_write_bytes(self, header, len, data, size, obj) < 0) {
2455 : 0 : return -1;
2456 : : }
2457 : :
2458 [ # # ]: 0 : if (memo_put(self, obj) < 0) {
2459 : 0 : return -1;
2460 : : }
2461 : :
2462 : 0 : return 0;
2463 : : }
2464 : :
2465 : : static int
2466 : 0 : save_bytearray(PicklerObject *self, PyObject *obj)
2467 : : {
2468 [ # # ]: 0 : if (self->proto < 5) {
2469 : : /* Older pickle protocols do not have an opcode for pickling
2470 : : * bytearrays. */
2471 : 0 : PyObject *reduce_value = NULL;
2472 : : int status;
2473 : :
2474 [ # # ]: 0 : if (PyByteArray_GET_SIZE(obj) == 0) {
2475 : 0 : reduce_value = Py_BuildValue("(O())",
2476 : : (PyObject *) &PyByteArray_Type);
2477 : : }
2478 : : else {
2479 : 0 : PyObject *bytes_obj = PyBytes_FromObject(obj);
2480 [ # # ]: 0 : if (bytes_obj != NULL) {
2481 : 0 : reduce_value = Py_BuildValue("(O(O))",
2482 : : (PyObject *) &PyByteArray_Type,
2483 : : bytes_obj);
2484 : 0 : Py_DECREF(bytes_obj);
2485 : : }
2486 : : }
2487 [ # # ]: 0 : if (reduce_value == NULL)
2488 : 0 : return -1;
2489 : :
2490 : : /* save_reduce() will memoize the object automatically. */
2491 : 0 : status = save_reduce(self, reduce_value, obj);
2492 : 0 : Py_DECREF(reduce_value);
2493 : 0 : return status;
2494 : : }
2495 : : else {
2496 : 0 : return _save_bytearray_data(self, obj, PyByteArray_AS_STRING(obj),
2497 : : PyByteArray_GET_SIZE(obj));
2498 : : }
2499 : : }
2500 : :
2501 : : static int
2502 : 0 : save_picklebuffer(PicklerObject *self, PyObject *obj)
2503 : : {
2504 [ # # ]: 0 : if (self->proto < 5) {
2505 : 0 : PickleState *st = _Pickle_GetGlobalState();
2506 : 0 : PyErr_SetString(st->PicklingError,
2507 : : "PickleBuffer can only pickled with protocol >= 5");
2508 : 0 : return -1;
2509 : : }
2510 : 0 : const Py_buffer* view = PyPickleBuffer_GetBuffer(obj);
2511 [ # # ]: 0 : if (view == NULL) {
2512 : 0 : return -1;
2513 : : }
2514 [ # # # # ]: 0 : if (view->suboffsets != NULL || !PyBuffer_IsContiguous(view, 'A')) {
2515 : 0 : PickleState *st = _Pickle_GetGlobalState();
2516 : 0 : PyErr_SetString(st->PicklingError,
2517 : : "PickleBuffer can not be pickled when "
2518 : : "pointing to a non-contiguous buffer");
2519 : 0 : return -1;
2520 : : }
2521 : 0 : int in_band = 1;
2522 [ # # ]: 0 : if (self->buffer_callback != NULL) {
2523 : 0 : PyObject *ret = PyObject_CallOneArg(self->buffer_callback, obj);
2524 [ # # ]: 0 : if (ret == NULL) {
2525 : 0 : return -1;
2526 : : }
2527 : 0 : in_band = PyObject_IsTrue(ret);
2528 : 0 : Py_DECREF(ret);
2529 [ # # ]: 0 : if (in_band == -1) {
2530 : 0 : return -1;
2531 : : }
2532 : : }
2533 [ # # ]: 0 : if (in_band) {
2534 : : /* Write data in-band */
2535 [ # # ]: 0 : if (view->readonly) {
2536 : 0 : return _save_bytes_data(self, obj, (const char*) view->buf,
2537 : : view->len);
2538 : : }
2539 : : else {
2540 : 0 : return _save_bytearray_data(self, obj, (const char*) view->buf,
2541 : : view->len);
2542 : : }
2543 : : }
2544 : : else {
2545 : : /* Write data out-of-band */
2546 : 0 : const char next_buffer_op = NEXT_BUFFER;
2547 [ # # ]: 0 : if (_Pickler_Write(self, &next_buffer_op, 1) < 0) {
2548 : 0 : return -1;
2549 : : }
2550 [ # # ]: 0 : if (view->readonly) {
2551 : 0 : const char readonly_buffer_op = READONLY_BUFFER;
2552 [ # # ]: 0 : if (_Pickler_Write(self, &readonly_buffer_op, 1) < 0) {
2553 : 0 : return -1;
2554 : : }
2555 : : }
2556 : : }
2557 : 0 : return 0;
2558 : : }
2559 : :
2560 : : /* A copy of PyUnicode_AsRawUnicodeEscapeString() that also translates
2561 : : backslash and newline characters to \uXXXX escapes. */
2562 : : static PyObject *
2563 : 0 : raw_unicode_escape(PyObject *obj)
2564 : : {
2565 : : char *p;
2566 : : Py_ssize_t i, size;
2567 : : const void *data;
2568 : : int kind;
2569 : : _PyBytesWriter writer;
2570 : :
2571 [ # # ]: 0 : if (PyUnicode_READY(obj))
2572 : 0 : return NULL;
2573 : :
2574 : 0 : _PyBytesWriter_Init(&writer);
2575 : :
2576 : 0 : size = PyUnicode_GET_LENGTH(obj);
2577 : 0 : data = PyUnicode_DATA(obj);
2578 : 0 : kind = PyUnicode_KIND(obj);
2579 : :
2580 : 0 : p = _PyBytesWriter_Alloc(&writer, size);
2581 [ # # ]: 0 : if (p == NULL)
2582 : 0 : goto error;
2583 : 0 : writer.overallocate = 1;
2584 : :
2585 [ # # ]: 0 : for (i=0; i < size; i++) {
2586 : 0 : Py_UCS4 ch = PyUnicode_READ(kind, data, i);
2587 : : /* Map 32-bit characters to '\Uxxxxxxxx' */
2588 [ # # ]: 0 : if (ch >= 0x10000) {
2589 : : /* -1: subtract 1 preallocated byte */
2590 : 0 : p = _PyBytesWriter_Prepare(&writer, p, 10-1);
2591 [ # # ]: 0 : if (p == NULL)
2592 : 0 : goto error;
2593 : :
2594 : 0 : *p++ = '\\';
2595 : 0 : *p++ = 'U';
2596 : 0 : *p++ = Py_hexdigits[(ch >> 28) & 0xf];
2597 : 0 : *p++ = Py_hexdigits[(ch >> 24) & 0xf];
2598 : 0 : *p++ = Py_hexdigits[(ch >> 20) & 0xf];
2599 : 0 : *p++ = Py_hexdigits[(ch >> 16) & 0xf];
2600 : 0 : *p++ = Py_hexdigits[(ch >> 12) & 0xf];
2601 : 0 : *p++ = Py_hexdigits[(ch >> 8) & 0xf];
2602 : 0 : *p++ = Py_hexdigits[(ch >> 4) & 0xf];
2603 : 0 : *p++ = Py_hexdigits[ch & 15];
2604 : : }
2605 : : /* Map 16-bit characters, '\\' and '\n' to '\uxxxx' */
2606 [ # # # # ]: 0 : else if (ch >= 256 ||
2607 [ # # # # : 0 : ch == '\\' || ch == 0 || ch == '\n' || ch == '\r' ||
# # # # ]
2608 : : ch == 0x1a)
2609 : : {
2610 : : /* -1: subtract 1 preallocated byte */
2611 : 0 : p = _PyBytesWriter_Prepare(&writer, p, 6-1);
2612 [ # # ]: 0 : if (p == NULL)
2613 : 0 : goto error;
2614 : :
2615 : 0 : *p++ = '\\';
2616 : 0 : *p++ = 'u';
2617 : 0 : *p++ = Py_hexdigits[(ch >> 12) & 0xf];
2618 : 0 : *p++ = Py_hexdigits[(ch >> 8) & 0xf];
2619 : 0 : *p++ = Py_hexdigits[(ch >> 4) & 0xf];
2620 : 0 : *p++ = Py_hexdigits[ch & 15];
2621 : : }
2622 : : /* Copy everything else as-is */
2623 : : else
2624 : 0 : *p++ = (char) ch;
2625 : : }
2626 : :
2627 : 0 : return _PyBytesWriter_Finish(&writer, p);
2628 : :
2629 : 0 : error:
2630 : 0 : _PyBytesWriter_Dealloc(&writer);
2631 : 0 : return NULL;
2632 : : }
2633 : :
2634 : : static int
2635 : 0 : write_unicode_binary(PicklerObject *self, PyObject *obj)
2636 : : {
2637 : : char header[9];
2638 : : Py_ssize_t len;
2639 : 0 : PyObject *encoded = NULL;
2640 : : Py_ssize_t size;
2641 : : const char *data;
2642 : :
2643 [ # # ]: 0 : if (PyUnicode_READY(obj))
2644 : 0 : return -1;
2645 : :
2646 : 0 : data = PyUnicode_AsUTF8AndSize(obj, &size);
2647 [ # # ]: 0 : if (data == NULL) {
2648 : : /* Issue #8383: for strings with lone surrogates, fallback on the
2649 : : "surrogatepass" error handler. */
2650 : 0 : PyErr_Clear();
2651 : 0 : encoded = PyUnicode_AsEncodedString(obj, "utf-8", "surrogatepass");
2652 [ # # ]: 0 : if (encoded == NULL)
2653 : 0 : return -1;
2654 : :
2655 : 0 : data = PyBytes_AS_STRING(encoded);
2656 : 0 : size = PyBytes_GET_SIZE(encoded);
2657 : : }
2658 : :
2659 : : assert(size >= 0);
2660 [ # # # # ]: 0 : if (size <= 0xff && self->proto >= 4) {
2661 : 0 : header[0] = SHORT_BINUNICODE;
2662 : 0 : header[1] = (unsigned char)(size & 0xff);
2663 : 0 : len = 2;
2664 : : }
2665 [ # # ]: 0 : else if ((size_t)size <= 0xffffffffUL) {
2666 : 0 : header[0] = BINUNICODE;
2667 : 0 : header[1] = (unsigned char)(size & 0xff);
2668 : 0 : header[2] = (unsigned char)((size >> 8) & 0xff);
2669 : 0 : header[3] = (unsigned char)((size >> 16) & 0xff);
2670 : 0 : header[4] = (unsigned char)((size >> 24) & 0xff);
2671 : 0 : len = 5;
2672 : : }
2673 [ # # ]: 0 : else if (self->proto >= 4) {
2674 : 0 : header[0] = BINUNICODE8;
2675 : 0 : _write_size64(header + 1, size);
2676 : 0 : len = 9;
2677 : : }
2678 : : else {
2679 : 0 : PyErr_SetString(PyExc_OverflowError,
2680 : : "serializing a string larger than 4 GiB "
2681 : : "requires pickle protocol 4 or higher");
2682 : 0 : Py_XDECREF(encoded);
2683 : 0 : return -1;
2684 : : }
2685 : :
2686 [ # # ]: 0 : if (_Pickler_write_bytes(self, header, len, data, size, encoded) < 0) {
2687 : 0 : Py_XDECREF(encoded);
2688 : 0 : return -1;
2689 : : }
2690 : 0 : Py_XDECREF(encoded);
2691 : 0 : return 0;
2692 : : }
2693 : :
2694 : : static int
2695 : 0 : save_unicode(PicklerObject *self, PyObject *obj)
2696 : : {
2697 [ # # ]: 0 : if (self->bin) {
2698 [ # # ]: 0 : if (write_unicode_binary(self, obj) < 0)
2699 : 0 : return -1;
2700 : : }
2701 : : else {
2702 : : PyObject *encoded;
2703 : : Py_ssize_t size;
2704 : 0 : const char unicode_op = UNICODE;
2705 : :
2706 : 0 : encoded = raw_unicode_escape(obj);
2707 [ # # ]: 0 : if (encoded == NULL)
2708 : 0 : return -1;
2709 : :
2710 [ # # ]: 0 : if (_Pickler_Write(self, &unicode_op, 1) < 0) {
2711 : 0 : Py_DECREF(encoded);
2712 : 0 : return -1;
2713 : : }
2714 : :
2715 : 0 : size = PyBytes_GET_SIZE(encoded);
2716 [ # # ]: 0 : if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0) {
2717 : 0 : Py_DECREF(encoded);
2718 : 0 : return -1;
2719 : : }
2720 : 0 : Py_DECREF(encoded);
2721 : :
2722 [ # # ]: 0 : if (_Pickler_Write(self, "\n", 1) < 0)
2723 : 0 : return -1;
2724 : : }
2725 [ # # ]: 0 : if (memo_put(self, obj) < 0)
2726 : 0 : return -1;
2727 : :
2728 : 0 : return 0;
2729 : : }
2730 : :
2731 : : /* A helper for save_tuple. Push the len elements in tuple t on the stack. */
2732 : : static int
2733 : 0 : store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len)
2734 : : {
2735 : : Py_ssize_t i;
2736 : :
2737 : : assert(PyTuple_Size(t) == len);
2738 : :
2739 [ # # ]: 0 : for (i = 0; i < len; i++) {
2740 : 0 : PyObject *element = PyTuple_GET_ITEM(t, i);
2741 : :
2742 [ # # ]: 0 : if (element == NULL)
2743 : 0 : return -1;
2744 [ # # ]: 0 : if (save(self, element, 0) < 0)
2745 : 0 : return -1;
2746 : : }
2747 : :
2748 : 0 : return 0;
2749 : : }
2750 : :
2751 : : /* Tuples are ubiquitous in the pickle protocols, so many techniques are
2752 : : * used across protocols to minimize the space needed to pickle them.
2753 : : * Tuples are also the only builtin immutable type that can be recursive
2754 : : * (a tuple can be reached from itself), and that requires some subtle
2755 : : * magic so that it works in all cases. IOW, this is a long routine.
2756 : : */
2757 : : static int
2758 : 0 : save_tuple(PicklerObject *self, PyObject *obj)
2759 : : {
2760 : : Py_ssize_t len, i;
2761 : :
2762 : 0 : const char mark_op = MARK;
2763 : 0 : const char tuple_op = TUPLE;
2764 : 0 : const char pop_op = POP;
2765 : 0 : const char pop_mark_op = POP_MARK;
2766 : 0 : const char len2opcode[] = {EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3};
2767 : :
2768 [ # # ]: 0 : if ((len = PyTuple_Size(obj)) < 0)
2769 : 0 : return -1;
2770 : :
2771 [ # # ]: 0 : if (len == 0) {
2772 : : char pdata[2];
2773 : :
2774 [ # # ]: 0 : if (self->proto) {
2775 : 0 : pdata[0] = EMPTY_TUPLE;
2776 : 0 : len = 1;
2777 : : }
2778 : : else {
2779 : 0 : pdata[0] = MARK;
2780 : 0 : pdata[1] = TUPLE;
2781 : 0 : len = 2;
2782 : : }
2783 [ # # ]: 0 : if (_Pickler_Write(self, pdata, len) < 0)
2784 : 0 : return -1;
2785 : 0 : return 0;
2786 : : }
2787 : :
2788 : : /* The tuple isn't in the memo now. If it shows up there after
2789 : : * saving the tuple elements, the tuple must be recursive, in
2790 : : * which case we'll pop everything we put on the stack, and fetch
2791 : : * its value from the memo.
2792 : : */
2793 [ # # # # ]: 0 : if (len <= 3 && self->proto >= 2) {
2794 : : /* Use TUPLE{1,2,3} opcodes. */
2795 [ # # ]: 0 : if (store_tuple_elements(self, obj, len) < 0)
2796 : 0 : return -1;
2797 : :
2798 [ # # ]: 0 : if (PyMemoTable_Get(self->memo, obj)) {
2799 : : /* pop the len elements */
2800 [ # # ]: 0 : for (i = 0; i < len; i++)
2801 [ # # ]: 0 : if (_Pickler_Write(self, &pop_op, 1) < 0)
2802 : 0 : return -1;
2803 : : /* fetch from memo */
2804 [ # # ]: 0 : if (memo_get(self, obj) < 0)
2805 : 0 : return -1;
2806 : :
2807 : 0 : return 0;
2808 : : }
2809 : : else { /* Not recursive. */
2810 [ # # ]: 0 : if (_Pickler_Write(self, len2opcode + len, 1) < 0)
2811 : 0 : return -1;
2812 : : }
2813 : 0 : goto memoize;
2814 : : }
2815 : :
2816 : : /* proto < 2 and len > 0, or proto >= 2 and len > 3.
2817 : : * Generate MARK e1 e2 ... TUPLE
2818 : : */
2819 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
2820 : 0 : return -1;
2821 : :
2822 [ # # ]: 0 : if (store_tuple_elements(self, obj, len) < 0)
2823 : 0 : return -1;
2824 : :
2825 [ # # ]: 0 : if (PyMemoTable_Get(self->memo, obj)) {
2826 : : /* pop the stack stuff we pushed */
2827 [ # # ]: 0 : if (self->bin) {
2828 [ # # ]: 0 : if (_Pickler_Write(self, &pop_mark_op, 1) < 0)
2829 : 0 : return -1;
2830 : : }
2831 : : else {
2832 : : /* Note that we pop one more than len, to remove
2833 : : * the MARK too.
2834 : : */
2835 [ # # ]: 0 : for (i = 0; i <= len; i++)
2836 [ # # ]: 0 : if (_Pickler_Write(self, &pop_op, 1) < 0)
2837 : 0 : return -1;
2838 : : }
2839 : : /* fetch from memo */
2840 [ # # ]: 0 : if (memo_get(self, obj) < 0)
2841 : 0 : return -1;
2842 : :
2843 : 0 : return 0;
2844 : : }
2845 : : else { /* Not recursive. */
2846 [ # # ]: 0 : if (_Pickler_Write(self, &tuple_op, 1) < 0)
2847 : 0 : return -1;
2848 : : }
2849 : :
2850 : 0 : memoize:
2851 [ # # ]: 0 : if (memo_put(self, obj) < 0)
2852 : 0 : return -1;
2853 : :
2854 : 0 : return 0;
2855 : : }
2856 : :
2857 : : /* iter is an iterator giving items, and we batch up chunks of
2858 : : * MARK item item ... item APPENDS
2859 : : * opcode sequences. Calling code should have arranged to first create an
2860 : : * empty list, or list-like object, for the APPENDS to operate on.
2861 : : * Returns 0 on success, <0 on error.
2862 : : */
2863 : : static int
2864 : 0 : batch_list(PicklerObject *self, PyObject *iter)
2865 : : {
2866 : 0 : PyObject *obj = NULL;
2867 : 0 : PyObject *firstitem = NULL;
2868 : : int i, n;
2869 : :
2870 : 0 : const char mark_op = MARK;
2871 : 0 : const char append_op = APPEND;
2872 : 0 : const char appends_op = APPENDS;
2873 : :
2874 : : assert(iter != NULL);
2875 : :
2876 : : /* XXX: I think this function could be made faster by avoiding the
2877 : : iterator interface and fetching objects directly from list using
2878 : : PyList_GET_ITEM.
2879 : : */
2880 : :
2881 [ # # ]: 0 : if (self->proto == 0) {
2882 : : /* APPENDS isn't available; do one at a time. */
2883 : : for (;;) {
2884 : 0 : obj = PyIter_Next(iter);
2885 [ # # ]: 0 : if (obj == NULL) {
2886 [ # # ]: 0 : if (PyErr_Occurred())
2887 : 0 : return -1;
2888 : 0 : break;
2889 : : }
2890 : 0 : i = save(self, obj, 0);
2891 : 0 : Py_DECREF(obj);
2892 [ # # ]: 0 : if (i < 0)
2893 : 0 : return -1;
2894 [ # # ]: 0 : if (_Pickler_Write(self, &append_op, 1) < 0)
2895 : 0 : return -1;
2896 : : }
2897 : 0 : return 0;
2898 : : }
2899 : :
2900 : : /* proto > 0: write in batches of BATCHSIZE. */
2901 : : do {
2902 : : /* Get first item */
2903 : 0 : firstitem = PyIter_Next(iter);
2904 [ # # ]: 0 : if (firstitem == NULL) {
2905 [ # # ]: 0 : if (PyErr_Occurred())
2906 : 0 : goto error;
2907 : :
2908 : : /* nothing more to add */
2909 : 0 : break;
2910 : : }
2911 : :
2912 : : /* Try to get a second item */
2913 : 0 : obj = PyIter_Next(iter);
2914 [ # # ]: 0 : if (obj == NULL) {
2915 [ # # ]: 0 : if (PyErr_Occurred())
2916 : 0 : goto error;
2917 : :
2918 : : /* Only one item to write */
2919 [ # # ]: 0 : if (save(self, firstitem, 0) < 0)
2920 : 0 : goto error;
2921 [ # # ]: 0 : if (_Pickler_Write(self, &append_op, 1) < 0)
2922 : 0 : goto error;
2923 [ # # ]: 0 : Py_CLEAR(firstitem);
2924 : 0 : break;
2925 : : }
2926 : :
2927 : : /* More than one item to write */
2928 : :
2929 : : /* Pump out MARK, items, APPENDS. */
2930 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
2931 : 0 : goto error;
2932 : :
2933 [ # # ]: 0 : if (save(self, firstitem, 0) < 0)
2934 : 0 : goto error;
2935 [ # # ]: 0 : Py_CLEAR(firstitem);
2936 : 0 : n = 1;
2937 : :
2938 : : /* Fetch and save up to BATCHSIZE items */
2939 [ # # ]: 0 : while (obj) {
2940 [ # # ]: 0 : if (save(self, obj, 0) < 0)
2941 : 0 : goto error;
2942 [ # # ]: 0 : Py_CLEAR(obj);
2943 : 0 : n += 1;
2944 : :
2945 [ # # ]: 0 : if (n == BATCHSIZE)
2946 : 0 : break;
2947 : :
2948 : 0 : obj = PyIter_Next(iter);
2949 [ # # ]: 0 : if (obj == NULL) {
2950 [ # # ]: 0 : if (PyErr_Occurred())
2951 : 0 : goto error;
2952 : 0 : break;
2953 : : }
2954 : : }
2955 : :
2956 [ # # ]: 0 : if (_Pickler_Write(self, &appends_op, 1) < 0)
2957 : 0 : goto error;
2958 : :
2959 [ # # ]: 0 : } while (n == BATCHSIZE);
2960 : 0 : return 0;
2961 : :
2962 : 0 : error:
2963 : 0 : Py_XDECREF(firstitem);
2964 : 0 : Py_XDECREF(obj);
2965 : 0 : return -1;
2966 : : }
2967 : :
2968 : : /* This is a variant of batch_list() above, specialized for lists (with no
2969 : : * support for list subclasses). Like batch_list(), we batch up chunks of
2970 : : * MARK item item ... item APPENDS
2971 : : * opcode sequences. Calling code should have arranged to first create an
2972 : : * empty list, or list-like object, for the APPENDS to operate on.
2973 : : * Returns 0 on success, -1 on error.
2974 : : *
2975 : : * This version is considerably faster than batch_list(), if less general.
2976 : : *
2977 : : * Note that this only works for protocols > 0.
2978 : : */
2979 : : static int
2980 : 0 : batch_list_exact(PicklerObject *self, PyObject *obj)
2981 : : {
2982 : 0 : PyObject *item = NULL;
2983 : : Py_ssize_t this_batch, total;
2984 : :
2985 : 0 : const char append_op = APPEND;
2986 : 0 : const char appends_op = APPENDS;
2987 : 0 : const char mark_op = MARK;
2988 : :
2989 : : assert(obj != NULL);
2990 : : assert(self->proto > 0);
2991 : : assert(PyList_CheckExact(obj));
2992 : :
2993 [ # # ]: 0 : if (PyList_GET_SIZE(obj) == 1) {
2994 : 0 : item = PyList_GET_ITEM(obj, 0);
2995 : 0 : Py_INCREF(item);
2996 : 0 : int err = save(self, item, 0);
2997 : 0 : Py_DECREF(item);
2998 [ # # ]: 0 : if (err < 0)
2999 : 0 : return -1;
3000 [ # # ]: 0 : if (_Pickler_Write(self, &append_op, 1) < 0)
3001 : 0 : return -1;
3002 : 0 : return 0;
3003 : : }
3004 : :
3005 : : /* Write in batches of BATCHSIZE. */
3006 : 0 : total = 0;
3007 : : do {
3008 : 0 : this_batch = 0;
3009 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
3010 : 0 : return -1;
3011 [ # # ]: 0 : while (total < PyList_GET_SIZE(obj)) {
3012 : 0 : item = PyList_GET_ITEM(obj, total);
3013 : 0 : Py_INCREF(item);
3014 : 0 : int err = save(self, item, 0);
3015 : 0 : Py_DECREF(item);
3016 [ # # ]: 0 : if (err < 0)
3017 : 0 : return -1;
3018 : 0 : total++;
3019 [ # # ]: 0 : if (++this_batch == BATCHSIZE)
3020 : 0 : break;
3021 : : }
3022 [ # # ]: 0 : if (_Pickler_Write(self, &appends_op, 1) < 0)
3023 : 0 : return -1;
3024 : :
3025 [ # # ]: 0 : } while (total < PyList_GET_SIZE(obj));
3026 : :
3027 : 0 : return 0;
3028 : : }
3029 : :
3030 : : static int
3031 : 0 : save_list(PicklerObject *self, PyObject *obj)
3032 : : {
3033 : : char header[3];
3034 : : Py_ssize_t len;
3035 : 0 : int status = 0;
3036 : :
3037 [ # # # # ]: 0 : if (self->fast && !fast_save_enter(self, obj))
3038 : 0 : goto error;
3039 : :
3040 : : /* Create an empty list. */
3041 [ # # ]: 0 : if (self->bin) {
3042 : 0 : header[0] = EMPTY_LIST;
3043 : 0 : len = 1;
3044 : : }
3045 : : else {
3046 : 0 : header[0] = MARK;
3047 : 0 : header[1] = LIST;
3048 : 0 : len = 2;
3049 : : }
3050 : :
3051 [ # # ]: 0 : if (_Pickler_Write(self, header, len) < 0)
3052 : 0 : goto error;
3053 : :
3054 : : /* Get list length, and bow out early if empty. */
3055 [ # # ]: 0 : if ((len = PyList_Size(obj)) < 0)
3056 : 0 : goto error;
3057 : :
3058 [ # # ]: 0 : if (memo_put(self, obj) < 0)
3059 : 0 : goto error;
3060 : :
3061 [ # # ]: 0 : if (len != 0) {
3062 : : /* Materialize the list elements. */
3063 [ # # # # ]: 0 : if (PyList_CheckExact(obj) && self->proto > 0) {
3064 [ # # ]: 0 : if (_Py_EnterRecursiveCall(" while pickling an object"))
3065 : 0 : goto error;
3066 : 0 : status = batch_list_exact(self, obj);
3067 : 0 : _Py_LeaveRecursiveCall();
3068 : : } else {
3069 : 0 : PyObject *iter = PyObject_GetIter(obj);
3070 [ # # ]: 0 : if (iter == NULL)
3071 : 0 : goto error;
3072 : :
3073 [ # # ]: 0 : if (_Py_EnterRecursiveCall(" while pickling an object")) {
3074 : 0 : Py_DECREF(iter);
3075 : 0 : goto error;
3076 : : }
3077 : 0 : status = batch_list(self, iter);
3078 : 0 : _Py_LeaveRecursiveCall();
3079 : 0 : Py_DECREF(iter);
3080 : : }
3081 : : }
3082 : : if (0) {
3083 : 0 : error:
3084 : 0 : status = -1;
3085 : : }
3086 : :
3087 [ # # # # ]: 0 : if (self->fast && !fast_save_leave(self, obj))
3088 : 0 : status = -1;
3089 : :
3090 : 0 : return status;
3091 : : }
3092 : :
3093 : : /* iter is an iterator giving (key, value) pairs, and we batch up chunks of
3094 : : * MARK key value ... key value SETITEMS
3095 : : * opcode sequences. Calling code should have arranged to first create an
3096 : : * empty dict, or dict-like object, for the SETITEMS to operate on.
3097 : : * Returns 0 on success, <0 on error.
3098 : : *
3099 : : * This is very much like batch_list(). The difference between saving
3100 : : * elements directly, and picking apart two-tuples, is so long-winded at
3101 : : * the C level, though, that attempts to combine these routines were too
3102 : : * ugly to bear.
3103 : : */
3104 : : static int
3105 : 0 : batch_dict(PicklerObject *self, PyObject *iter)
3106 : : {
3107 : 0 : PyObject *obj = NULL;
3108 : 0 : PyObject *firstitem = NULL;
3109 : : int i, n;
3110 : :
3111 : 0 : const char mark_op = MARK;
3112 : 0 : const char setitem_op = SETITEM;
3113 : 0 : const char setitems_op = SETITEMS;
3114 : :
3115 : : assert(iter != NULL);
3116 : :
3117 [ # # ]: 0 : if (self->proto == 0) {
3118 : : /* SETITEMS isn't available; do one at a time. */
3119 : : for (;;) {
3120 : 0 : obj = PyIter_Next(iter);
3121 [ # # ]: 0 : if (obj == NULL) {
3122 [ # # ]: 0 : if (PyErr_Occurred())
3123 : 0 : return -1;
3124 : 0 : break;
3125 : : }
3126 [ # # # # ]: 0 : if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
3127 : 0 : PyErr_SetString(PyExc_TypeError, "dict items "
3128 : : "iterator must return 2-tuples");
3129 : 0 : return -1;
3130 : : }
3131 : 0 : i = save(self, PyTuple_GET_ITEM(obj, 0), 0);
3132 [ # # ]: 0 : if (i >= 0)
3133 : 0 : i = save(self, PyTuple_GET_ITEM(obj, 1), 0);
3134 : 0 : Py_DECREF(obj);
3135 [ # # ]: 0 : if (i < 0)
3136 : 0 : return -1;
3137 [ # # ]: 0 : if (_Pickler_Write(self, &setitem_op, 1) < 0)
3138 : 0 : return -1;
3139 : : }
3140 : 0 : return 0;
3141 : : }
3142 : :
3143 : : /* proto > 0: write in batches of BATCHSIZE. */
3144 : : do {
3145 : : /* Get first item */
3146 : 0 : firstitem = PyIter_Next(iter);
3147 [ # # ]: 0 : if (firstitem == NULL) {
3148 [ # # ]: 0 : if (PyErr_Occurred())
3149 : 0 : goto error;
3150 : :
3151 : : /* nothing more to add */
3152 : 0 : break;
3153 : : }
3154 [ # # # # ]: 0 : if (!PyTuple_Check(firstitem) || PyTuple_Size(firstitem) != 2) {
3155 : 0 : PyErr_SetString(PyExc_TypeError, "dict items "
3156 : : "iterator must return 2-tuples");
3157 : 0 : goto error;
3158 : : }
3159 : :
3160 : : /* Try to get a second item */
3161 : 0 : obj = PyIter_Next(iter);
3162 [ # # ]: 0 : if (obj == NULL) {
3163 [ # # ]: 0 : if (PyErr_Occurred())
3164 : 0 : goto error;
3165 : :
3166 : : /* Only one item to write */
3167 [ # # ]: 0 : if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
3168 : 0 : goto error;
3169 [ # # ]: 0 : if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
3170 : 0 : goto error;
3171 [ # # ]: 0 : if (_Pickler_Write(self, &setitem_op, 1) < 0)
3172 : 0 : goto error;
3173 [ # # ]: 0 : Py_CLEAR(firstitem);
3174 : 0 : break;
3175 : : }
3176 : :
3177 : : /* More than one item to write */
3178 : :
3179 : : /* Pump out MARK, items, SETITEMS. */
3180 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
3181 : 0 : goto error;
3182 : :
3183 [ # # ]: 0 : if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
3184 : 0 : goto error;
3185 [ # # ]: 0 : if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
3186 : 0 : goto error;
3187 [ # # ]: 0 : Py_CLEAR(firstitem);
3188 : 0 : n = 1;
3189 : :
3190 : : /* Fetch and save up to BATCHSIZE items */
3191 [ # # ]: 0 : while (obj) {
3192 [ # # # # ]: 0 : if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 2) {
3193 : 0 : PyErr_SetString(PyExc_TypeError, "dict items "
3194 : : "iterator must return 2-tuples");
3195 : 0 : goto error;
3196 : : }
3197 [ # # # # ]: 0 : if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
3198 : 0 : save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
3199 : 0 : goto error;
3200 [ # # ]: 0 : Py_CLEAR(obj);
3201 : 0 : n += 1;
3202 : :
3203 [ # # ]: 0 : if (n == BATCHSIZE)
3204 : 0 : break;
3205 : :
3206 : 0 : obj = PyIter_Next(iter);
3207 [ # # ]: 0 : if (obj == NULL) {
3208 [ # # ]: 0 : if (PyErr_Occurred())
3209 : 0 : goto error;
3210 : 0 : break;
3211 : : }
3212 : : }
3213 : :
3214 [ # # ]: 0 : if (_Pickler_Write(self, &setitems_op, 1) < 0)
3215 : 0 : goto error;
3216 : :
3217 [ # # ]: 0 : } while (n == BATCHSIZE);
3218 : 0 : return 0;
3219 : :
3220 : 0 : error:
3221 : 0 : Py_XDECREF(firstitem);
3222 : 0 : Py_XDECREF(obj);
3223 : 0 : return -1;
3224 : : }
3225 : :
3226 : : /* This is a variant of batch_dict() above that specializes for dicts, with no
3227 : : * support for dict subclasses. Like batch_dict(), we batch up chunks of
3228 : : * MARK key value ... key value SETITEMS
3229 : : * opcode sequences. Calling code should have arranged to first create an
3230 : : * empty dict, or dict-like object, for the SETITEMS to operate on.
3231 : : * Returns 0 on success, -1 on error.
3232 : : *
3233 : : * Note that this currently doesn't work for protocol 0.
3234 : : */
3235 : : static int
3236 : 0 : batch_dict_exact(PicklerObject *self, PyObject *obj)
3237 : : {
3238 : 0 : PyObject *key = NULL, *value = NULL;
3239 : : int i;
3240 : 0 : Py_ssize_t dict_size, ppos = 0;
3241 : :
3242 : 0 : const char mark_op = MARK;
3243 : 0 : const char setitem_op = SETITEM;
3244 : 0 : const char setitems_op = SETITEMS;
3245 : :
3246 : : assert(obj != NULL && PyDict_CheckExact(obj));
3247 : : assert(self->proto > 0);
3248 : :
3249 : 0 : dict_size = PyDict_GET_SIZE(obj);
3250 : :
3251 : : /* Special-case len(d) == 1 to save space. */
3252 [ # # ]: 0 : if (dict_size == 1) {
3253 : 0 : PyDict_Next(obj, &ppos, &key, &value);
3254 : 0 : Py_INCREF(key);
3255 : 0 : Py_INCREF(value);
3256 [ # # ]: 0 : if (save(self, key, 0) < 0) {
3257 : 0 : goto error;
3258 : : }
3259 [ # # ]: 0 : if (save(self, value, 0) < 0) {
3260 : 0 : goto error;
3261 : : }
3262 [ # # ]: 0 : Py_CLEAR(key);
3263 [ # # ]: 0 : Py_CLEAR(value);
3264 [ # # ]: 0 : if (_Pickler_Write(self, &setitem_op, 1) < 0)
3265 : 0 : return -1;
3266 : 0 : return 0;
3267 : : }
3268 : :
3269 : : /* Write in batches of BATCHSIZE. */
3270 : : do {
3271 : 0 : i = 0;
3272 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
3273 : 0 : return -1;
3274 [ # # ]: 0 : while (PyDict_Next(obj, &ppos, &key, &value)) {
3275 : 0 : Py_INCREF(key);
3276 : 0 : Py_INCREF(value);
3277 [ # # ]: 0 : if (save(self, key, 0) < 0) {
3278 : 0 : goto error;
3279 : : }
3280 [ # # ]: 0 : if (save(self, value, 0) < 0) {
3281 : 0 : goto error;
3282 : : }
3283 [ # # ]: 0 : Py_CLEAR(key);
3284 [ # # ]: 0 : Py_CLEAR(value);
3285 [ # # ]: 0 : if (++i == BATCHSIZE)
3286 : 0 : break;
3287 : : }
3288 [ # # ]: 0 : if (_Pickler_Write(self, &setitems_op, 1) < 0)
3289 : 0 : return -1;
3290 [ # # ]: 0 : if (PyDict_GET_SIZE(obj) != dict_size) {
3291 : 0 : PyErr_Format(
3292 : : PyExc_RuntimeError,
3293 : : "dictionary changed size during iteration");
3294 : 0 : return -1;
3295 : : }
3296 : :
3297 [ # # ]: 0 : } while (i == BATCHSIZE);
3298 : 0 : return 0;
3299 : 0 : error:
3300 : 0 : Py_XDECREF(key);
3301 : 0 : Py_XDECREF(value);
3302 : 0 : return -1;
3303 : : }
3304 : :
3305 : : static int
3306 : 0 : save_dict(PicklerObject *self, PyObject *obj)
3307 : : {
3308 : : PyObject *items, *iter;
3309 : : char header[3];
3310 : : Py_ssize_t len;
3311 : 0 : int status = 0;
3312 : : assert(PyDict_Check(obj));
3313 : :
3314 [ # # # # ]: 0 : if (self->fast && !fast_save_enter(self, obj))
3315 : 0 : goto error;
3316 : :
3317 : : /* Create an empty dict. */
3318 [ # # ]: 0 : if (self->bin) {
3319 : 0 : header[0] = EMPTY_DICT;
3320 : 0 : len = 1;
3321 : : }
3322 : : else {
3323 : 0 : header[0] = MARK;
3324 : 0 : header[1] = DICT;
3325 : 0 : len = 2;
3326 : : }
3327 : :
3328 [ # # ]: 0 : if (_Pickler_Write(self, header, len) < 0)
3329 : 0 : goto error;
3330 : :
3331 [ # # ]: 0 : if (memo_put(self, obj) < 0)
3332 : 0 : goto error;
3333 : :
3334 [ # # ]: 0 : if (PyDict_GET_SIZE(obj)) {
3335 : : /* Save the dict items. */
3336 [ # # # # ]: 0 : if (PyDict_CheckExact(obj) && self->proto > 0) {
3337 : : /* We can take certain shortcuts if we know this is a dict and
3338 : : not a dict subclass. */
3339 [ # # ]: 0 : if (_Py_EnterRecursiveCall(" while pickling an object"))
3340 : 0 : goto error;
3341 : 0 : status = batch_dict_exact(self, obj);
3342 : 0 : _Py_LeaveRecursiveCall();
3343 : : } else {
3344 : 0 : items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items));
3345 [ # # ]: 0 : if (items == NULL)
3346 : 0 : goto error;
3347 : 0 : iter = PyObject_GetIter(items);
3348 : 0 : Py_DECREF(items);
3349 [ # # ]: 0 : if (iter == NULL)
3350 : 0 : goto error;
3351 [ # # ]: 0 : if (_Py_EnterRecursiveCall(" while pickling an object")) {
3352 : 0 : Py_DECREF(iter);
3353 : 0 : goto error;
3354 : : }
3355 : 0 : status = batch_dict(self, iter);
3356 : 0 : _Py_LeaveRecursiveCall();
3357 : 0 : Py_DECREF(iter);
3358 : : }
3359 : : }
3360 : :
3361 : : if (0) {
3362 : 0 : error:
3363 : 0 : status = -1;
3364 : : }
3365 : :
3366 [ # # # # ]: 0 : if (self->fast && !fast_save_leave(self, obj))
3367 : 0 : status = -1;
3368 : :
3369 : 0 : return status;
3370 : : }
3371 : :
3372 : : static int
3373 : 0 : save_set(PicklerObject *self, PyObject *obj)
3374 : : {
3375 : : PyObject *item;
3376 : : int i;
3377 : 0 : Py_ssize_t set_size, ppos = 0;
3378 : : Py_hash_t hash;
3379 : :
3380 : 0 : const char empty_set_op = EMPTY_SET;
3381 : 0 : const char mark_op = MARK;
3382 : 0 : const char additems_op = ADDITEMS;
3383 : :
3384 [ # # ]: 0 : if (self->proto < 4) {
3385 : : PyObject *items;
3386 : : PyObject *reduce_value;
3387 : : int status;
3388 : :
3389 : 0 : items = PySequence_List(obj);
3390 [ # # ]: 0 : if (items == NULL) {
3391 : 0 : return -1;
3392 : : }
3393 : 0 : reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PySet_Type, items);
3394 : 0 : Py_DECREF(items);
3395 [ # # ]: 0 : if (reduce_value == NULL) {
3396 : 0 : return -1;
3397 : : }
3398 : : /* save_reduce() will memoize the object automatically. */
3399 : 0 : status = save_reduce(self, reduce_value, obj);
3400 : 0 : Py_DECREF(reduce_value);
3401 : 0 : return status;
3402 : : }
3403 : :
3404 [ # # ]: 0 : if (_Pickler_Write(self, &empty_set_op, 1) < 0)
3405 : 0 : return -1;
3406 : :
3407 [ # # ]: 0 : if (memo_put(self, obj) < 0)
3408 : 0 : return -1;
3409 : :
3410 : 0 : set_size = PySet_GET_SIZE(obj);
3411 [ # # ]: 0 : if (set_size == 0)
3412 : 0 : return 0; /* nothing to do */
3413 : :
3414 : : /* Write in batches of BATCHSIZE. */
3415 : : do {
3416 : 0 : i = 0;
3417 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
3418 : 0 : return -1;
3419 [ # # ]: 0 : while (_PySet_NextEntry(obj, &ppos, &item, &hash)) {
3420 : 0 : Py_INCREF(item);
3421 : 0 : int err = save(self, item, 0);
3422 [ # # ]: 0 : Py_CLEAR(item);
3423 [ # # ]: 0 : if (err < 0)
3424 : 0 : return -1;
3425 [ # # ]: 0 : if (++i == BATCHSIZE)
3426 : 0 : break;
3427 : : }
3428 [ # # ]: 0 : if (_Pickler_Write(self, &additems_op, 1) < 0)
3429 : 0 : return -1;
3430 [ # # ]: 0 : if (PySet_GET_SIZE(obj) != set_size) {
3431 : 0 : PyErr_Format(
3432 : : PyExc_RuntimeError,
3433 : : "set changed size during iteration");
3434 : 0 : return -1;
3435 : : }
3436 [ # # ]: 0 : } while (i == BATCHSIZE);
3437 : :
3438 : 0 : return 0;
3439 : : }
3440 : :
3441 : : static int
3442 : 0 : save_frozenset(PicklerObject *self, PyObject *obj)
3443 : : {
3444 : : PyObject *iter;
3445 : :
3446 : 0 : const char mark_op = MARK;
3447 : 0 : const char frozenset_op = FROZENSET;
3448 : :
3449 [ # # # # ]: 0 : if (self->fast && !fast_save_enter(self, obj))
3450 : 0 : return -1;
3451 : :
3452 [ # # ]: 0 : if (self->proto < 4) {
3453 : : PyObject *items;
3454 : : PyObject *reduce_value;
3455 : : int status;
3456 : :
3457 : 0 : items = PySequence_List(obj);
3458 [ # # ]: 0 : if (items == NULL) {
3459 : 0 : return -1;
3460 : : }
3461 : 0 : reduce_value = Py_BuildValue("(O(O))", (PyObject*)&PyFrozenSet_Type,
3462 : : items);
3463 : 0 : Py_DECREF(items);
3464 [ # # ]: 0 : if (reduce_value == NULL) {
3465 : 0 : return -1;
3466 : : }
3467 : : /* save_reduce() will memoize the object automatically. */
3468 : 0 : status = save_reduce(self, reduce_value, obj);
3469 : 0 : Py_DECREF(reduce_value);
3470 : 0 : return status;
3471 : : }
3472 : :
3473 [ # # ]: 0 : if (_Pickler_Write(self, &mark_op, 1) < 0)
3474 : 0 : return -1;
3475 : :
3476 : 0 : iter = PyObject_GetIter(obj);
3477 [ # # ]: 0 : if (iter == NULL) {
3478 : 0 : return -1;
3479 : : }
3480 : 0 : for (;;) {
3481 : : PyObject *item;
3482 : :
3483 : 0 : item = PyIter_Next(iter);
3484 [ # # ]: 0 : if (item == NULL) {
3485 [ # # ]: 0 : if (PyErr_Occurred()) {
3486 : 0 : Py_DECREF(iter);
3487 : 0 : return -1;
3488 : : }
3489 : 0 : break;
3490 : : }
3491 [ # # ]: 0 : if (save(self, item, 0) < 0) {
3492 : 0 : Py_DECREF(item);
3493 : 0 : Py_DECREF(iter);
3494 : 0 : return -1;
3495 : : }
3496 : 0 : Py_DECREF(item);
3497 : : }
3498 : 0 : Py_DECREF(iter);
3499 : :
3500 : : /* If the object is already in the memo, this means it is
3501 : : recursive. In this case, throw away everything we put on the
3502 : : stack, and fetch the object back from the memo. */
3503 [ # # ]: 0 : if (PyMemoTable_Get(self->memo, obj)) {
3504 : 0 : const char pop_mark_op = POP_MARK;
3505 : :
3506 [ # # ]: 0 : if (_Pickler_Write(self, &pop_mark_op, 1) < 0)
3507 : 0 : return -1;
3508 [ # # ]: 0 : if (memo_get(self, obj) < 0)
3509 : 0 : return -1;
3510 : 0 : return 0;
3511 : : }
3512 : :
3513 [ # # ]: 0 : if (_Pickler_Write(self, &frozenset_op, 1) < 0)
3514 : 0 : return -1;
3515 [ # # ]: 0 : if (memo_put(self, obj) < 0)
3516 : 0 : return -1;
3517 : :
3518 : 0 : return 0;
3519 : : }
3520 : :
3521 : : static int
3522 : 0 : fix_imports(PyObject **module_name, PyObject **global_name)
3523 : : {
3524 : : PyObject *key;
3525 : : PyObject *item;
3526 : 0 : PickleState *st = _Pickle_GetGlobalState();
3527 : :
3528 : 0 : key = PyTuple_Pack(2, *module_name, *global_name);
3529 [ # # ]: 0 : if (key == NULL)
3530 : 0 : return -1;
3531 : 0 : item = PyDict_GetItemWithError(st->name_mapping_3to2, key);
3532 : 0 : Py_DECREF(key);
3533 [ # # ]: 0 : if (item) {
3534 : : PyObject *fixed_module_name;
3535 : : PyObject *fixed_global_name;
3536 : :
3537 [ # # # # ]: 0 : if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
3538 : 0 : PyErr_Format(PyExc_RuntimeError,
3539 : : "_compat_pickle.REVERSE_NAME_MAPPING values "
3540 : : "should be 2-tuples, not %.200s",
3541 : 0 : Py_TYPE(item)->tp_name);
3542 : 0 : return -1;
3543 : : }
3544 : 0 : fixed_module_name = PyTuple_GET_ITEM(item, 0);
3545 : 0 : fixed_global_name = PyTuple_GET_ITEM(item, 1);
3546 [ # # # # ]: 0 : if (!PyUnicode_Check(fixed_module_name) ||
3547 : 0 : !PyUnicode_Check(fixed_global_name)) {
3548 : 0 : PyErr_Format(PyExc_RuntimeError,
3549 : : "_compat_pickle.REVERSE_NAME_MAPPING values "
3550 : : "should be pairs of str, not (%.200s, %.200s)",
3551 : 0 : Py_TYPE(fixed_module_name)->tp_name,
3552 : 0 : Py_TYPE(fixed_global_name)->tp_name);
3553 : 0 : return -1;
3554 : : }
3555 : :
3556 [ # # ]: 0 : Py_CLEAR(*module_name);
3557 [ # # ]: 0 : Py_CLEAR(*global_name);
3558 : 0 : *module_name = Py_NewRef(fixed_module_name);
3559 : 0 : *global_name = Py_NewRef(fixed_global_name);
3560 : 0 : return 0;
3561 : : }
3562 [ # # ]: 0 : else if (PyErr_Occurred()) {
3563 : 0 : return -1;
3564 : : }
3565 : :
3566 : 0 : item = PyDict_GetItemWithError(st->import_mapping_3to2, *module_name);
3567 [ # # ]: 0 : if (item) {
3568 [ # # ]: 0 : if (!PyUnicode_Check(item)) {
3569 : 0 : PyErr_Format(PyExc_RuntimeError,
3570 : : "_compat_pickle.REVERSE_IMPORT_MAPPING values "
3571 : : "should be strings, not %.200s",
3572 : 0 : Py_TYPE(item)->tp_name);
3573 : 0 : return -1;
3574 : : }
3575 : 0 : Py_XSETREF(*module_name, Py_NewRef(item));
3576 : : }
3577 [ # # ]: 0 : else if (PyErr_Occurred()) {
3578 : 0 : return -1;
3579 : : }
3580 : :
3581 : 0 : return 0;
3582 : : }
3583 : :
3584 : : static int
3585 : 0 : save_global(PicklerObject *self, PyObject *obj, PyObject *name)
3586 : : {
3587 : 0 : PyObject *global_name = NULL;
3588 : 0 : PyObject *module_name = NULL;
3589 : 0 : PyObject *module = NULL;
3590 : 0 : PyObject *parent = NULL;
3591 : 0 : PyObject *dotted_path = NULL;
3592 : 0 : PyObject *lastname = NULL;
3593 : : PyObject *cls;
3594 : 0 : PickleState *st = _Pickle_GetGlobalState();
3595 : 0 : int status = 0;
3596 : :
3597 : 0 : const char global_op = GLOBAL;
3598 : :
3599 [ # # ]: 0 : if (name) {
3600 : 0 : global_name = Py_NewRef(name);
3601 : : }
3602 : : else {
3603 [ # # ]: 0 : if (_PyObject_LookupAttr(obj, &_Py_ID(__qualname__), &global_name) < 0)
3604 : 0 : goto error;
3605 [ # # ]: 0 : if (global_name == NULL) {
3606 : 0 : global_name = PyObject_GetAttr(obj, &_Py_ID(__name__));
3607 [ # # ]: 0 : if (global_name == NULL)
3608 : 0 : goto error;
3609 : : }
3610 : : }
3611 : :
3612 : 0 : dotted_path = get_dotted_path(module, global_name);
3613 [ # # ]: 0 : if (dotted_path == NULL)
3614 : 0 : goto error;
3615 : 0 : module_name = whichmodule(obj, dotted_path);
3616 [ # # ]: 0 : if (module_name == NULL)
3617 : 0 : goto error;
3618 : :
3619 : : /* XXX: Change to use the import C API directly with level=0 to disallow
3620 : : relative imports.
3621 : :
3622 : : XXX: PyImport_ImportModuleLevel could be used. However, this bypasses
3623 : : builtins.__import__. Therefore, _pickle, unlike pickle.py, will ignore
3624 : : custom import functions (IMHO, this would be a nice security
3625 : : feature). The import C API would need to be extended to support the
3626 : : extra parameters of __import__ to fix that. */
3627 : 0 : module = PyImport_Import(module_name);
3628 [ # # ]: 0 : if (module == NULL) {
3629 : 0 : PyErr_Format(st->PicklingError,
3630 : : "Can't pickle %R: import of module %R failed",
3631 : : obj, module_name);
3632 : 0 : goto error;
3633 : : }
3634 : 0 : lastname = Py_NewRef(PyList_GET_ITEM(dotted_path,
3635 : : PyList_GET_SIZE(dotted_path) - 1));
3636 : 0 : cls = get_deep_attribute(module, dotted_path, &parent);
3637 [ # # ]: 0 : Py_CLEAR(dotted_path);
3638 [ # # ]: 0 : if (cls == NULL) {
3639 : 0 : PyErr_Format(st->PicklingError,
3640 : : "Can't pickle %R: attribute lookup %S on %S failed",
3641 : : obj, global_name, module_name);
3642 : 0 : goto error;
3643 : : }
3644 [ # # ]: 0 : if (cls != obj) {
3645 : 0 : Py_DECREF(cls);
3646 : 0 : PyErr_Format(st->PicklingError,
3647 : : "Can't pickle %R: it's not the same object as %S.%S",
3648 : : obj, module_name, global_name);
3649 : 0 : goto error;
3650 : : }
3651 : 0 : Py_DECREF(cls);
3652 : :
3653 [ # # ]: 0 : if (self->proto >= 2) {
3654 : : /* See whether this is in the extension registry, and if
3655 : : * so generate an EXT opcode.
3656 : : */
3657 : : PyObject *extension_key;
3658 : : PyObject *code_obj; /* extension code as Python object */
3659 : : long code; /* extension code as C value */
3660 : : char pdata[5];
3661 : : Py_ssize_t n;
3662 : :
3663 : 0 : extension_key = PyTuple_Pack(2, module_name, global_name);
3664 [ # # ]: 0 : if (extension_key == NULL) {
3665 : 0 : goto error;
3666 : : }
3667 : 0 : code_obj = PyDict_GetItemWithError(st->extension_registry,
3668 : : extension_key);
3669 : 0 : Py_DECREF(extension_key);
3670 : : /* The object is not registered in the extension registry.
3671 : : This is the most likely code path. */
3672 [ # # ]: 0 : if (code_obj == NULL) {
3673 [ # # ]: 0 : if (PyErr_Occurred()) {
3674 : 0 : goto error;
3675 : : }
3676 : 0 : goto gen_global;
3677 : : }
3678 : :
3679 : : /* XXX: pickle.py doesn't check neither the type, nor the range
3680 : : of the value returned by the extension_registry. It should for
3681 : : consistency. */
3682 : :
3683 : : /* Verify code_obj has the right type and value. */
3684 [ # # ]: 0 : if (!PyLong_Check(code_obj)) {
3685 : 0 : PyErr_Format(st->PicklingError,
3686 : : "Can't pickle %R: extension code %R isn't an integer",
3687 : : obj, code_obj);
3688 : 0 : goto error;
3689 : : }
3690 : 0 : code = PyLong_AS_LONG(code_obj);
3691 [ # # # # ]: 0 : if (code <= 0 || code > 0x7fffffffL) {
3692 [ # # ]: 0 : if (!PyErr_Occurred())
3693 : 0 : PyErr_Format(st->PicklingError, "Can't pickle %R: extension "
3694 : : "code %ld is out of range", obj, code);
3695 : 0 : goto error;
3696 : : }
3697 : :
3698 : : /* Generate an EXT opcode. */
3699 [ # # ]: 0 : if (code <= 0xff) {
3700 : 0 : pdata[0] = EXT1;
3701 : 0 : pdata[1] = (unsigned char)code;
3702 : 0 : n = 2;
3703 : : }
3704 [ # # ]: 0 : else if (code <= 0xffff) {
3705 : 0 : pdata[0] = EXT2;
3706 : 0 : pdata[1] = (unsigned char)(code & 0xff);
3707 : 0 : pdata[2] = (unsigned char)((code >> 8) & 0xff);
3708 : 0 : n = 3;
3709 : : }
3710 : : else {
3711 : 0 : pdata[0] = EXT4;
3712 : 0 : pdata[1] = (unsigned char)(code & 0xff);
3713 : 0 : pdata[2] = (unsigned char)((code >> 8) & 0xff);
3714 : 0 : pdata[3] = (unsigned char)((code >> 16) & 0xff);
3715 : 0 : pdata[4] = (unsigned char)((code >> 24) & 0xff);
3716 : 0 : n = 5;
3717 : : }
3718 : :
3719 [ # # ]: 0 : if (_Pickler_Write(self, pdata, n) < 0)
3720 : 0 : goto error;
3721 : : }
3722 : : else {
3723 : 0 : gen_global:
3724 [ # # ]: 0 : if (parent == module) {
3725 : 0 : Py_SETREF(global_name, Py_NewRef(lastname));
3726 : : }
3727 [ # # ]: 0 : if (self->proto >= 4) {
3728 : 0 : const char stack_global_op = STACK_GLOBAL;
3729 : :
3730 [ # # ]: 0 : if (save(self, module_name, 0) < 0)
3731 : 0 : goto error;
3732 [ # # ]: 0 : if (save(self, global_name, 0) < 0)
3733 : 0 : goto error;
3734 : :
3735 [ # # ]: 0 : if (_Pickler_Write(self, &stack_global_op, 1) < 0)
3736 : 0 : goto error;
3737 : : }
3738 [ # # ]: 0 : else if (parent != module) {
3739 : 0 : PickleState *st = _Pickle_GetGlobalState();
3740 : 0 : PyObject *reduce_value = Py_BuildValue("(O(OO))",
3741 : : st->getattr, parent, lastname);
3742 [ # # ]: 0 : if (reduce_value == NULL)
3743 : 0 : goto error;
3744 : 0 : status = save_reduce(self, reduce_value, NULL);
3745 : 0 : Py_DECREF(reduce_value);
3746 [ # # ]: 0 : if (status < 0)
3747 : 0 : goto error;
3748 : : }
3749 : : else {
3750 : : /* Generate a normal global opcode if we are using a pickle
3751 : : protocol < 4, or if the object is not registered in the
3752 : : extension registry. */
3753 : : PyObject *encoded;
3754 : : PyObject *(*unicode_encoder)(PyObject *);
3755 : :
3756 [ # # ]: 0 : if (_Pickler_Write(self, &global_op, 1) < 0)
3757 : 0 : goto error;
3758 : :
3759 : : /* For protocol < 3 and if the user didn't request against doing
3760 : : so, we convert module names to the old 2.x module names. */
3761 [ # # # # ]: 0 : if (self->proto < 3 && self->fix_imports) {
3762 [ # # ]: 0 : if (fix_imports(&module_name, &global_name) < 0) {
3763 : 0 : goto error;
3764 : : }
3765 : : }
3766 : :
3767 : : /* Since Python 3.0 now supports non-ASCII identifiers, we encode
3768 : : both the module name and the global name using UTF-8. We do so
3769 : : only when we are using the pickle protocol newer than version
3770 : : 3. This is to ensure compatibility with older Unpickler running
3771 : : on Python 2.x. */
3772 [ # # ]: 0 : if (self->proto == 3) {
3773 : 0 : unicode_encoder = PyUnicode_AsUTF8String;
3774 : : }
3775 : : else {
3776 : 0 : unicode_encoder = PyUnicode_AsASCIIString;
3777 : : }
3778 : 0 : encoded = unicode_encoder(module_name);
3779 [ # # ]: 0 : if (encoded == NULL) {
3780 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
3781 : 0 : PyErr_Format(st->PicklingError,
3782 : : "can't pickle module identifier '%S' using "
3783 : : "pickle protocol %i",
3784 : : module_name, self->proto);
3785 : 0 : goto error;
3786 : : }
3787 [ # # ]: 0 : if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
3788 : : PyBytes_GET_SIZE(encoded)) < 0) {
3789 : 0 : Py_DECREF(encoded);
3790 : 0 : goto error;
3791 : : }
3792 : 0 : Py_DECREF(encoded);
3793 [ # # ]: 0 : if(_Pickler_Write(self, "\n", 1) < 0)
3794 : 0 : goto error;
3795 : :
3796 : : /* Save the name of the module. */
3797 : 0 : encoded = unicode_encoder(global_name);
3798 [ # # ]: 0 : if (encoded == NULL) {
3799 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError))
3800 : 0 : PyErr_Format(st->PicklingError,
3801 : : "can't pickle global identifier '%S' using "
3802 : : "pickle protocol %i",
3803 : : global_name, self->proto);
3804 : 0 : goto error;
3805 : : }
3806 [ # # ]: 0 : if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
3807 : : PyBytes_GET_SIZE(encoded)) < 0) {
3808 : 0 : Py_DECREF(encoded);
3809 : 0 : goto error;
3810 : : }
3811 : 0 : Py_DECREF(encoded);
3812 [ # # ]: 0 : if (_Pickler_Write(self, "\n", 1) < 0)
3813 : 0 : goto error;
3814 : : }
3815 : : /* Memoize the object. */
3816 [ # # ]: 0 : if (memo_put(self, obj) < 0)
3817 : 0 : goto error;
3818 : : }
3819 : :
3820 : : if (0) {
3821 : 0 : error:
3822 : 0 : status = -1;
3823 : : }
3824 : 0 : Py_XDECREF(module_name);
3825 : 0 : Py_XDECREF(global_name);
3826 : 0 : Py_XDECREF(module);
3827 : 0 : Py_XDECREF(parent);
3828 : 0 : Py_XDECREF(dotted_path);
3829 : 0 : Py_XDECREF(lastname);
3830 : :
3831 : 0 : return status;
3832 : : }
3833 : :
3834 : : static int
3835 : 0 : save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton)
3836 : : {
3837 : : PyObject *reduce_value;
3838 : : int status;
3839 : :
3840 : 0 : reduce_value = Py_BuildValue("O(O)", &PyType_Type, singleton);
3841 [ # # ]: 0 : if (reduce_value == NULL) {
3842 : 0 : return -1;
3843 : : }
3844 : 0 : status = save_reduce(self, reduce_value, obj);
3845 : 0 : Py_DECREF(reduce_value);
3846 : 0 : return status;
3847 : : }
3848 : :
3849 : : static int
3850 : 0 : save_type(PicklerObject *self, PyObject *obj)
3851 : : {
3852 [ # # ]: 0 : if (obj == (PyObject *)&_PyNone_Type) {
3853 : 0 : return save_singleton_type(self, obj, Py_None);
3854 : : }
3855 [ # # ]: 0 : else if (obj == (PyObject *)&PyEllipsis_Type) {
3856 : 0 : return save_singleton_type(self, obj, Py_Ellipsis);
3857 : : }
3858 [ # # ]: 0 : else if (obj == (PyObject *)&_PyNotImplemented_Type) {
3859 : 0 : return save_singleton_type(self, obj, Py_NotImplemented);
3860 : : }
3861 : 0 : return save_global(self, obj, NULL);
3862 : : }
3863 : :
3864 : : static int
3865 : 0 : save_pers(PicklerObject *self, PyObject *obj)
3866 : : {
3867 : 0 : PyObject *pid = NULL;
3868 : 0 : int status = 0;
3869 : :
3870 : 0 : const char persid_op = PERSID;
3871 : 0 : const char binpersid_op = BINPERSID;
3872 : :
3873 : 0 : pid = call_method(self->pers_func, self->pers_func_self, obj);
3874 [ # # ]: 0 : if (pid == NULL)
3875 : 0 : return -1;
3876 : :
3877 [ # # ]: 0 : if (pid != Py_None) {
3878 [ # # ]: 0 : if (self->bin) {
3879 [ # # # # ]: 0 : if (save(self, pid, 1) < 0 ||
3880 : 0 : _Pickler_Write(self, &binpersid_op, 1) < 0)
3881 : 0 : goto error;
3882 : : }
3883 : : else {
3884 : : PyObject *pid_str;
3885 : :
3886 : 0 : pid_str = PyObject_Str(pid);
3887 [ # # ]: 0 : if (pid_str == NULL)
3888 : 0 : goto error;
3889 : :
3890 : : /* XXX: Should it check whether the pid contains embedded
3891 : : newlines? */
3892 [ # # ]: 0 : if (!PyUnicode_IS_ASCII(pid_str)) {
3893 : 0 : PyErr_SetString(_Pickle_GetGlobalState()->PicklingError,
3894 : : "persistent IDs in protocol 0 must be "
3895 : : "ASCII strings");
3896 : 0 : Py_DECREF(pid_str);
3897 : 0 : goto error;
3898 : : }
3899 : :
3900 [ # # # # ]: 0 : if (_Pickler_Write(self, &persid_op, 1) < 0 ||
3901 : 0 : _Pickler_Write(self, PyUnicode_DATA(pid_str),
3902 [ # # ]: 0 : PyUnicode_GET_LENGTH(pid_str)) < 0 ||
3903 : 0 : _Pickler_Write(self, "\n", 1) < 0) {
3904 : 0 : Py_DECREF(pid_str);
3905 : 0 : goto error;
3906 : : }
3907 : 0 : Py_DECREF(pid_str);
3908 : : }
3909 : 0 : status = 1;
3910 : : }
3911 : :
3912 : : if (0) {
3913 : 0 : error:
3914 : 0 : status = -1;
3915 : : }
3916 : 0 : Py_XDECREF(pid);
3917 : :
3918 : 0 : return status;
3919 : : }
3920 : :
3921 : : static PyObject *
3922 : 0 : get_class(PyObject *obj)
3923 : : {
3924 : : PyObject *cls;
3925 : :
3926 [ # # ]: 0 : if (_PyObject_LookupAttr(obj, &_Py_ID(__class__), &cls) == 0) {
3927 : 0 : cls = Py_NewRef(Py_TYPE(obj));
3928 : : }
3929 : 0 : return cls;
3930 : : }
3931 : :
3932 : : /* We're saving obj, and args is the 2-thru-5 tuple returned by the
3933 : : * appropriate __reduce__ method for obj.
3934 : : */
3935 : : static int
3936 : 0 : save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
3937 : : {
3938 : : PyObject *callable;
3939 : : PyObject *argtup;
3940 : 0 : PyObject *state = NULL;
3941 : 0 : PyObject *listitems = Py_None;
3942 : 0 : PyObject *dictitems = Py_None;
3943 : 0 : PyObject *state_setter = Py_None;
3944 : 0 : PickleState *st = _Pickle_GetGlobalState();
3945 : : Py_ssize_t size;
3946 : 0 : int use_newobj = 0, use_newobj_ex = 0;
3947 : :
3948 : 0 : const char reduce_op = REDUCE;
3949 : 0 : const char build_op = BUILD;
3950 : 0 : const char newobj_op = NEWOBJ;
3951 : 0 : const char newobj_ex_op = NEWOBJ_EX;
3952 : :
3953 : 0 : size = PyTuple_Size(args);
3954 [ # # # # ]: 0 : if (size < 2 || size > 6) {
3955 : 0 : PyErr_SetString(st->PicklingError, "tuple returned by "
3956 : : "__reduce__ must contain 2 through 6 elements");
3957 : 0 : return -1;
3958 : : }
3959 : :
3960 [ # # ]: 0 : if (!PyArg_UnpackTuple(args, "save_reduce", 2, 6,
3961 : : &callable, &argtup, &state, &listitems, &dictitems,
3962 : : &state_setter))
3963 : 0 : return -1;
3964 : :
3965 [ # # ]: 0 : if (!PyCallable_Check(callable)) {
3966 : 0 : PyErr_SetString(st->PicklingError, "first item of the tuple "
3967 : : "returned by __reduce__ must be callable");
3968 : 0 : return -1;
3969 : : }
3970 [ # # ]: 0 : if (!PyTuple_Check(argtup)) {
3971 : 0 : PyErr_SetString(st->PicklingError, "second item of the tuple "
3972 : : "returned by __reduce__ must be a tuple");
3973 : 0 : return -1;
3974 : : }
3975 : :
3976 [ # # ]: 0 : if (state == Py_None)
3977 : 0 : state = NULL;
3978 : :
3979 [ # # ]: 0 : if (listitems == Py_None)
3980 : 0 : listitems = NULL;
3981 [ # # ]: 0 : else if (!PyIter_Check(listitems)) {
3982 : 0 : PyErr_Format(st->PicklingError, "fourth element of the tuple "
3983 : : "returned by __reduce__ must be an iterator, not %s",
3984 : 0 : Py_TYPE(listitems)->tp_name);
3985 : 0 : return -1;
3986 : : }
3987 : :
3988 [ # # ]: 0 : if (dictitems == Py_None)
3989 : 0 : dictitems = NULL;
3990 [ # # ]: 0 : else if (!PyIter_Check(dictitems)) {
3991 : 0 : PyErr_Format(st->PicklingError, "fifth element of the tuple "
3992 : : "returned by __reduce__ must be an iterator, not %s",
3993 : 0 : Py_TYPE(dictitems)->tp_name);
3994 : 0 : return -1;
3995 : : }
3996 : :
3997 [ # # ]: 0 : if (state_setter == Py_None)
3998 : 0 : state_setter = NULL;
3999 [ # # ]: 0 : else if (!PyCallable_Check(state_setter)) {
4000 : 0 : PyErr_Format(st->PicklingError, "sixth element of the tuple "
4001 : : "returned by __reduce__ must be a function, not %s",
4002 : 0 : Py_TYPE(state_setter)->tp_name);
4003 : 0 : return -1;
4004 : : }
4005 : :
4006 [ # # ]: 0 : if (self->proto >= 2) {
4007 : : PyObject *name;
4008 : :
4009 [ # # ]: 0 : if (_PyObject_LookupAttr(callable, &_Py_ID(__name__), &name) < 0) {
4010 : 0 : return -1;
4011 : : }
4012 [ # # # # ]: 0 : if (name != NULL && PyUnicode_Check(name)) {
4013 : 0 : use_newobj_ex = _PyUnicode_Equal(name, &_Py_ID(__newobj_ex__));
4014 [ # # ]: 0 : if (!use_newobj_ex) {
4015 : 0 : use_newobj = _PyUnicode_Equal(name, &_Py_ID(__newobj__));
4016 : : }
4017 : : }
4018 : 0 : Py_XDECREF(name);
4019 : : }
4020 : :
4021 [ # # ]: 0 : if (use_newobj_ex) {
4022 : : PyObject *cls;
4023 : : PyObject *args;
4024 : : PyObject *kwargs;
4025 : :
4026 [ # # ]: 0 : if (PyTuple_GET_SIZE(argtup) != 3) {
4027 : 0 : PyErr_Format(st->PicklingError,
4028 : : "length of the NEWOBJ_EX argument tuple must be "
4029 : : "exactly 3, not %zd", PyTuple_GET_SIZE(argtup));
4030 : 0 : return -1;
4031 : : }
4032 : :
4033 : 0 : cls = PyTuple_GET_ITEM(argtup, 0);
4034 [ # # ]: 0 : if (!PyType_Check(cls)) {
4035 : 0 : PyErr_Format(st->PicklingError,
4036 : : "first item from NEWOBJ_EX argument tuple must "
4037 : 0 : "be a class, not %.200s", Py_TYPE(cls)->tp_name);
4038 : 0 : return -1;
4039 : : }
4040 : 0 : args = PyTuple_GET_ITEM(argtup, 1);
4041 [ # # ]: 0 : if (!PyTuple_Check(args)) {
4042 : 0 : PyErr_Format(st->PicklingError,
4043 : : "second item from NEWOBJ_EX argument tuple must "
4044 : 0 : "be a tuple, not %.200s", Py_TYPE(args)->tp_name);
4045 : 0 : return -1;
4046 : : }
4047 : 0 : kwargs = PyTuple_GET_ITEM(argtup, 2);
4048 [ # # ]: 0 : if (!PyDict_Check(kwargs)) {
4049 : 0 : PyErr_Format(st->PicklingError,
4050 : : "third item from NEWOBJ_EX argument tuple must "
4051 : 0 : "be a dict, not %.200s", Py_TYPE(kwargs)->tp_name);
4052 : 0 : return -1;
4053 : : }
4054 : :
4055 [ # # ]: 0 : if (self->proto >= 4) {
4056 [ # # # # ]: 0 : if (save(self, cls, 0) < 0 ||
4057 [ # # ]: 0 : save(self, args, 0) < 0 ||
4058 [ # # ]: 0 : save(self, kwargs, 0) < 0 ||
4059 : 0 : _Pickler_Write(self, &newobj_ex_op, 1) < 0) {
4060 : 0 : return -1;
4061 : : }
4062 : : }
4063 : : else {
4064 : : PyObject *newargs;
4065 : : PyObject *cls_new;
4066 : : Py_ssize_t i;
4067 : :
4068 : 0 : newargs = PyTuple_New(PyTuple_GET_SIZE(args) + 2);
4069 [ # # ]: 0 : if (newargs == NULL)
4070 : 0 : return -1;
4071 : :
4072 : 0 : cls_new = PyObject_GetAttr(cls, &_Py_ID(__new__));
4073 [ # # ]: 0 : if (cls_new == NULL) {
4074 : 0 : Py_DECREF(newargs);
4075 : 0 : return -1;
4076 : : }
4077 : 0 : PyTuple_SET_ITEM(newargs, 0, cls_new);
4078 : 0 : PyTuple_SET_ITEM(newargs, 1, Py_NewRef(cls));
4079 [ # # ]: 0 : for (i = 0; i < PyTuple_GET_SIZE(args); i++) {
4080 : 0 : PyObject *item = PyTuple_GET_ITEM(args, i);
4081 : 0 : PyTuple_SET_ITEM(newargs, i + 2, Py_NewRef(item));
4082 : : }
4083 : :
4084 : 0 : callable = PyObject_Call(st->partial, newargs, kwargs);
4085 : 0 : Py_DECREF(newargs);
4086 [ # # ]: 0 : if (callable == NULL)
4087 : 0 : return -1;
4088 : :
4089 : 0 : newargs = PyTuple_New(0);
4090 [ # # ]: 0 : if (newargs == NULL) {
4091 : 0 : Py_DECREF(callable);
4092 : 0 : return -1;
4093 : : }
4094 : :
4095 [ # # # # ]: 0 : if (save(self, callable, 0) < 0 ||
4096 [ # # ]: 0 : save(self, newargs, 0) < 0 ||
4097 : 0 : _Pickler_Write(self, &reduce_op, 1) < 0) {
4098 : 0 : Py_DECREF(newargs);
4099 : 0 : Py_DECREF(callable);
4100 : 0 : return -1;
4101 : : }
4102 : 0 : Py_DECREF(newargs);
4103 : 0 : Py_DECREF(callable);
4104 : : }
4105 : : }
4106 [ # # ]: 0 : else if (use_newobj) {
4107 : : PyObject *cls;
4108 : : PyObject *newargtup;
4109 : : PyObject *obj_class;
4110 : : int p;
4111 : :
4112 : : /* Sanity checks. */
4113 [ # # ]: 0 : if (PyTuple_GET_SIZE(argtup) < 1) {
4114 : 0 : PyErr_SetString(st->PicklingError, "__newobj__ arglist is empty");
4115 : 0 : return -1;
4116 : : }
4117 : :
4118 : 0 : cls = PyTuple_GET_ITEM(argtup, 0);
4119 [ # # ]: 0 : if (!PyType_Check(cls)) {
4120 : 0 : PyErr_SetString(st->PicklingError, "args[0] from "
4121 : : "__newobj__ args is not a type");
4122 : 0 : return -1;
4123 : : }
4124 : :
4125 [ # # ]: 0 : if (obj != NULL) {
4126 : 0 : obj_class = get_class(obj);
4127 [ # # ]: 0 : if (obj_class == NULL) {
4128 : 0 : return -1;
4129 : : }
4130 : 0 : p = obj_class != cls;
4131 : 0 : Py_DECREF(obj_class);
4132 [ # # ]: 0 : if (p) {
4133 : 0 : PyErr_SetString(st->PicklingError, "args[0] from "
4134 : : "__newobj__ args has the wrong class");
4135 : 0 : return -1;
4136 : : }
4137 : : }
4138 : : /* XXX: These calls save() are prone to infinite recursion. Imagine
4139 : : what happen if the value returned by the __reduce__() method of
4140 : : some extension type contains another object of the same type. Ouch!
4141 : :
4142 : : Here is a quick example, that I ran into, to illustrate what I
4143 : : mean:
4144 : :
4145 : : >>> import pickle, copyreg
4146 : : >>> copyreg.dispatch_table.pop(complex)
4147 : : >>> pickle.dumps(1+2j)
4148 : : Traceback (most recent call last):
4149 : : ...
4150 : : RecursionError: maximum recursion depth exceeded
4151 : :
4152 : : Removing the complex class from copyreg.dispatch_table made the
4153 : : __reduce_ex__() method emit another complex object:
4154 : :
4155 : : >>> (1+1j).__reduce_ex__(2)
4156 : : (<function __newobj__ at 0xb7b71c3c>,
4157 : : (<class 'complex'>, (1+1j)), None, None, None)
4158 : :
4159 : : Thus when save() was called on newargstup (the 2nd item) recursion
4160 : : ensued. Of course, the bug was in the complex class which had a
4161 : : broken __getnewargs__() that emitted another complex object. But,
4162 : : the point, here, is it is quite easy to end up with a broken reduce
4163 : : function. */
4164 : :
4165 : : /* Save the class and its __new__ arguments. */
4166 [ # # ]: 0 : if (save(self, cls, 0) < 0)
4167 : 0 : return -1;
4168 : :
4169 : 0 : newargtup = PyTuple_GetSlice(argtup, 1, PyTuple_GET_SIZE(argtup));
4170 [ # # ]: 0 : if (newargtup == NULL)
4171 : 0 : return -1;
4172 : :
4173 : 0 : p = save(self, newargtup, 0);
4174 : 0 : Py_DECREF(newargtup);
4175 [ # # ]: 0 : if (p < 0)
4176 : 0 : return -1;
4177 : :
4178 : : /* Add NEWOBJ opcode. */
4179 [ # # ]: 0 : if (_Pickler_Write(self, &newobj_op, 1) < 0)
4180 : 0 : return -1;
4181 : : }
4182 : : else { /* Not using NEWOBJ. */
4183 [ # # # # ]: 0 : if (save(self, callable, 0) < 0 ||
4184 [ # # ]: 0 : save(self, argtup, 0) < 0 ||
4185 : 0 : _Pickler_Write(self, &reduce_op, 1) < 0)
4186 : 0 : return -1;
4187 : : }
4188 : :
4189 : : /* obj can be NULL when save_reduce() is used directly. A NULL obj means
4190 : : the caller do not want to memoize the object. Not particularly useful,
4191 : : but that is to mimic the behavior save_reduce() in pickle.py when
4192 : : obj is None. */
4193 [ # # ]: 0 : if (obj != NULL) {
4194 : : /* If the object is already in the memo, this means it is
4195 : : recursive. In this case, throw away everything we put on the
4196 : : stack, and fetch the object back from the memo. */
4197 [ # # ]: 0 : if (PyMemoTable_Get(self->memo, obj)) {
4198 : 0 : const char pop_op = POP;
4199 : :
4200 [ # # ]: 0 : if (_Pickler_Write(self, &pop_op, 1) < 0)
4201 : 0 : return -1;
4202 [ # # ]: 0 : if (memo_get(self, obj) < 0)
4203 : 0 : return -1;
4204 : :
4205 : 0 : return 0;
4206 : : }
4207 [ # # ]: 0 : else if (memo_put(self, obj) < 0)
4208 : 0 : return -1;
4209 : : }
4210 : :
4211 [ # # # # ]: 0 : if (listitems && batch_list(self, listitems) < 0)
4212 : 0 : return -1;
4213 : :
4214 [ # # # # ]: 0 : if (dictitems && batch_dict(self, dictitems) < 0)
4215 : 0 : return -1;
4216 : :
4217 [ # # ]: 0 : if (state) {
4218 [ # # ]: 0 : if (state_setter == NULL) {
4219 [ # # # # ]: 0 : if (save(self, state, 0) < 0 ||
4220 : 0 : _Pickler_Write(self, &build_op, 1) < 0)
4221 : 0 : return -1;
4222 : : }
4223 : : else {
4224 : :
4225 : : /* If a state_setter is specified, call it instead of load_build to
4226 : : * update obj's with its previous state.
4227 : : * The first 4 save/write instructions push state_setter and its
4228 : : * tuple of expected arguments (obj, state) onto the stack. The
4229 : : * REDUCE opcode triggers the state_setter(obj, state) function
4230 : : * call. Finally, because state-updating routines only do in-place
4231 : : * modification, the whole operation has to be stack-transparent.
4232 : : * Thus, we finally pop the call's output from the stack.*/
4233 : :
4234 : 0 : const char tupletwo_op = TUPLE2;
4235 : 0 : const char pop_op = POP;
4236 [ # # # # ]: 0 : if (save(self, state_setter, 0) < 0 ||
4237 [ # # # # ]: 0 : save(self, obj, 0) < 0 || save(self, state, 0) < 0 ||
4238 [ # # ]: 0 : _Pickler_Write(self, &tupletwo_op, 1) < 0 ||
4239 [ # # ]: 0 : _Pickler_Write(self, &reduce_op, 1) < 0 ||
4240 : 0 : _Pickler_Write(self, &pop_op, 1) < 0)
4241 : 0 : return -1;
4242 : : }
4243 : : }
4244 : 0 : return 0;
4245 : : }
4246 : :
4247 : : static int
4248 : 0 : save(PicklerObject *self, PyObject *obj, int pers_save)
4249 : : {
4250 : : PyTypeObject *type;
4251 : 0 : PyObject *reduce_func = NULL;
4252 : 0 : PyObject *reduce_value = NULL;
4253 : 0 : int status = 0;
4254 : :
4255 [ # # ]: 0 : if (_Pickler_OpcodeBoundary(self) < 0)
4256 : 0 : return -1;
4257 : :
4258 : : /* The extra pers_save argument is necessary to avoid calling save_pers()
4259 : : on its returned object. */
4260 [ # # # # ]: 0 : if (!pers_save && self->pers_func) {
4261 : : /* save_pers() returns:
4262 : : -1 to signal an error;
4263 : : 0 if it did nothing successfully;
4264 : : 1 if a persistent id was saved.
4265 : : */
4266 [ # # ]: 0 : if ((status = save_pers(self, obj)) != 0)
4267 : 0 : return status;
4268 : : }
4269 : :
4270 : 0 : type = Py_TYPE(obj);
4271 : :
4272 : : /* The old cPickle had an optimization that used switch-case statement
4273 : : dispatching on the first letter of the type name. This has was removed
4274 : : since benchmarks shown that this optimization was actually slowing
4275 : : things down. */
4276 : :
4277 : : /* Atom types; these aren't memoized, so don't check the memo. */
4278 : :
4279 [ # # ]: 0 : if (obj == Py_None) {
4280 : 0 : return save_none(self, obj);
4281 : : }
4282 [ # # # # ]: 0 : else if (obj == Py_False || obj == Py_True) {
4283 : 0 : return save_bool(self, obj);
4284 : : }
4285 [ # # ]: 0 : else if (type == &PyLong_Type) {
4286 : 0 : return save_long(self, obj);
4287 : : }
4288 [ # # ]: 0 : else if (type == &PyFloat_Type) {
4289 : 0 : return save_float(self, obj);
4290 : : }
4291 : :
4292 : : /* Check the memo to see if it has the object. If so, generate
4293 : : a GET (or BINGET) opcode, instead of pickling the object
4294 : : once again. */
4295 [ # # ]: 0 : if (PyMemoTable_Get(self->memo, obj)) {
4296 : 0 : return memo_get(self, obj);
4297 : : }
4298 : :
4299 [ # # ]: 0 : if (type == &PyBytes_Type) {
4300 : 0 : return save_bytes(self, obj);
4301 : : }
4302 [ # # ]: 0 : else if (type == &PyUnicode_Type) {
4303 : 0 : return save_unicode(self, obj);
4304 : : }
4305 : :
4306 : : /* We're only calling _Py_EnterRecursiveCall here so that atomic
4307 : : types above are pickled faster. */
4308 [ # # ]: 0 : if (_Py_EnterRecursiveCall(" while pickling an object")) {
4309 : 0 : return -1;
4310 : : }
4311 : :
4312 [ # # ]: 0 : if (type == &PyDict_Type) {
4313 : 0 : status = save_dict(self, obj);
4314 : 0 : goto done;
4315 : : }
4316 [ # # ]: 0 : else if (type == &PySet_Type) {
4317 : 0 : status = save_set(self, obj);
4318 : 0 : goto done;
4319 : : }
4320 [ # # ]: 0 : else if (type == &PyFrozenSet_Type) {
4321 : 0 : status = save_frozenset(self, obj);
4322 : 0 : goto done;
4323 : : }
4324 [ # # ]: 0 : else if (type == &PyList_Type) {
4325 : 0 : status = save_list(self, obj);
4326 : 0 : goto done;
4327 : : }
4328 [ # # ]: 0 : else if (type == &PyTuple_Type) {
4329 : 0 : status = save_tuple(self, obj);
4330 : 0 : goto done;
4331 : : }
4332 [ # # ]: 0 : else if (type == &PyByteArray_Type) {
4333 : 0 : status = save_bytearray(self, obj);
4334 : 0 : goto done;
4335 : : }
4336 [ # # ]: 0 : else if (type == &PyPickleBuffer_Type) {
4337 : 0 : status = save_picklebuffer(self, obj);
4338 : 0 : goto done;
4339 : : }
4340 : :
4341 : : /* Now, check reducer_override. If it returns NotImplemented,
4342 : : * fallback to save_type or save_global, and then perhaps to the
4343 : : * regular reduction mechanism.
4344 : : */
4345 [ # # ]: 0 : if (self->reducer_override != NULL) {
4346 : 0 : reduce_value = PyObject_CallOneArg(self->reducer_override, obj);
4347 [ # # ]: 0 : if (reduce_value == NULL) {
4348 : 0 : goto error;
4349 : : }
4350 [ # # ]: 0 : if (reduce_value != Py_NotImplemented) {
4351 : 0 : goto reduce;
4352 : : }
4353 : 0 : Py_SETREF(reduce_value, NULL);
4354 : : }
4355 : :
4356 [ # # ]: 0 : if (type == &PyType_Type) {
4357 : 0 : status = save_type(self, obj);
4358 : 0 : goto done;
4359 : : }
4360 [ # # ]: 0 : else if (type == &PyFunction_Type) {
4361 : 0 : status = save_global(self, obj, NULL);
4362 : 0 : goto done;
4363 : : }
4364 : :
4365 : : /* XXX: This part needs some unit tests. */
4366 : :
4367 : : /* Get a reduction callable, and call it. This may come from
4368 : : * self.dispatch_table, copyreg.dispatch_table, the object's
4369 : : * __reduce_ex__ method, or the object's __reduce__ method.
4370 : : */
4371 [ # # ]: 0 : if (self->dispatch_table == NULL) {
4372 : 0 : PickleState *st = _Pickle_GetGlobalState();
4373 : 0 : reduce_func = PyDict_GetItemWithError(st->dispatch_table,
4374 : : (PyObject *)type);
4375 [ # # ]: 0 : if (reduce_func == NULL) {
4376 [ # # ]: 0 : if (PyErr_Occurred()) {
4377 : 0 : goto error;
4378 : : }
4379 : : } else {
4380 : : /* PyDict_GetItemWithError() returns a borrowed reference.
4381 : : Increase the reference count to be consistent with
4382 : : PyObject_GetItem and _PyObject_GetAttrId used below. */
4383 : 0 : Py_INCREF(reduce_func);
4384 : : }
4385 : : } else {
4386 : 0 : reduce_func = PyObject_GetItem(self->dispatch_table,
4387 : : (PyObject *)type);
4388 [ # # ]: 0 : if (reduce_func == NULL) {
4389 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_KeyError))
4390 : 0 : PyErr_Clear();
4391 : : else
4392 : 0 : goto error;
4393 : : }
4394 : : }
4395 [ # # ]: 0 : if (reduce_func != NULL) {
4396 : 0 : reduce_value = _Pickle_FastCall(reduce_func, Py_NewRef(obj));
4397 : : }
4398 [ # # ]: 0 : else if (PyType_IsSubtype(type, &PyType_Type)) {
4399 : 0 : status = save_global(self, obj, NULL);
4400 : 0 : goto done;
4401 : : }
4402 : : else {
4403 : : /* XXX: If the __reduce__ method is defined, __reduce_ex__ is
4404 : : automatically defined as __reduce__. While this is convenient, this
4405 : : make it impossible to know which method was actually called. Of
4406 : : course, this is not a big deal. But still, it would be nice to let
4407 : : the user know which method was called when something go
4408 : : wrong. Incidentally, this means if __reduce_ex__ is not defined, we
4409 : : don't actually have to check for a __reduce__ method. */
4410 : :
4411 : : /* Check for a __reduce_ex__ method. */
4412 [ # # ]: 0 : if (_PyObject_LookupAttr(obj, &_Py_ID(__reduce_ex__), &reduce_func) < 0) {
4413 : 0 : goto error;
4414 : : }
4415 [ # # ]: 0 : if (reduce_func != NULL) {
4416 : : PyObject *proto;
4417 : 0 : proto = PyLong_FromLong(self->proto);
4418 [ # # ]: 0 : if (proto != NULL) {
4419 : 0 : reduce_value = _Pickle_FastCall(reduce_func, proto);
4420 : : }
4421 : : }
4422 : : else {
4423 : : /* Check for a __reduce__ method. */
4424 [ # # ]: 0 : if (_PyObject_LookupAttr(obj, &_Py_ID(__reduce__), &reduce_func) < 0) {
4425 : 0 : goto error;
4426 : : }
4427 [ # # ]: 0 : if (reduce_func != NULL) {
4428 : 0 : reduce_value = PyObject_CallNoArgs(reduce_func);
4429 : : }
4430 : : else {
4431 : 0 : PickleState *st = _Pickle_GetGlobalState();
4432 : 0 : PyErr_Format(st->PicklingError,
4433 : : "can't pickle '%.200s' object: %R",
4434 : : type->tp_name, obj);
4435 : 0 : goto error;
4436 : : }
4437 : : }
4438 : : }
4439 : :
4440 [ # # ]: 0 : if (reduce_value == NULL)
4441 : 0 : goto error;
4442 : :
4443 : 0 : reduce:
4444 [ # # ]: 0 : if (PyUnicode_Check(reduce_value)) {
4445 : 0 : status = save_global(self, obj, reduce_value);
4446 : 0 : goto done;
4447 : : }
4448 : :
4449 [ # # ]: 0 : if (!PyTuple_Check(reduce_value)) {
4450 : 0 : PickleState *st = _Pickle_GetGlobalState();
4451 : 0 : PyErr_SetString(st->PicklingError,
4452 : : "__reduce__ must return a string or tuple");
4453 : 0 : goto error;
4454 : : }
4455 : :
4456 : 0 : status = save_reduce(self, reduce_value, obj);
4457 : :
4458 : : if (0) {
4459 : 0 : error:
4460 : 0 : status = -1;
4461 : : }
4462 : 0 : done:
4463 : :
4464 : 0 : _Py_LeaveRecursiveCall();
4465 : 0 : Py_XDECREF(reduce_func);
4466 : 0 : Py_XDECREF(reduce_value);
4467 : :
4468 : 0 : return status;
4469 : : }
4470 : :
4471 : : static int
4472 : 0 : dump(PicklerObject *self, PyObject *obj)
4473 : : {
4474 : 0 : const char stop_op = STOP;
4475 : 0 : int status = -1;
4476 : : PyObject *tmp;
4477 : :
4478 [ # # ]: 0 : if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(reducer_override),
4479 : : &tmp) < 0) {
4480 : 0 : goto error;
4481 : : }
4482 : : /* Cache the reducer_override method, if it exists. */
4483 [ # # ]: 0 : if (tmp != NULL) {
4484 : 0 : Py_XSETREF(self->reducer_override, tmp);
4485 : : }
4486 : : else {
4487 [ # # ]: 0 : Py_CLEAR(self->reducer_override);
4488 : : }
4489 : :
4490 [ # # ]: 0 : if (self->proto >= 2) {
4491 : : char header[2];
4492 : :
4493 : 0 : header[0] = PROTO;
4494 : : assert(self->proto >= 0 && self->proto < 256);
4495 : 0 : header[1] = (unsigned char)self->proto;
4496 [ # # ]: 0 : if (_Pickler_Write(self, header, 2) < 0)
4497 : 0 : goto error;
4498 [ # # ]: 0 : if (self->proto >= 4)
4499 : 0 : self->framing = 1;
4500 : : }
4501 : :
4502 [ # # # # ]: 0 : if (save(self, obj, 0) < 0 ||
4503 [ # # ]: 0 : _Pickler_Write(self, &stop_op, 1) < 0 ||
4504 : 0 : _Pickler_CommitFrame(self) < 0)
4505 : 0 : goto error;
4506 : :
4507 : : // Success
4508 : 0 : status = 0;
4509 : :
4510 : 0 : error:
4511 : 0 : self->framing = 0;
4512 : :
4513 : : /* Break the reference cycle we generated at the beginning this function
4514 : : * call when setting the reducer_override attribute of the Pickler instance
4515 : : * to a bound method of the same instance. This is important as the Pickler
4516 : : * instance holds a reference to each object it has pickled (through its
4517 : : * memo): thus, these objects won't be garbage-collected as long as the
4518 : : * Pickler itself is not collected. */
4519 [ # # ]: 0 : Py_CLEAR(self->reducer_override);
4520 : 0 : return status;
4521 : : }
4522 : :
4523 : : /*[clinic input]
4524 : :
4525 : : _pickle.Pickler.clear_memo
4526 : :
4527 : : Clears the pickler's "memo".
4528 : :
4529 : : The memo is the data structure that remembers which objects the
4530 : : pickler has already seen, so that shared or recursive objects are
4531 : : pickled by reference and not by value. This method is useful when
4532 : : re-using picklers.
4533 : : [clinic start generated code]*/
4534 : :
4535 : : static PyObject *
4536 : 0 : _pickle_Pickler_clear_memo_impl(PicklerObject *self)
4537 : : /*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/
4538 : : {
4539 [ # # ]: 0 : if (self->memo)
4540 : 0 : PyMemoTable_Clear(self->memo);
4541 : :
4542 : 0 : Py_RETURN_NONE;
4543 : : }
4544 : :
4545 : : /*[clinic input]
4546 : :
4547 : : _pickle.Pickler.dump
4548 : :
4549 : : obj: object
4550 : : /
4551 : :
4552 : : Write a pickled representation of the given object to the open file.
4553 : : [clinic start generated code]*/
4554 : :
4555 : : static PyObject *
4556 : 0 : _pickle_Pickler_dump(PicklerObject *self, PyObject *obj)
4557 : : /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/
4558 : : {
4559 : : /* Check whether the Pickler was initialized correctly (issue3664).
4560 : : Developers often forget to call __init__() in their subclasses, which
4561 : : would trigger a segfault without this check. */
4562 [ # # ]: 0 : if (self->write == NULL) {
4563 : 0 : PickleState *st = _Pickle_GetGlobalState();
4564 : 0 : PyErr_Format(st->PicklingError,
4565 : : "Pickler.__init__() was not called by %s.__init__()",
4566 : 0 : Py_TYPE(self)->tp_name);
4567 : 0 : return NULL;
4568 : : }
4569 : :
4570 [ # # ]: 0 : if (_Pickler_ClearBuffer(self) < 0)
4571 : 0 : return NULL;
4572 : :
4573 [ # # ]: 0 : if (dump(self, obj) < 0)
4574 : 0 : return NULL;
4575 : :
4576 [ # # ]: 0 : if (_Pickler_FlushToFile(self) < 0)
4577 : 0 : return NULL;
4578 : :
4579 : 0 : Py_RETURN_NONE;
4580 : : }
4581 : :
4582 : : /*[clinic input]
4583 : :
4584 : : _pickle.Pickler.__sizeof__ -> size_t
4585 : :
4586 : : Returns size in memory, in bytes.
4587 : : [clinic start generated code]*/
4588 : :
4589 : : static size_t
4590 : 0 : _pickle_Pickler___sizeof___impl(PicklerObject *self)
4591 : : /*[clinic end generated code: output=23ad75658d3b59ff input=d8127c8e7012ebd7]*/
4592 : : {
4593 : 0 : size_t res = _PyObject_SIZE(Py_TYPE(self));
4594 [ # # ]: 0 : if (self->memo != NULL) {
4595 : 0 : res += sizeof(PyMemoTable);
4596 : 0 : res += self->memo->mt_allocated * sizeof(PyMemoEntry);
4597 : : }
4598 [ # # ]: 0 : if (self->output_buffer != NULL) {
4599 : 0 : size_t s = _PySys_GetSizeOf(self->output_buffer);
4600 [ # # ]: 0 : if (s == (size_t)-1) {
4601 : 0 : return -1;
4602 : : }
4603 : 0 : res += s;
4604 : : }
4605 : 0 : return res;
4606 : : }
4607 : :
4608 : : static struct PyMethodDef Pickler_methods[] = {
4609 : : _PICKLE_PICKLER_DUMP_METHODDEF
4610 : : _PICKLE_PICKLER_CLEAR_MEMO_METHODDEF
4611 : : _PICKLE_PICKLER___SIZEOF___METHODDEF
4612 : : {NULL, NULL} /* sentinel */
4613 : : };
4614 : :
4615 : : static void
4616 : 0 : Pickler_dealloc(PicklerObject *self)
4617 : : {
4618 : 0 : PyObject_GC_UnTrack(self);
4619 : :
4620 : 0 : Py_XDECREF(self->output_buffer);
4621 : 0 : Py_XDECREF(self->write);
4622 : 0 : Py_XDECREF(self->pers_func);
4623 : 0 : Py_XDECREF(self->dispatch_table);
4624 : 0 : Py_XDECREF(self->fast_memo);
4625 : 0 : Py_XDECREF(self->reducer_override);
4626 : 0 : Py_XDECREF(self->buffer_callback);
4627 : :
4628 : 0 : PyMemoTable_Del(self->memo);
4629 : :
4630 : 0 : Py_TYPE(self)->tp_free((PyObject *)self);
4631 : 0 : }
4632 : :
4633 : : static int
4634 : 0 : Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
4635 : : {
4636 [ # # # # ]: 0 : Py_VISIT(self->write);
4637 [ # # # # ]: 0 : Py_VISIT(self->pers_func);
4638 [ # # # # ]: 0 : Py_VISIT(self->dispatch_table);
4639 [ # # # # ]: 0 : Py_VISIT(self->fast_memo);
4640 [ # # # # ]: 0 : Py_VISIT(self->reducer_override);
4641 [ # # # # ]: 0 : Py_VISIT(self->buffer_callback);
4642 : 0 : return 0;
4643 : : }
4644 : :
4645 : : static int
4646 : 0 : Pickler_clear(PicklerObject *self)
4647 : : {
4648 [ # # ]: 0 : Py_CLEAR(self->output_buffer);
4649 [ # # ]: 0 : Py_CLEAR(self->write);
4650 [ # # ]: 0 : Py_CLEAR(self->pers_func);
4651 [ # # ]: 0 : Py_CLEAR(self->dispatch_table);
4652 [ # # ]: 0 : Py_CLEAR(self->fast_memo);
4653 [ # # ]: 0 : Py_CLEAR(self->reducer_override);
4654 [ # # ]: 0 : Py_CLEAR(self->buffer_callback);
4655 : :
4656 [ # # ]: 0 : if (self->memo != NULL) {
4657 : 0 : PyMemoTable *memo = self->memo;
4658 : 0 : self->memo = NULL;
4659 : 0 : PyMemoTable_Del(memo);
4660 : : }
4661 : 0 : return 0;
4662 : : }
4663 : :
4664 : :
4665 : : /*[clinic input]
4666 : :
4667 : : _pickle.Pickler.__init__
4668 : :
4669 : : file: object
4670 : : protocol: object = None
4671 : : fix_imports: bool = True
4672 : : buffer_callback: object = None
4673 : :
4674 : : This takes a binary file for writing a pickle data stream.
4675 : :
4676 : : The optional *protocol* argument tells the pickler to use the given
4677 : : protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default
4678 : : protocol is 4. It was introduced in Python 3.4, and is incompatible
4679 : : with previous versions.
4680 : :
4681 : : Specifying a negative protocol version selects the highest protocol
4682 : : version supported. The higher the protocol used, the more recent the
4683 : : version of Python needed to read the pickle produced.
4684 : :
4685 : : The *file* argument must have a write() method that accepts a single
4686 : : bytes argument. It can thus be a file object opened for binary
4687 : : writing, an io.BytesIO instance, or any other custom object that meets
4688 : : this interface.
4689 : :
4690 : : If *fix_imports* is True and protocol is less than 3, pickle will try
4691 : : to map the new Python 3 names to the old module names used in Python
4692 : : 2, so that the pickle data stream is readable with Python 2.
4693 : :
4694 : : If *buffer_callback* is None (the default), buffer views are
4695 : : serialized into *file* as part of the pickle stream.
4696 : :
4697 : : If *buffer_callback* is not None, then it can be called any number
4698 : : of times with a buffer view. If the callback returns a false value
4699 : : (such as None), the given buffer is out-of-band; otherwise the
4700 : : buffer is serialized in-band, i.e. inside the pickle stream.
4701 : :
4702 : : It is an error if *buffer_callback* is not None and *protocol*
4703 : : is None or smaller than 5.
4704 : :
4705 : : [clinic start generated code]*/
4706 : :
4707 : : static int
4708 : 0 : _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
4709 : : PyObject *protocol, int fix_imports,
4710 : : PyObject *buffer_callback)
4711 : : /*[clinic end generated code: output=0abedc50590d259b input=a7c969699bf5dad3]*/
4712 : : {
4713 : : /* In case of multiple __init__() calls, clear previous content. */
4714 [ # # ]: 0 : if (self->write != NULL)
4715 : 0 : (void)Pickler_clear(self);
4716 : :
4717 [ # # ]: 0 : if (_Pickler_SetProtocol(self, protocol, fix_imports) < 0)
4718 : 0 : return -1;
4719 : :
4720 [ # # ]: 0 : if (_Pickler_SetOutputStream(self, file) < 0)
4721 : 0 : return -1;
4722 : :
4723 [ # # ]: 0 : if (_Pickler_SetBufferCallback(self, buffer_callback) < 0)
4724 : 0 : return -1;
4725 : :
4726 : : /* memo and output_buffer may have already been created in _Pickler_New */
4727 [ # # ]: 0 : if (self->memo == NULL) {
4728 : 0 : self->memo = PyMemoTable_New();
4729 [ # # ]: 0 : if (self->memo == NULL)
4730 : 0 : return -1;
4731 : : }
4732 : 0 : self->output_len = 0;
4733 [ # # ]: 0 : if (self->output_buffer == NULL) {
4734 : 0 : self->max_output_len = WRITE_BUF_SIZE;
4735 : 0 : self->output_buffer = PyBytes_FromStringAndSize(NULL,
4736 : : self->max_output_len);
4737 [ # # ]: 0 : if (self->output_buffer == NULL)
4738 : 0 : return -1;
4739 : : }
4740 : :
4741 : 0 : self->fast = 0;
4742 : 0 : self->fast_nesting = 0;
4743 : 0 : self->fast_memo = NULL;
4744 : :
4745 [ # # ]: 0 : if (init_method_ref((PyObject *)self, &_Py_ID(persistent_id),
4746 : : &self->pers_func, &self->pers_func_self) < 0)
4747 : : {
4748 : 0 : return -1;
4749 : : }
4750 [ # # ]: 0 : if (self->dispatch_table != NULL) {
4751 : 0 : return 0;
4752 : : }
4753 [ # # ]: 0 : if (_PyObject_LookupAttr((PyObject *)self, &_Py_ID(dispatch_table),
4754 : : &self->dispatch_table) < 0) {
4755 : 0 : return -1;
4756 : : }
4757 : :
4758 : 0 : return 0;
4759 : : }
4760 : :
4761 : :
4762 : : /* Define a proxy object for the Pickler's internal memo object. This is to
4763 : : * avoid breaking code like:
4764 : : * pickler.memo.clear()
4765 : : * and
4766 : : * pickler.memo = saved_memo
4767 : : * Is this a good idea? Not really, but we don't want to break code that uses
4768 : : * it. Note that we don't implement the entire mapping API here. This is
4769 : : * intentional, as these should be treated as black-box implementation details.
4770 : : */
4771 : :
4772 : : /*[clinic input]
4773 : : _pickle.PicklerMemoProxy.clear
4774 : :
4775 : : Remove all items from memo.
4776 : : [clinic start generated code]*/
4777 : :
4778 : : static PyObject *
4779 : 0 : _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self)
4780 : : /*[clinic end generated code: output=5fb9370d48ae8b05 input=ccc186dacd0f1405]*/
4781 : : {
4782 [ # # ]: 0 : if (self->pickler->memo)
4783 : 0 : PyMemoTable_Clear(self->pickler->memo);
4784 : 0 : Py_RETURN_NONE;
4785 : : }
4786 : :
4787 : : /*[clinic input]
4788 : : _pickle.PicklerMemoProxy.copy
4789 : :
4790 : : Copy the memo to a new object.
4791 : : [clinic start generated code]*/
4792 : :
4793 : : static PyObject *
4794 : 0 : _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self)
4795 : : /*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/
4796 : : {
4797 : : PyMemoTable *memo;
4798 : 0 : PyObject *new_memo = PyDict_New();
4799 [ # # ]: 0 : if (new_memo == NULL)
4800 : 0 : return NULL;
4801 : :
4802 : 0 : memo = self->pickler->memo;
4803 [ # # ]: 0 : for (size_t i = 0; i < memo->mt_allocated; ++i) {
4804 : 0 : PyMemoEntry entry = memo->mt_table[i];
4805 [ # # ]: 0 : if (entry.me_key != NULL) {
4806 : : int status;
4807 : : PyObject *key, *value;
4808 : :
4809 : 0 : key = PyLong_FromVoidPtr(entry.me_key);
4810 : 0 : value = Py_BuildValue("nO", entry.me_value, entry.me_key);
4811 : :
4812 [ # # # # ]: 0 : if (key == NULL || value == NULL) {
4813 : 0 : Py_XDECREF(key);
4814 : 0 : Py_XDECREF(value);
4815 : 0 : goto error;
4816 : : }
4817 : 0 : status = PyDict_SetItem(new_memo, key, value);
4818 : 0 : Py_DECREF(key);
4819 : 0 : Py_DECREF(value);
4820 [ # # ]: 0 : if (status < 0)
4821 : 0 : goto error;
4822 : : }
4823 : : }
4824 : 0 : return new_memo;
4825 : :
4826 : 0 : error:
4827 : 0 : Py_XDECREF(new_memo);
4828 : 0 : return NULL;
4829 : : }
4830 : :
4831 : : /*[clinic input]
4832 : : _pickle.PicklerMemoProxy.__reduce__
4833 : :
4834 : : Implement pickle support.
4835 : : [clinic start generated code]*/
4836 : :
4837 : : static PyObject *
4838 : 0 : _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self)
4839 : : /*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/
4840 : : {
4841 : : PyObject *reduce_value, *dict_args;
4842 : 0 : PyObject *contents = _pickle_PicklerMemoProxy_copy_impl(self);
4843 [ # # ]: 0 : if (contents == NULL)
4844 : 0 : return NULL;
4845 : :
4846 : 0 : reduce_value = PyTuple_New(2);
4847 [ # # ]: 0 : if (reduce_value == NULL) {
4848 : 0 : Py_DECREF(contents);
4849 : 0 : return NULL;
4850 : : }
4851 : 0 : dict_args = PyTuple_New(1);
4852 [ # # ]: 0 : if (dict_args == NULL) {
4853 : 0 : Py_DECREF(contents);
4854 : 0 : Py_DECREF(reduce_value);
4855 : 0 : return NULL;
4856 : : }
4857 : 0 : PyTuple_SET_ITEM(dict_args, 0, contents);
4858 : 0 : PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type));
4859 : 0 : PyTuple_SET_ITEM(reduce_value, 1, dict_args);
4860 : 0 : return reduce_value;
4861 : : }
4862 : :
4863 : : static PyMethodDef picklerproxy_methods[] = {
4864 : : _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF
4865 : : _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF
4866 : : _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF
4867 : : {NULL, NULL} /* sentinel */
4868 : : };
4869 : :
4870 : : static void
4871 : 0 : PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self)
4872 : : {
4873 : 0 : PyObject_GC_UnTrack(self);
4874 : 0 : Py_XDECREF(self->pickler);
4875 : 0 : PyObject_GC_Del((PyObject *)self);
4876 : 0 : }
4877 : :
4878 : : static int
4879 : 0 : PicklerMemoProxy_traverse(PicklerMemoProxyObject *self,
4880 : : visitproc visit, void *arg)
4881 : : {
4882 [ # # # # ]: 0 : Py_VISIT(self->pickler);
4883 : 0 : return 0;
4884 : : }
4885 : :
4886 : : static int
4887 : 0 : PicklerMemoProxy_clear(PicklerMemoProxyObject *self)
4888 : : {
4889 [ # # ]: 0 : Py_CLEAR(self->pickler);
4890 : 0 : return 0;
4891 : : }
4892 : :
4893 : : static PyTypeObject PicklerMemoProxyType = {
4894 : : PyVarObject_HEAD_INIT(NULL, 0)
4895 : : "_pickle.PicklerMemoProxy", /*tp_name*/
4896 : : sizeof(PicklerMemoProxyObject), /*tp_basicsize*/
4897 : : 0,
4898 : : (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */
4899 : : 0, /* tp_vectorcall_offset */
4900 : : 0, /* tp_getattr */
4901 : : 0, /* tp_setattr */
4902 : : 0, /* tp_as_async */
4903 : : 0, /* tp_repr */
4904 : : 0, /* tp_as_number */
4905 : : 0, /* tp_as_sequence */
4906 : : 0, /* tp_as_mapping */
4907 : : PyObject_HashNotImplemented, /* tp_hash */
4908 : : 0, /* tp_call */
4909 : : 0, /* tp_str */
4910 : : PyObject_GenericGetAttr, /* tp_getattro */
4911 : : PyObject_GenericSetAttr, /* tp_setattro */
4912 : : 0, /* tp_as_buffer */
4913 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
4914 : : 0, /* tp_doc */
4915 : : (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */
4916 : : (inquiry)PicklerMemoProxy_clear, /* tp_clear */
4917 : : 0, /* tp_richcompare */
4918 : : 0, /* tp_weaklistoffset */
4919 : : 0, /* tp_iter */
4920 : : 0, /* tp_iternext */
4921 : : picklerproxy_methods, /* tp_methods */
4922 : : };
4923 : :
4924 : : static PyObject *
4925 : 0 : PicklerMemoProxy_New(PicklerObject *pickler)
4926 : : {
4927 : : PicklerMemoProxyObject *self;
4928 : :
4929 : 0 : self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType);
4930 [ # # ]: 0 : if (self == NULL)
4931 : 0 : return NULL;
4932 : 0 : self->pickler = (PicklerObject*)Py_NewRef(pickler);
4933 : 0 : PyObject_GC_Track(self);
4934 : 0 : return (PyObject *)self;
4935 : : }
4936 : :
4937 : : /*****************************************************************************/
4938 : :
4939 : : static PyObject *
4940 : 0 : Pickler_get_memo(PicklerObject *self, void *Py_UNUSED(ignored))
4941 : : {
4942 : 0 : return PicklerMemoProxy_New(self);
4943 : : }
4944 : :
4945 : : static int
4946 : 0 : Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored))
4947 : : {
4948 : 0 : PyMemoTable *new_memo = NULL;
4949 : :
4950 [ # # ]: 0 : if (obj == NULL) {
4951 : 0 : PyErr_SetString(PyExc_TypeError,
4952 : : "attribute deletion is not supported");
4953 : 0 : return -1;
4954 : : }
4955 : :
4956 [ # # ]: 0 : if (Py_IS_TYPE(obj, &PicklerMemoProxyType)) {
4957 : 0 : PicklerObject *pickler =
4958 : : ((PicklerMemoProxyObject *)obj)->pickler;
4959 : :
4960 : 0 : new_memo = PyMemoTable_Copy(pickler->memo);
4961 [ # # ]: 0 : if (new_memo == NULL)
4962 : 0 : return -1;
4963 : : }
4964 [ # # ]: 0 : else if (PyDict_Check(obj)) {
4965 : 0 : Py_ssize_t i = 0;
4966 : : PyObject *key, *value;
4967 : :
4968 : 0 : new_memo = PyMemoTable_New();
4969 [ # # ]: 0 : if (new_memo == NULL)
4970 : 0 : return -1;
4971 : :
4972 [ # # ]: 0 : while (PyDict_Next(obj, &i, &key, &value)) {
4973 : : Py_ssize_t memo_id;
4974 : : PyObject *memo_obj;
4975 : :
4976 [ # # # # ]: 0 : if (!PyTuple_Check(value) || PyTuple_GET_SIZE(value) != 2) {
4977 : 0 : PyErr_SetString(PyExc_TypeError,
4978 : : "'memo' values must be 2-item tuples");
4979 : 0 : goto error;
4980 : : }
4981 : 0 : memo_id = PyLong_AsSsize_t(PyTuple_GET_ITEM(value, 0));
4982 [ # # # # ]: 0 : if (memo_id == -1 && PyErr_Occurred())
4983 : 0 : goto error;
4984 : 0 : memo_obj = PyTuple_GET_ITEM(value, 1);
4985 [ # # ]: 0 : if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0)
4986 : 0 : goto error;
4987 : : }
4988 : : }
4989 : : else {
4990 : 0 : PyErr_Format(PyExc_TypeError,
4991 : : "'memo' attribute must be a PicklerMemoProxy object "
4992 : 0 : "or dict, not %.200s", Py_TYPE(obj)->tp_name);
4993 : 0 : return -1;
4994 : : }
4995 : :
4996 : 0 : PyMemoTable_Del(self->memo);
4997 : 0 : self->memo = new_memo;
4998 : :
4999 : 0 : return 0;
5000 : :
5001 : 0 : error:
5002 [ # # ]: 0 : if (new_memo)
5003 : 0 : PyMemoTable_Del(new_memo);
5004 : 0 : return -1;
5005 : : }
5006 : :
5007 : : static PyObject *
5008 : 0 : Pickler_get_persid(PicklerObject *self, void *Py_UNUSED(ignored))
5009 : : {
5010 [ # # ]: 0 : if (self->pers_func == NULL) {
5011 : 0 : PyErr_SetString(PyExc_AttributeError, "persistent_id");
5012 : 0 : return NULL;
5013 : : }
5014 : 0 : return reconstruct_method(self->pers_func, self->pers_func_self);
5015 : : }
5016 : :
5017 : : static int
5018 : 0 : Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored))
5019 : : {
5020 [ # # ]: 0 : if (value == NULL) {
5021 : 0 : PyErr_SetString(PyExc_TypeError,
5022 : : "attribute deletion is not supported");
5023 : 0 : return -1;
5024 : : }
5025 [ # # ]: 0 : if (!PyCallable_Check(value)) {
5026 : 0 : PyErr_SetString(PyExc_TypeError,
5027 : : "persistent_id must be a callable taking one argument");
5028 : 0 : return -1;
5029 : : }
5030 : :
5031 : 0 : self->pers_func_self = NULL;
5032 : 0 : Py_XSETREF(self->pers_func, Py_NewRef(value));
5033 : :
5034 : 0 : return 0;
5035 : : }
5036 : :
5037 : : static PyMemberDef Pickler_members[] = {
5038 : : {"bin", T_INT, offsetof(PicklerObject, bin)},
5039 : : {"fast", T_INT, offsetof(PicklerObject, fast)},
5040 : : {"dispatch_table", T_OBJECT_EX, offsetof(PicklerObject, dispatch_table)},
5041 : : {NULL}
5042 : : };
5043 : :
5044 : : static PyGetSetDef Pickler_getsets[] = {
5045 : : {"memo", (getter)Pickler_get_memo,
5046 : : (setter)Pickler_set_memo},
5047 : : {"persistent_id", (getter)Pickler_get_persid,
5048 : : (setter)Pickler_set_persid},
5049 : : {NULL}
5050 : : };
5051 : :
5052 : : static PyTypeObject Pickler_Type = {
5053 : : PyVarObject_HEAD_INIT(NULL, 0)
5054 : : "_pickle.Pickler" , /*tp_name*/
5055 : : sizeof(PicklerObject), /*tp_basicsize*/
5056 : : 0, /*tp_itemsize*/
5057 : : (destructor)Pickler_dealloc, /*tp_dealloc*/
5058 : : 0, /*tp_vectorcall_offset*/
5059 : : 0, /*tp_getattr*/
5060 : : 0, /*tp_setattr*/
5061 : : 0, /*tp_as_async*/
5062 : : 0, /*tp_repr*/
5063 : : 0, /*tp_as_number*/
5064 : : 0, /*tp_as_sequence*/
5065 : : 0, /*tp_as_mapping*/
5066 : : 0, /*tp_hash*/
5067 : : 0, /*tp_call*/
5068 : : 0, /*tp_str*/
5069 : : 0, /*tp_getattro*/
5070 : : 0, /*tp_setattro*/
5071 : : 0, /*tp_as_buffer*/
5072 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
5073 : : _pickle_Pickler___init____doc__, /*tp_doc*/
5074 : : (traverseproc)Pickler_traverse, /*tp_traverse*/
5075 : : (inquiry)Pickler_clear, /*tp_clear*/
5076 : : 0, /*tp_richcompare*/
5077 : : 0, /*tp_weaklistoffset*/
5078 : : 0, /*tp_iter*/
5079 : : 0, /*tp_iternext*/
5080 : : Pickler_methods, /*tp_methods*/
5081 : : Pickler_members, /*tp_members*/
5082 : : Pickler_getsets, /*tp_getset*/
5083 : : 0, /*tp_base*/
5084 : : 0, /*tp_dict*/
5085 : : 0, /*tp_descr_get*/
5086 : : 0, /*tp_descr_set*/
5087 : : 0, /*tp_dictoffset*/
5088 : : _pickle_Pickler___init__, /*tp_init*/
5089 : : PyType_GenericAlloc, /*tp_alloc*/
5090 : : PyType_GenericNew, /*tp_new*/
5091 : : PyObject_GC_Del, /*tp_free*/
5092 : : 0, /*tp_is_gc*/
5093 : : };
5094 : :
5095 : : /* Temporary helper for calling self.find_class().
5096 : :
5097 : : XXX: It would be nice to able to avoid Python function call overhead, by
5098 : : using directly the C version of find_class(), when find_class() is not
5099 : : overridden by a subclass. Although, this could become rather hackish. A
5100 : : simpler optimization would be to call the C function when self is not a
5101 : : subclass instance. */
5102 : : static PyObject *
5103 : 0 : find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name)
5104 : : {
5105 : 0 : return PyObject_CallMethodObjArgs((PyObject *)self, &_Py_ID(find_class),
5106 : : module_name, global_name, NULL);
5107 : : }
5108 : :
5109 : : static Py_ssize_t
5110 : 0 : marker(UnpicklerObject *self)
5111 : : {
5112 : : Py_ssize_t mark;
5113 : :
5114 [ # # ]: 0 : if (self->num_marks < 1) {
5115 : 0 : PickleState *st = _Pickle_GetGlobalState();
5116 : 0 : PyErr_SetString(st->UnpicklingError, "could not find MARK");
5117 : 0 : return -1;
5118 : : }
5119 : :
5120 : 0 : mark = self->marks[--self->num_marks];
5121 : 0 : self->stack->mark_set = self->num_marks != 0;
5122 : 0 : self->stack->fence = self->num_marks ?
5123 [ # # ]: 0 : self->marks[self->num_marks - 1] : 0;
5124 : 0 : return mark;
5125 : : }
5126 : :
5127 : : static int
5128 : 0 : load_none(UnpicklerObject *self)
5129 : : {
5130 [ # # ]: 0 : PDATA_APPEND(self->stack, Py_None, -1);
5131 : 0 : return 0;
5132 : : }
5133 : :
5134 : : static int
5135 : 0 : load_int(UnpicklerObject *self)
5136 : : {
5137 : : PyObject *value;
5138 : : char *endptr, *s;
5139 : : Py_ssize_t len;
5140 : : long x;
5141 : :
5142 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5143 : 0 : return -1;
5144 [ # # ]: 0 : if (len < 2)
5145 : 0 : return bad_readline();
5146 : :
5147 : 0 : errno = 0;
5148 : : /* XXX: Should the base argument of strtol() be explicitly set to 10?
5149 : : XXX(avassalotti): Should this uses PyOS_strtol()? */
5150 : 0 : x = strtol(s, &endptr, 0);
5151 : :
5152 [ # # # # : 0 : if (errno || (*endptr != '\n' && *endptr != '\0')) {
# # ]
5153 : : /* Hm, maybe we've got something long. Let's try reading
5154 : : * it as a Python int object. */
5155 : 0 : errno = 0;
5156 : : /* XXX: Same thing about the base here. */
5157 : 0 : value = PyLong_FromString(s, NULL, 0);
5158 [ # # ]: 0 : if (value == NULL) {
5159 : 0 : PyErr_SetString(PyExc_ValueError,
5160 : : "could not convert string to int");
5161 : 0 : return -1;
5162 : : }
5163 : : }
5164 : : else {
5165 [ # # # # : 0 : if (len == 3 && (x == 0 || x == 1)) {
# # ]
5166 [ # # ]: 0 : if ((value = PyBool_FromLong(x)) == NULL)
5167 : 0 : return -1;
5168 : : }
5169 : : else {
5170 [ # # ]: 0 : if ((value = PyLong_FromLong(x)) == NULL)
5171 : 0 : return -1;
5172 : : }
5173 : : }
5174 : :
5175 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5176 : 0 : return 0;
5177 : : }
5178 : :
5179 : : static int
5180 : 0 : load_bool(UnpicklerObject *self, PyObject *boolean)
5181 : : {
5182 : : assert(boolean == Py_True || boolean == Py_False);
5183 [ # # ]: 0 : PDATA_APPEND(self->stack, boolean, -1);
5184 : 0 : return 0;
5185 : : }
5186 : :
5187 : : /* s contains x bytes of an unsigned little-endian integer. Return its value
5188 : : * as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX.
5189 : : */
5190 : : static Py_ssize_t
5191 : 0 : calc_binsize(char *bytes, int nbytes)
5192 : : {
5193 : 0 : unsigned char *s = (unsigned char *)bytes;
5194 : : int i;
5195 : 0 : size_t x = 0;
5196 : :
5197 [ # # ]: 0 : if (nbytes > (int)sizeof(size_t)) {
5198 : : /* Check for integer overflow. BINBYTES8 and BINUNICODE8 opcodes
5199 : : * have 64-bit size that can't be represented on 32-bit platform.
5200 : : */
5201 [ # # ]: 0 : for (i = (int)sizeof(size_t); i < nbytes; i++) {
5202 [ # # ]: 0 : if (s[i])
5203 : 0 : return -1;
5204 : : }
5205 : 0 : nbytes = (int)sizeof(size_t);
5206 : : }
5207 [ # # ]: 0 : for (i = 0; i < nbytes; i++) {
5208 : 0 : x |= (size_t) s[i] << (8 * i);
5209 : : }
5210 : :
5211 [ # # ]: 0 : if (x > PY_SSIZE_T_MAX)
5212 : 0 : return -1;
5213 : : else
5214 : 0 : return (Py_ssize_t) x;
5215 : : }
5216 : :
5217 : : /* s contains x bytes of a little-endian integer. Return its value as a
5218 : : * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian
5219 : : * int, but when x is 4 it's a signed one. This is a historical source
5220 : : * of x-platform bugs.
5221 : : */
5222 : : static long
5223 : 0 : calc_binint(char *bytes, int nbytes)
5224 : : {
5225 : 0 : unsigned char *s = (unsigned char *)bytes;
5226 : : Py_ssize_t i;
5227 : 0 : long x = 0;
5228 : :
5229 [ # # ]: 0 : for (i = 0; i < nbytes; i++) {
5230 : 0 : x |= (long)s[i] << (8 * i);
5231 : : }
5232 : :
5233 : : /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
5234 : : * is signed, so on a box with longs bigger than 4 bytes we need
5235 : : * to extend a BININT's sign bit to the full width.
5236 : : */
5237 [ # # ]: 0 : if (SIZEOF_LONG > 4 && nbytes == 4) {
5238 : 0 : x |= -(x & (1L << 31));
5239 : : }
5240 : :
5241 : 0 : return x;
5242 : : }
5243 : :
5244 : : static int
5245 : 0 : load_binintx(UnpicklerObject *self, char *s, int size)
5246 : : {
5247 : : PyObject *value;
5248 : : long x;
5249 : :
5250 : 0 : x = calc_binint(s, size);
5251 : :
5252 [ # # ]: 0 : if ((value = PyLong_FromLong(x)) == NULL)
5253 : 0 : return -1;
5254 : :
5255 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5256 : 0 : return 0;
5257 : : }
5258 : :
5259 : : static int
5260 : 0 : load_binint(UnpicklerObject *self)
5261 : : {
5262 : : char *s;
5263 : :
5264 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 4) < 0)
5265 : 0 : return -1;
5266 : :
5267 : 0 : return load_binintx(self, s, 4);
5268 : : }
5269 : :
5270 : : static int
5271 : 0 : load_binint1(UnpicklerObject *self)
5272 : : {
5273 : : char *s;
5274 : :
5275 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 1) < 0)
5276 : 0 : return -1;
5277 : :
5278 : 0 : return load_binintx(self, s, 1);
5279 : : }
5280 : :
5281 : : static int
5282 : 0 : load_binint2(UnpicklerObject *self)
5283 : : {
5284 : : char *s;
5285 : :
5286 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 2) < 0)
5287 : 0 : return -1;
5288 : :
5289 : 0 : return load_binintx(self, s, 2);
5290 : : }
5291 : :
5292 : : static int
5293 : 0 : load_long(UnpicklerObject *self)
5294 : : {
5295 : : PyObject *value;
5296 : 0 : char *s = NULL;
5297 : : Py_ssize_t len;
5298 : :
5299 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5300 : 0 : return -1;
5301 [ # # ]: 0 : if (len < 2)
5302 : 0 : return bad_readline();
5303 : :
5304 : : /* s[len-2] will usually be 'L' (and s[len-1] is '\n'); we need to remove
5305 : : the 'L' before calling PyLong_FromString. In order to maintain
5306 : : compatibility with Python 3.0.0, we don't actually *require*
5307 : : the 'L' to be present. */
5308 [ # # ]: 0 : if (s[len-2] == 'L')
5309 : 0 : s[len-2] = '\0';
5310 : : /* XXX: Should the base argument explicitly set to 10? */
5311 : 0 : value = PyLong_FromString(s, NULL, 0);
5312 [ # # ]: 0 : if (value == NULL)
5313 : 0 : return -1;
5314 : :
5315 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5316 : 0 : return 0;
5317 : : }
5318 : :
5319 : : /* 'size' bytes contain the # of bytes of little-endian 256's-complement
5320 : : * data following.
5321 : : */
5322 : : static int
5323 : 0 : load_counted_long(UnpicklerObject *self, int size)
5324 : : {
5325 : : PyObject *value;
5326 : : char *nbytes;
5327 : : char *pdata;
5328 : :
5329 : : assert(size == 1 || size == 4);
5330 [ # # # # ]: 0 : if (_Unpickler_Read(self, &nbytes, size) < 0)
5331 : 0 : return -1;
5332 : :
5333 : 0 : size = calc_binint(nbytes, size);
5334 [ # # ]: 0 : if (size < 0) {
5335 : 0 : PickleState *st = _Pickle_GetGlobalState();
5336 : : /* Corrupt or hostile pickle -- we never write one like this */
5337 : 0 : PyErr_SetString(st->UnpicklingError,
5338 : : "LONG pickle has negative byte count");
5339 : 0 : return -1;
5340 : : }
5341 : :
5342 [ # # ]: 0 : if (size == 0)
5343 : 0 : value = PyLong_FromLong(0L);
5344 : : else {
5345 : : /* Read the raw little-endian bytes and convert. */
5346 [ # # # # ]: 0 : if (_Unpickler_Read(self, &pdata, size) < 0)
5347 : 0 : return -1;
5348 : 0 : value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size,
5349 : : 1 /* little endian */ , 1 /* signed */ );
5350 : : }
5351 [ # # ]: 0 : if (value == NULL)
5352 : 0 : return -1;
5353 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5354 : 0 : return 0;
5355 : : }
5356 : :
5357 : : static int
5358 : 0 : load_float(UnpicklerObject *self)
5359 : : {
5360 : : PyObject *value;
5361 : : char *endptr, *s;
5362 : : Py_ssize_t len;
5363 : : double d;
5364 : :
5365 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5366 : 0 : return -1;
5367 [ # # ]: 0 : if (len < 2)
5368 : 0 : return bad_readline();
5369 : :
5370 : 0 : errno = 0;
5371 : 0 : d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError);
5372 [ # # # # ]: 0 : if (d == -1.0 && PyErr_Occurred())
5373 : 0 : return -1;
5374 [ # # # # ]: 0 : if ((endptr[0] != '\n') && (endptr[0] != '\0')) {
5375 : 0 : PyErr_SetString(PyExc_ValueError, "could not convert string to float");
5376 : 0 : return -1;
5377 : : }
5378 : 0 : value = PyFloat_FromDouble(d);
5379 [ # # ]: 0 : if (value == NULL)
5380 : 0 : return -1;
5381 : :
5382 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5383 : 0 : return 0;
5384 : : }
5385 : :
5386 : : static int
5387 : 0 : load_binfloat(UnpicklerObject *self)
5388 : : {
5389 : : PyObject *value;
5390 : : double x;
5391 : : char *s;
5392 : :
5393 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 8) < 0)
5394 : 0 : return -1;
5395 : :
5396 : 0 : x = PyFloat_Unpack8(s, 0);
5397 [ # # # # ]: 0 : if (x == -1.0 && PyErr_Occurred())
5398 : 0 : return -1;
5399 : :
5400 [ # # ]: 0 : if ((value = PyFloat_FromDouble(x)) == NULL)
5401 : 0 : return -1;
5402 : :
5403 [ # # ]: 0 : PDATA_PUSH(self->stack, value, -1);
5404 : 0 : return 0;
5405 : : }
5406 : :
5407 : : static int
5408 : 0 : load_string(UnpicklerObject *self)
5409 : : {
5410 : : PyObject *bytes;
5411 : : PyObject *obj;
5412 : : Py_ssize_t len;
5413 : : char *s, *p;
5414 : :
5415 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5416 : 0 : return -1;
5417 : : /* Strip the newline */
5418 : 0 : len--;
5419 : : /* Strip outermost quotes */
5420 [ # # # # : 0 : if (len >= 2 && s[0] == s[len - 1] && (s[0] == '\'' || s[0] == '"')) {
# # # # ]
5421 : 0 : p = s + 1;
5422 : 0 : len -= 2;
5423 : : }
5424 : : else {
5425 : 0 : PickleState *st = _Pickle_GetGlobalState();
5426 : 0 : PyErr_SetString(st->UnpicklingError,
5427 : : "the STRING opcode argument must be quoted");
5428 : 0 : return -1;
5429 : : }
5430 : : assert(len >= 0);
5431 : :
5432 : : /* Use the PyBytes API to decode the string, since that is what is used
5433 : : to encode, and then coerce the result to Unicode. */
5434 : 0 : bytes = PyBytes_DecodeEscape(p, len, NULL, 0, NULL);
5435 [ # # ]: 0 : if (bytes == NULL)
5436 : 0 : return -1;
5437 : :
5438 : : /* Leave the Python 2.x strings as bytes if the *encoding* given to the
5439 : : Unpickler was 'bytes'. Otherwise, convert them to unicode. */
5440 [ # # ]: 0 : if (strcmp(self->encoding, "bytes") == 0) {
5441 : 0 : obj = bytes;
5442 : : }
5443 : : else {
5444 : 0 : obj = PyUnicode_FromEncodedObject(bytes, self->encoding, self->errors);
5445 : 0 : Py_DECREF(bytes);
5446 [ # # ]: 0 : if (obj == NULL) {
5447 : 0 : return -1;
5448 : : }
5449 : : }
5450 : :
5451 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
5452 : 0 : return 0;
5453 : : }
5454 : :
5455 : : static int
5456 : 0 : load_counted_binstring(UnpicklerObject *self, int nbytes)
5457 : : {
5458 : : PyObject *obj;
5459 : : Py_ssize_t size;
5460 : : char *s;
5461 : :
5462 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, nbytes) < 0)
5463 : 0 : return -1;
5464 : :
5465 : 0 : size = calc_binsize(s, nbytes);
5466 [ # # ]: 0 : if (size < 0) {
5467 : 0 : PickleState *st = _Pickle_GetGlobalState();
5468 : 0 : PyErr_Format(st->UnpicklingError,
5469 : : "BINSTRING exceeds system's maximum size of %zd bytes",
5470 : : PY_SSIZE_T_MAX);
5471 : 0 : return -1;
5472 : : }
5473 : :
5474 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, size) < 0)
5475 : 0 : return -1;
5476 : :
5477 : : /* Convert Python 2.x strings to bytes if the *encoding* given to the
5478 : : Unpickler was 'bytes'. Otherwise, convert them to unicode. */
5479 [ # # ]: 0 : if (strcmp(self->encoding, "bytes") == 0) {
5480 : 0 : obj = PyBytes_FromStringAndSize(s, size);
5481 : : }
5482 : : else {
5483 : 0 : obj = PyUnicode_Decode(s, size, self->encoding, self->errors);
5484 : : }
5485 [ # # ]: 0 : if (obj == NULL) {
5486 : 0 : return -1;
5487 : : }
5488 : :
5489 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
5490 : 0 : return 0;
5491 : : }
5492 : :
5493 : : static int
5494 : 0 : load_counted_binbytes(UnpicklerObject *self, int nbytes)
5495 : : {
5496 : : PyObject *bytes;
5497 : : Py_ssize_t size;
5498 : : char *s;
5499 : :
5500 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, nbytes) < 0)
5501 : 0 : return -1;
5502 : :
5503 : 0 : size = calc_binsize(s, nbytes);
5504 [ # # ]: 0 : if (size < 0) {
5505 : 0 : PyErr_Format(PyExc_OverflowError,
5506 : : "BINBYTES exceeds system's maximum size of %zd bytes",
5507 : : PY_SSIZE_T_MAX);
5508 : 0 : return -1;
5509 : : }
5510 : :
5511 : 0 : bytes = PyBytes_FromStringAndSize(NULL, size);
5512 [ # # ]: 0 : if (bytes == NULL)
5513 : 0 : return -1;
5514 [ # # ]: 0 : if (_Unpickler_ReadInto(self, PyBytes_AS_STRING(bytes), size) < 0) {
5515 : 0 : Py_DECREF(bytes);
5516 : 0 : return -1;
5517 : : }
5518 : :
5519 [ # # ]: 0 : PDATA_PUSH(self->stack, bytes, -1);
5520 : 0 : return 0;
5521 : : }
5522 : :
5523 : : static int
5524 : 0 : load_counted_bytearray(UnpicklerObject *self)
5525 : : {
5526 : : PyObject *bytearray;
5527 : : Py_ssize_t size;
5528 : : char *s;
5529 : :
5530 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 8) < 0) {
5531 : 0 : return -1;
5532 : : }
5533 : :
5534 : 0 : size = calc_binsize(s, 8);
5535 [ # # ]: 0 : if (size < 0) {
5536 : 0 : PyErr_Format(PyExc_OverflowError,
5537 : : "BYTEARRAY8 exceeds system's maximum size of %zd bytes",
5538 : : PY_SSIZE_T_MAX);
5539 : 0 : return -1;
5540 : : }
5541 : :
5542 : 0 : bytearray = PyByteArray_FromStringAndSize(NULL, size);
5543 [ # # ]: 0 : if (bytearray == NULL) {
5544 : 0 : return -1;
5545 : : }
5546 [ # # ]: 0 : if (_Unpickler_ReadInto(self, PyByteArray_AS_STRING(bytearray), size) < 0) {
5547 : 0 : Py_DECREF(bytearray);
5548 : 0 : return -1;
5549 : : }
5550 : :
5551 [ # # ]: 0 : PDATA_PUSH(self->stack, bytearray, -1);
5552 : 0 : return 0;
5553 : : }
5554 : :
5555 : : static int
5556 : 0 : load_next_buffer(UnpicklerObject *self)
5557 : : {
5558 [ # # ]: 0 : if (self->buffers == NULL) {
5559 : 0 : PickleState *st = _Pickle_GetGlobalState();
5560 : 0 : PyErr_SetString(st->UnpicklingError,
5561 : : "pickle stream refers to out-of-band data "
5562 : : "but no *buffers* argument was given");
5563 : 0 : return -1;
5564 : : }
5565 : 0 : PyObject *buf = PyIter_Next(self->buffers);
5566 [ # # ]: 0 : if (buf == NULL) {
5567 [ # # ]: 0 : if (!PyErr_Occurred()) {
5568 : 0 : PickleState *st = _Pickle_GetGlobalState();
5569 : 0 : PyErr_SetString(st->UnpicklingError,
5570 : : "not enough out-of-band buffers");
5571 : : }
5572 : 0 : return -1;
5573 : : }
5574 : :
5575 [ # # ]: 0 : PDATA_PUSH(self->stack, buf, -1);
5576 : 0 : return 0;
5577 : : }
5578 : :
5579 : : static int
5580 : 0 : load_readonly_buffer(UnpicklerObject *self)
5581 : : {
5582 : 0 : Py_ssize_t len = Py_SIZE(self->stack);
5583 [ # # ]: 0 : if (len <= self->stack->fence) {
5584 : 0 : return Pdata_stack_underflow(self->stack);
5585 : : }
5586 : :
5587 : 0 : PyObject *obj = self->stack->data[len - 1];
5588 : 0 : PyObject *view = PyMemoryView_FromObject(obj);
5589 [ # # ]: 0 : if (view == NULL) {
5590 : 0 : return -1;
5591 : : }
5592 [ # # ]: 0 : if (!PyMemoryView_GET_BUFFER(view)->readonly) {
5593 : : /* Original object is writable */
5594 : 0 : PyMemoryView_GET_BUFFER(view)->readonly = 1;
5595 : 0 : self->stack->data[len - 1] = view;
5596 : 0 : Py_DECREF(obj);
5597 : : }
5598 : : else {
5599 : : /* Original object is read-only, no need to replace it */
5600 : 0 : Py_DECREF(view);
5601 : : }
5602 : 0 : return 0;
5603 : : }
5604 : :
5605 : : static int
5606 : 0 : load_unicode(UnpicklerObject *self)
5607 : : {
5608 : : PyObject *str;
5609 : : Py_ssize_t len;
5610 : 0 : char *s = NULL;
5611 : :
5612 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5613 : 0 : return -1;
5614 [ # # ]: 0 : if (len < 1)
5615 : 0 : return bad_readline();
5616 : :
5617 : 0 : str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL);
5618 [ # # ]: 0 : if (str == NULL)
5619 : 0 : return -1;
5620 : :
5621 [ # # ]: 0 : PDATA_PUSH(self->stack, str, -1);
5622 : 0 : return 0;
5623 : : }
5624 : :
5625 : : static int
5626 : 0 : load_counted_binunicode(UnpicklerObject *self, int nbytes)
5627 : : {
5628 : : PyObject *str;
5629 : : Py_ssize_t size;
5630 : : char *s;
5631 : :
5632 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, nbytes) < 0)
5633 : 0 : return -1;
5634 : :
5635 : 0 : size = calc_binsize(s, nbytes);
5636 [ # # ]: 0 : if (size < 0) {
5637 : 0 : PyErr_Format(PyExc_OverflowError,
5638 : : "BINUNICODE exceeds system's maximum size of %zd bytes",
5639 : : PY_SSIZE_T_MAX);
5640 : 0 : return -1;
5641 : : }
5642 : :
5643 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, size) < 0)
5644 : 0 : return -1;
5645 : :
5646 : 0 : str = PyUnicode_DecodeUTF8(s, size, "surrogatepass");
5647 [ # # ]: 0 : if (str == NULL)
5648 : 0 : return -1;
5649 : :
5650 [ # # ]: 0 : PDATA_PUSH(self->stack, str, -1);
5651 : 0 : return 0;
5652 : : }
5653 : :
5654 : : static int
5655 : 0 : load_counted_tuple(UnpicklerObject *self, Py_ssize_t len)
5656 : : {
5657 : : PyObject *tuple;
5658 : :
5659 [ # # ]: 0 : if (Py_SIZE(self->stack) < len)
5660 : 0 : return Pdata_stack_underflow(self->stack);
5661 : :
5662 : 0 : tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len);
5663 [ # # ]: 0 : if (tuple == NULL)
5664 : 0 : return -1;
5665 [ # # ]: 0 : PDATA_PUSH(self->stack, tuple, -1);
5666 : 0 : return 0;
5667 : : }
5668 : :
5669 : : static int
5670 : 0 : load_tuple(UnpicklerObject *self)
5671 : : {
5672 : : Py_ssize_t i;
5673 : :
5674 [ # # ]: 0 : if ((i = marker(self)) < 0)
5675 : 0 : return -1;
5676 : :
5677 : 0 : return load_counted_tuple(self, Py_SIZE(self->stack) - i);
5678 : : }
5679 : :
5680 : : static int
5681 : 0 : load_empty_list(UnpicklerObject *self)
5682 : : {
5683 : : PyObject *list;
5684 : :
5685 [ # # ]: 0 : if ((list = PyList_New(0)) == NULL)
5686 : 0 : return -1;
5687 [ # # ]: 0 : PDATA_PUSH(self->stack, list, -1);
5688 : 0 : return 0;
5689 : : }
5690 : :
5691 : : static int
5692 : 0 : load_empty_dict(UnpicklerObject *self)
5693 : : {
5694 : : PyObject *dict;
5695 : :
5696 [ # # ]: 0 : if ((dict = PyDict_New()) == NULL)
5697 : 0 : return -1;
5698 [ # # ]: 0 : PDATA_PUSH(self->stack, dict, -1);
5699 : 0 : return 0;
5700 : : }
5701 : :
5702 : : static int
5703 : 0 : load_empty_set(UnpicklerObject *self)
5704 : : {
5705 : : PyObject *set;
5706 : :
5707 [ # # ]: 0 : if ((set = PySet_New(NULL)) == NULL)
5708 : 0 : return -1;
5709 [ # # ]: 0 : PDATA_PUSH(self->stack, set, -1);
5710 : 0 : return 0;
5711 : : }
5712 : :
5713 : : static int
5714 : 0 : load_list(UnpicklerObject *self)
5715 : : {
5716 : : PyObject *list;
5717 : : Py_ssize_t i;
5718 : :
5719 [ # # ]: 0 : if ((i = marker(self)) < 0)
5720 : 0 : return -1;
5721 : :
5722 : 0 : list = Pdata_poplist(self->stack, i);
5723 [ # # ]: 0 : if (list == NULL)
5724 : 0 : return -1;
5725 [ # # ]: 0 : PDATA_PUSH(self->stack, list, -1);
5726 : 0 : return 0;
5727 : : }
5728 : :
5729 : : static int
5730 : 0 : load_dict(UnpicklerObject *self)
5731 : : {
5732 : : PyObject *dict, *key, *value;
5733 : : Py_ssize_t i, j, k;
5734 : :
5735 [ # # ]: 0 : if ((i = marker(self)) < 0)
5736 : 0 : return -1;
5737 : 0 : j = Py_SIZE(self->stack);
5738 : :
5739 [ # # ]: 0 : if ((dict = PyDict_New()) == NULL)
5740 : 0 : return -1;
5741 : :
5742 [ # # ]: 0 : if ((j - i) % 2 != 0) {
5743 : 0 : PickleState *st = _Pickle_GetGlobalState();
5744 : 0 : PyErr_SetString(st->UnpicklingError, "odd number of items for DICT");
5745 : 0 : Py_DECREF(dict);
5746 : 0 : return -1;
5747 : : }
5748 : :
5749 [ # # ]: 0 : for (k = i + 1; k < j; k += 2) {
5750 : 0 : key = self->stack->data[k - 1];
5751 : 0 : value = self->stack->data[k];
5752 [ # # ]: 0 : if (PyDict_SetItem(dict, key, value) < 0) {
5753 : 0 : Py_DECREF(dict);
5754 : 0 : return -1;
5755 : : }
5756 : : }
5757 : 0 : Pdata_clear(self->stack, i);
5758 [ # # ]: 0 : PDATA_PUSH(self->stack, dict, -1);
5759 : 0 : return 0;
5760 : : }
5761 : :
5762 : : static int
5763 : 0 : load_frozenset(UnpicklerObject *self)
5764 : : {
5765 : : PyObject *items;
5766 : : PyObject *frozenset;
5767 : : Py_ssize_t i;
5768 : :
5769 [ # # ]: 0 : if ((i = marker(self)) < 0)
5770 : 0 : return -1;
5771 : :
5772 : 0 : items = Pdata_poptuple(self->stack, i);
5773 [ # # ]: 0 : if (items == NULL)
5774 : 0 : return -1;
5775 : :
5776 : 0 : frozenset = PyFrozenSet_New(items);
5777 : 0 : Py_DECREF(items);
5778 [ # # ]: 0 : if (frozenset == NULL)
5779 : 0 : return -1;
5780 : :
5781 [ # # ]: 0 : PDATA_PUSH(self->stack, frozenset, -1);
5782 : 0 : return 0;
5783 : : }
5784 : :
5785 : : static PyObject *
5786 : 0 : instantiate(PyObject *cls, PyObject *args)
5787 : : {
5788 : : /* Caller must assure args are a tuple. Normally, args come from
5789 : : Pdata_poptuple which packs objects from the top of the stack
5790 : : into a newly created tuple. */
5791 : : assert(PyTuple_Check(args));
5792 [ # # # # ]: 0 : if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) {
5793 : : PyObject *func;
5794 [ # # ]: 0 : if (_PyObject_LookupAttr(cls, &_Py_ID(__getinitargs__), &func) < 0) {
5795 : 0 : return NULL;
5796 : : }
5797 [ # # ]: 0 : if (func == NULL) {
5798 : 0 : return PyObject_CallMethodOneArg(cls, &_Py_ID(__new__), cls);
5799 : : }
5800 : 0 : Py_DECREF(func);
5801 : : }
5802 : 0 : return PyObject_CallObject(cls, args);
5803 : : }
5804 : :
5805 : : static int
5806 : 0 : load_obj(UnpicklerObject *self)
5807 : : {
5808 : 0 : PyObject *cls, *args, *obj = NULL;
5809 : : Py_ssize_t i;
5810 : :
5811 [ # # ]: 0 : if ((i = marker(self)) < 0)
5812 : 0 : return -1;
5813 : :
5814 [ # # ]: 0 : if (Py_SIZE(self->stack) - i < 1)
5815 : 0 : return Pdata_stack_underflow(self->stack);
5816 : :
5817 : 0 : args = Pdata_poptuple(self->stack, i + 1);
5818 [ # # ]: 0 : if (args == NULL)
5819 : 0 : return -1;
5820 : :
5821 : 0 : PDATA_POP(self->stack, cls);
5822 [ # # ]: 0 : if (cls) {
5823 : 0 : obj = instantiate(cls, args);
5824 : 0 : Py_DECREF(cls);
5825 : : }
5826 : 0 : Py_DECREF(args);
5827 [ # # ]: 0 : if (obj == NULL)
5828 : 0 : return -1;
5829 : :
5830 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
5831 : 0 : return 0;
5832 : : }
5833 : :
5834 : : static int
5835 : 0 : load_inst(UnpicklerObject *self)
5836 : : {
5837 : 0 : PyObject *cls = NULL;
5838 : 0 : PyObject *args = NULL;
5839 : 0 : PyObject *obj = NULL;
5840 : : PyObject *module_name;
5841 : : PyObject *class_name;
5842 : : Py_ssize_t len;
5843 : : Py_ssize_t i;
5844 : : char *s;
5845 : :
5846 [ # # ]: 0 : if ((i = marker(self)) < 0)
5847 : 0 : return -1;
5848 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5849 : 0 : return -1;
5850 [ # # ]: 0 : if (len < 2)
5851 : 0 : return bad_readline();
5852 : :
5853 : : /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII
5854 : : identifiers are permitted in Python 3.0, since the INST opcode is only
5855 : : supported by older protocols on Python 2.x. */
5856 : 0 : module_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
5857 [ # # ]: 0 : if (module_name == NULL)
5858 : 0 : return -1;
5859 : :
5860 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) >= 0) {
5861 [ # # ]: 0 : if (len < 2) {
5862 : 0 : Py_DECREF(module_name);
5863 : 0 : return bad_readline();
5864 : : }
5865 : 0 : class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
5866 [ # # ]: 0 : if (class_name != NULL) {
5867 : 0 : cls = find_class(self, module_name, class_name);
5868 : 0 : Py_DECREF(class_name);
5869 : : }
5870 : : }
5871 : 0 : Py_DECREF(module_name);
5872 : :
5873 [ # # ]: 0 : if (cls == NULL)
5874 : 0 : return -1;
5875 : :
5876 [ # # ]: 0 : if ((args = Pdata_poptuple(self->stack, i)) != NULL) {
5877 : 0 : obj = instantiate(cls, args);
5878 : 0 : Py_DECREF(args);
5879 : : }
5880 : 0 : Py_DECREF(cls);
5881 : :
5882 [ # # ]: 0 : if (obj == NULL)
5883 : 0 : return -1;
5884 : :
5885 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
5886 : 0 : return 0;
5887 : : }
5888 : :
5889 : : static void
5890 : 0 : newobj_unpickling_error(const char * msg, int use_kwargs, PyObject *arg)
5891 : : {
5892 : 0 : PickleState *st = _Pickle_GetGlobalState();
5893 [ # # ]: 0 : PyErr_Format(st->UnpicklingError, msg,
5894 : : use_kwargs ? "NEWOBJ_EX" : "NEWOBJ",
5895 : 0 : Py_TYPE(arg)->tp_name);
5896 : 0 : }
5897 : :
5898 : : static int
5899 : 0 : load_newobj(UnpicklerObject *self, int use_kwargs)
5900 : : {
5901 : 0 : PyObject *cls, *args, *kwargs = NULL;
5902 : : PyObject *obj;
5903 : :
5904 : : /* Stack is ... cls args [kwargs], and we want to call
5905 : : * cls.__new__(cls, *args, **kwargs).
5906 : : */
5907 [ # # ]: 0 : if (use_kwargs) {
5908 : 0 : PDATA_POP(self->stack, kwargs);
5909 [ # # ]: 0 : if (kwargs == NULL) {
5910 : 0 : return -1;
5911 : : }
5912 : : }
5913 : 0 : PDATA_POP(self->stack, args);
5914 [ # # ]: 0 : if (args == NULL) {
5915 : 0 : Py_XDECREF(kwargs);
5916 : 0 : return -1;
5917 : : }
5918 : 0 : PDATA_POP(self->stack, cls);
5919 [ # # ]: 0 : if (cls == NULL) {
5920 : 0 : Py_XDECREF(kwargs);
5921 : 0 : Py_DECREF(args);
5922 : 0 : return -1;
5923 : : }
5924 : :
5925 [ # # ]: 0 : if (!PyType_Check(cls)) {
5926 : 0 : newobj_unpickling_error("%s class argument must be a type, not %.200s",
5927 : : use_kwargs, cls);
5928 : 0 : goto error;
5929 : : }
5930 [ # # ]: 0 : if (((PyTypeObject *)cls)->tp_new == NULL) {
5931 : 0 : newobj_unpickling_error("%s class argument '%.200s' doesn't have __new__",
5932 : : use_kwargs, cls);
5933 : 0 : goto error;
5934 : : }
5935 [ # # ]: 0 : if (!PyTuple_Check(args)) {
5936 : 0 : newobj_unpickling_error("%s args argument must be a tuple, not %.200s",
5937 : : use_kwargs, args);
5938 : 0 : goto error;
5939 : : }
5940 [ # # # # ]: 0 : if (use_kwargs && !PyDict_Check(kwargs)) {
5941 : 0 : newobj_unpickling_error("%s kwargs argument must be a dict, not %.200s",
5942 : : use_kwargs, kwargs);
5943 : 0 : goto error;
5944 : : }
5945 : :
5946 : 0 : obj = ((PyTypeObject *)cls)->tp_new((PyTypeObject *)cls, args, kwargs);
5947 [ # # ]: 0 : if (obj == NULL) {
5948 : 0 : goto error;
5949 : : }
5950 : 0 : Py_XDECREF(kwargs);
5951 : 0 : Py_DECREF(args);
5952 : 0 : Py_DECREF(cls);
5953 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
5954 : 0 : return 0;
5955 : :
5956 : 0 : error:
5957 : 0 : Py_XDECREF(kwargs);
5958 : 0 : Py_DECREF(args);
5959 : 0 : Py_DECREF(cls);
5960 : 0 : return -1;
5961 : : }
5962 : :
5963 : : static int
5964 : 0 : load_global(UnpicklerObject *self)
5965 : : {
5966 : 0 : PyObject *global = NULL;
5967 : : PyObject *module_name;
5968 : : PyObject *global_name;
5969 : : Py_ssize_t len;
5970 : : char *s;
5971 : :
5972 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
5973 : 0 : return -1;
5974 [ # # ]: 0 : if (len < 2)
5975 : 0 : return bad_readline();
5976 : 0 : module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
5977 [ # # ]: 0 : if (!module_name)
5978 : 0 : return -1;
5979 : :
5980 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) >= 0) {
5981 [ # # ]: 0 : if (len < 2) {
5982 : 0 : Py_DECREF(module_name);
5983 : 0 : return bad_readline();
5984 : : }
5985 : 0 : global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict");
5986 [ # # ]: 0 : if (global_name) {
5987 : 0 : global = find_class(self, module_name, global_name);
5988 : 0 : Py_DECREF(global_name);
5989 : : }
5990 : : }
5991 : 0 : Py_DECREF(module_name);
5992 : :
5993 [ # # ]: 0 : if (global == NULL)
5994 : 0 : return -1;
5995 [ # # ]: 0 : PDATA_PUSH(self->stack, global, -1);
5996 : 0 : return 0;
5997 : : }
5998 : :
5999 : : static int
6000 : 0 : load_stack_global(UnpicklerObject *self)
6001 : : {
6002 : : PyObject *global;
6003 : : PyObject *module_name;
6004 : : PyObject *global_name;
6005 : :
6006 : 0 : PDATA_POP(self->stack, global_name);
6007 : 0 : PDATA_POP(self->stack, module_name);
6008 [ # # # # : 0 : if (module_name == NULL || !PyUnicode_CheckExact(module_name) ||
# # ]
6009 [ # # ]: 0 : global_name == NULL || !PyUnicode_CheckExact(global_name)) {
6010 : 0 : PickleState *st = _Pickle_GetGlobalState();
6011 : 0 : PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str");
6012 : 0 : Py_XDECREF(global_name);
6013 : 0 : Py_XDECREF(module_name);
6014 : 0 : return -1;
6015 : : }
6016 : 0 : global = find_class(self, module_name, global_name);
6017 : 0 : Py_DECREF(global_name);
6018 : 0 : Py_DECREF(module_name);
6019 [ # # ]: 0 : if (global == NULL)
6020 : 0 : return -1;
6021 [ # # ]: 0 : PDATA_PUSH(self->stack, global, -1);
6022 : 0 : return 0;
6023 : : }
6024 : :
6025 : : static int
6026 : 0 : load_persid(UnpicklerObject *self)
6027 : : {
6028 : : PyObject *pid, *obj;
6029 : : Py_ssize_t len;
6030 : : char *s;
6031 : :
6032 [ # # ]: 0 : if (self->pers_func) {
6033 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
6034 : 0 : return -1;
6035 [ # # ]: 0 : if (len < 1)
6036 : 0 : return bad_readline();
6037 : :
6038 : 0 : pid = PyUnicode_DecodeASCII(s, len - 1, "strict");
6039 [ # # ]: 0 : if (pid == NULL) {
6040 [ # # ]: 0 : if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
6041 : 0 : PyErr_SetString(_Pickle_GetGlobalState()->UnpicklingError,
6042 : : "persistent IDs in protocol 0 must be "
6043 : : "ASCII strings");
6044 : : }
6045 : 0 : return -1;
6046 : : }
6047 : :
6048 : 0 : obj = call_method(self->pers_func, self->pers_func_self, pid);
6049 : 0 : Py_DECREF(pid);
6050 [ # # ]: 0 : if (obj == NULL)
6051 : 0 : return -1;
6052 : :
6053 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
6054 : 0 : return 0;
6055 : : }
6056 : : else {
6057 : 0 : PickleState *st = _Pickle_GetGlobalState();
6058 : 0 : PyErr_SetString(st->UnpicklingError,
6059 : : "A load persistent id instruction was encountered, "
6060 : : "but no persistent_load function was specified.");
6061 : 0 : return -1;
6062 : : }
6063 : : }
6064 : :
6065 : : static int
6066 : 0 : load_binpersid(UnpicklerObject *self)
6067 : : {
6068 : : PyObject *pid, *obj;
6069 : :
6070 [ # # ]: 0 : if (self->pers_func) {
6071 : 0 : PDATA_POP(self->stack, pid);
6072 [ # # ]: 0 : if (pid == NULL)
6073 : 0 : return -1;
6074 : :
6075 : 0 : obj = call_method(self->pers_func, self->pers_func_self, pid);
6076 : 0 : Py_DECREF(pid);
6077 [ # # ]: 0 : if (obj == NULL)
6078 : 0 : return -1;
6079 : :
6080 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
6081 : 0 : return 0;
6082 : : }
6083 : : else {
6084 : 0 : PickleState *st = _Pickle_GetGlobalState();
6085 : 0 : PyErr_SetString(st->UnpicklingError,
6086 : : "A load persistent id instruction was encountered, "
6087 : : "but no persistent_load function was specified.");
6088 : 0 : return -1;
6089 : : }
6090 : : }
6091 : :
6092 : : static int
6093 : 0 : load_pop(UnpicklerObject *self)
6094 : : {
6095 : 0 : Py_ssize_t len = Py_SIZE(self->stack);
6096 : :
6097 : : /* Note that we split the (pickle.py) stack into two stacks,
6098 : : * an object stack and a mark stack. We have to be clever and
6099 : : * pop the right one. We do this by looking at the top of the
6100 : : * mark stack first, and only signalling a stack underflow if
6101 : : * the object stack is empty and the mark stack doesn't match
6102 : : * our expectations.
6103 : : */
6104 [ # # # # ]: 0 : if (self->num_marks > 0 && self->marks[self->num_marks - 1] == len) {
6105 : 0 : self->num_marks--;
6106 : 0 : self->stack->mark_set = self->num_marks != 0;
6107 : 0 : self->stack->fence = self->num_marks ?
6108 [ # # ]: 0 : self->marks[self->num_marks - 1] : 0;
6109 [ # # ]: 0 : } else if (len <= self->stack->fence)
6110 : 0 : return Pdata_stack_underflow(self->stack);
6111 : : else {
6112 : 0 : len--;
6113 : 0 : Py_DECREF(self->stack->data[len]);
6114 : 0 : Py_SET_SIZE(self->stack, len);
6115 : : }
6116 : 0 : return 0;
6117 : : }
6118 : :
6119 : : static int
6120 : 0 : load_pop_mark(UnpicklerObject *self)
6121 : : {
6122 : : Py_ssize_t i;
6123 : :
6124 [ # # ]: 0 : if ((i = marker(self)) < 0)
6125 : 0 : return -1;
6126 : :
6127 : 0 : Pdata_clear(self->stack, i);
6128 : :
6129 : 0 : return 0;
6130 : : }
6131 : :
6132 : : static int
6133 : 0 : load_dup(UnpicklerObject *self)
6134 : : {
6135 : : PyObject *last;
6136 : 0 : Py_ssize_t len = Py_SIZE(self->stack);
6137 : :
6138 [ # # ]: 0 : if (len <= self->stack->fence)
6139 : 0 : return Pdata_stack_underflow(self->stack);
6140 : 0 : last = self->stack->data[len - 1];
6141 [ # # ]: 0 : PDATA_APPEND(self->stack, last, -1);
6142 : 0 : return 0;
6143 : : }
6144 : :
6145 : : static int
6146 : 0 : load_get(UnpicklerObject *self)
6147 : : {
6148 : : PyObject *key, *value;
6149 : : Py_ssize_t idx;
6150 : : Py_ssize_t len;
6151 : : char *s;
6152 : :
6153 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
6154 : 0 : return -1;
6155 [ # # ]: 0 : if (len < 2)
6156 : 0 : return bad_readline();
6157 : :
6158 : 0 : key = PyLong_FromString(s, NULL, 10);
6159 [ # # ]: 0 : if (key == NULL)
6160 : 0 : return -1;
6161 : 0 : idx = PyLong_AsSsize_t(key);
6162 [ # # # # ]: 0 : if (idx == -1 && PyErr_Occurred()) {
6163 : 0 : Py_DECREF(key);
6164 : 0 : return -1;
6165 : : }
6166 : :
6167 : 0 : value = _Unpickler_MemoGet(self, idx);
6168 [ # # ]: 0 : if (value == NULL) {
6169 [ # # ]: 0 : if (!PyErr_Occurred()) {
6170 : 0 : PickleState *st = _Pickle_GetGlobalState();
6171 : 0 : PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx);
6172 : : }
6173 : 0 : Py_DECREF(key);
6174 : 0 : return -1;
6175 : : }
6176 : 0 : Py_DECREF(key);
6177 : :
6178 [ # # ]: 0 : PDATA_APPEND(self->stack, value, -1);
6179 : 0 : return 0;
6180 : : }
6181 : :
6182 : : static int
6183 : 0 : load_binget(UnpicklerObject *self)
6184 : : {
6185 : : PyObject *value;
6186 : : Py_ssize_t idx;
6187 : : char *s;
6188 : :
6189 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 1) < 0)
6190 : 0 : return -1;
6191 : :
6192 : 0 : idx = Py_CHARMASK(s[0]);
6193 : :
6194 : 0 : value = _Unpickler_MemoGet(self, idx);
6195 [ # # ]: 0 : if (value == NULL) {
6196 : 0 : PyObject *key = PyLong_FromSsize_t(idx);
6197 [ # # ]: 0 : if (key != NULL) {
6198 : 0 : PickleState *st = _Pickle_GetGlobalState();
6199 : 0 : PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx);
6200 : 0 : Py_DECREF(key);
6201 : : }
6202 : 0 : return -1;
6203 : : }
6204 : :
6205 [ # # ]: 0 : PDATA_APPEND(self->stack, value, -1);
6206 : 0 : return 0;
6207 : : }
6208 : :
6209 : : static int
6210 : 0 : load_long_binget(UnpicklerObject *self)
6211 : : {
6212 : : PyObject *value;
6213 : : Py_ssize_t idx;
6214 : : char *s;
6215 : :
6216 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 4) < 0)
6217 : 0 : return -1;
6218 : :
6219 : 0 : idx = calc_binsize(s, 4);
6220 : :
6221 : 0 : value = _Unpickler_MemoGet(self, idx);
6222 [ # # ]: 0 : if (value == NULL) {
6223 : 0 : PyObject *key = PyLong_FromSsize_t(idx);
6224 [ # # ]: 0 : if (key != NULL) {
6225 : 0 : PickleState *st = _Pickle_GetGlobalState();
6226 : 0 : PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx);
6227 : 0 : Py_DECREF(key);
6228 : : }
6229 : 0 : return -1;
6230 : : }
6231 : :
6232 [ # # ]: 0 : PDATA_APPEND(self->stack, value, -1);
6233 : 0 : return 0;
6234 : : }
6235 : :
6236 : : /* Push an object from the extension registry (EXT[124]). nbytes is
6237 : : * the number of bytes following the opcode, holding the index (code) value.
6238 : : */
6239 : : static int
6240 : 0 : load_extension(UnpicklerObject *self, int nbytes)
6241 : : {
6242 : : char *codebytes; /* the nbytes bytes after the opcode */
6243 : : long code; /* calc_binint returns long */
6244 : : PyObject *py_code; /* code as a Python int */
6245 : : PyObject *obj; /* the object to push */
6246 : : PyObject *pair; /* (module_name, class_name) */
6247 : : PyObject *module_name, *class_name;
6248 : 0 : PickleState *st = _Pickle_GetGlobalState();
6249 : :
6250 : : assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
6251 [ # # # # ]: 0 : if (_Unpickler_Read(self, &codebytes, nbytes) < 0)
6252 : 0 : return -1;
6253 : 0 : code = calc_binint(codebytes, nbytes);
6254 [ # # ]: 0 : if (code <= 0) { /* note that 0 is forbidden */
6255 : : /* Corrupt or hostile pickle. */
6256 : 0 : PyErr_SetString(st->UnpicklingError, "EXT specifies code <= 0");
6257 : 0 : return -1;
6258 : : }
6259 : :
6260 : : /* Look for the code in the cache. */
6261 : 0 : py_code = PyLong_FromLong(code);
6262 [ # # ]: 0 : if (py_code == NULL)
6263 : 0 : return -1;
6264 : 0 : obj = PyDict_GetItemWithError(st->extension_cache, py_code);
6265 [ # # ]: 0 : if (obj != NULL) {
6266 : : /* Bingo. */
6267 : 0 : Py_DECREF(py_code);
6268 [ # # ]: 0 : PDATA_APPEND(self->stack, obj, -1);
6269 : 0 : return 0;
6270 : : }
6271 [ # # ]: 0 : if (PyErr_Occurred()) {
6272 : 0 : Py_DECREF(py_code);
6273 : 0 : return -1;
6274 : : }
6275 : :
6276 : : /* Look up the (module_name, class_name) pair. */
6277 : 0 : pair = PyDict_GetItemWithError(st->inverted_registry, py_code);
6278 [ # # ]: 0 : if (pair == NULL) {
6279 : 0 : Py_DECREF(py_code);
6280 [ # # ]: 0 : if (!PyErr_Occurred()) {
6281 : 0 : PyErr_Format(PyExc_ValueError, "unregistered extension "
6282 : : "code %ld", code);
6283 : : }
6284 : 0 : return -1;
6285 : : }
6286 : : /* Since the extension registry is manipulable via Python code,
6287 : : * confirm that pair is really a 2-tuple of strings.
6288 : : */
6289 [ # # # # ]: 0 : if (!PyTuple_Check(pair) || PyTuple_Size(pair) != 2) {
6290 : 0 : goto error;
6291 : : }
6292 : :
6293 : 0 : module_name = PyTuple_GET_ITEM(pair, 0);
6294 [ # # ]: 0 : if (!PyUnicode_Check(module_name)) {
6295 : 0 : goto error;
6296 : : }
6297 : :
6298 : 0 : class_name = PyTuple_GET_ITEM(pair, 1);
6299 [ # # ]: 0 : if (!PyUnicode_Check(class_name)) {
6300 : 0 : goto error;
6301 : : }
6302 : :
6303 : : /* Load the object. */
6304 : 0 : obj = find_class(self, module_name, class_name);
6305 [ # # ]: 0 : if (obj == NULL) {
6306 : 0 : Py_DECREF(py_code);
6307 : 0 : return -1;
6308 : : }
6309 : : /* Cache code -> obj. */
6310 : 0 : code = PyDict_SetItem(st->extension_cache, py_code, obj);
6311 : 0 : Py_DECREF(py_code);
6312 [ # # ]: 0 : if (code < 0) {
6313 : 0 : Py_DECREF(obj);
6314 : 0 : return -1;
6315 : : }
6316 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
6317 : 0 : return 0;
6318 : :
6319 : 0 : error:
6320 : 0 : Py_DECREF(py_code);
6321 : 0 : PyErr_Format(PyExc_ValueError, "_inverted_registry[%ld] "
6322 : : "isn't a 2-tuple of strings", code);
6323 : 0 : return -1;
6324 : : }
6325 : :
6326 : : static int
6327 : 0 : load_put(UnpicklerObject *self)
6328 : : {
6329 : : PyObject *key, *value;
6330 : : Py_ssize_t idx;
6331 : : Py_ssize_t len;
6332 : 0 : char *s = NULL;
6333 : :
6334 [ # # ]: 0 : if ((len = _Unpickler_Readline(self, &s)) < 0)
6335 : 0 : return -1;
6336 [ # # ]: 0 : if (len < 2)
6337 : 0 : return bad_readline();
6338 [ # # ]: 0 : if (Py_SIZE(self->stack) <= self->stack->fence)
6339 : 0 : return Pdata_stack_underflow(self->stack);
6340 : 0 : value = self->stack->data[Py_SIZE(self->stack) - 1];
6341 : :
6342 : 0 : key = PyLong_FromString(s, NULL, 10);
6343 [ # # ]: 0 : if (key == NULL)
6344 : 0 : return -1;
6345 : 0 : idx = PyLong_AsSsize_t(key);
6346 : 0 : Py_DECREF(key);
6347 [ # # ]: 0 : if (idx < 0) {
6348 [ # # ]: 0 : if (!PyErr_Occurred())
6349 : 0 : PyErr_SetString(PyExc_ValueError,
6350 : : "negative PUT argument");
6351 : 0 : return -1;
6352 : : }
6353 : :
6354 : 0 : return _Unpickler_MemoPut(self, idx, value);
6355 : : }
6356 : :
6357 : : static int
6358 : 0 : load_binput(UnpicklerObject *self)
6359 : : {
6360 : : PyObject *value;
6361 : : Py_ssize_t idx;
6362 : : char *s;
6363 : :
6364 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 1) < 0)
6365 : 0 : return -1;
6366 : :
6367 [ # # ]: 0 : if (Py_SIZE(self->stack) <= self->stack->fence)
6368 : 0 : return Pdata_stack_underflow(self->stack);
6369 : 0 : value = self->stack->data[Py_SIZE(self->stack) - 1];
6370 : :
6371 : 0 : idx = Py_CHARMASK(s[0]);
6372 : :
6373 : 0 : return _Unpickler_MemoPut(self, idx, value);
6374 : : }
6375 : :
6376 : : static int
6377 : 0 : load_long_binput(UnpicklerObject *self)
6378 : : {
6379 : : PyObject *value;
6380 : : Py_ssize_t idx;
6381 : : char *s;
6382 : :
6383 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 4) < 0)
6384 : 0 : return -1;
6385 : :
6386 [ # # ]: 0 : if (Py_SIZE(self->stack) <= self->stack->fence)
6387 : 0 : return Pdata_stack_underflow(self->stack);
6388 : 0 : value = self->stack->data[Py_SIZE(self->stack) - 1];
6389 : :
6390 : 0 : idx = calc_binsize(s, 4);
6391 [ # # ]: 0 : if (idx < 0) {
6392 : 0 : PyErr_SetString(PyExc_ValueError,
6393 : : "negative LONG_BINPUT argument");
6394 : 0 : return -1;
6395 : : }
6396 : :
6397 : 0 : return _Unpickler_MemoPut(self, idx, value);
6398 : : }
6399 : :
6400 : : static int
6401 : 0 : load_memoize(UnpicklerObject *self)
6402 : : {
6403 : : PyObject *value;
6404 : :
6405 [ # # ]: 0 : if (Py_SIZE(self->stack) <= self->stack->fence)
6406 : 0 : return Pdata_stack_underflow(self->stack);
6407 : 0 : value = self->stack->data[Py_SIZE(self->stack) - 1];
6408 : :
6409 : 0 : return _Unpickler_MemoPut(self, self->memo_len, value);
6410 : : }
6411 : :
6412 : : static int
6413 : 0 : do_append(UnpicklerObject *self, Py_ssize_t x)
6414 : : {
6415 : : PyObject *value;
6416 : : PyObject *slice;
6417 : : PyObject *list;
6418 : : PyObject *result;
6419 : : Py_ssize_t len, i;
6420 : :
6421 : 0 : len = Py_SIZE(self->stack);
6422 [ # # # # ]: 0 : if (x > len || x <= self->stack->fence)
6423 : 0 : return Pdata_stack_underflow(self->stack);
6424 [ # # ]: 0 : if (len == x) /* nothing to do */
6425 : 0 : return 0;
6426 : :
6427 : 0 : list = self->stack->data[x - 1];
6428 : :
6429 [ # # ]: 0 : if (PyList_CheckExact(list)) {
6430 : : Py_ssize_t list_len;
6431 : : int ret;
6432 : :
6433 : 0 : slice = Pdata_poplist(self->stack, x);
6434 [ # # ]: 0 : if (!slice)
6435 : 0 : return -1;
6436 : 0 : list_len = PyList_GET_SIZE(list);
6437 : 0 : ret = PyList_SetSlice(list, list_len, list_len, slice);
6438 : 0 : Py_DECREF(slice);
6439 : 0 : return ret;
6440 : : }
6441 : : else {
6442 : : PyObject *extend_func;
6443 : :
6444 [ # # ]: 0 : if (_PyObject_LookupAttr(list, &_Py_ID(extend), &extend_func) < 0) {
6445 : 0 : return -1;
6446 : : }
6447 [ # # ]: 0 : if (extend_func != NULL) {
6448 : 0 : slice = Pdata_poplist(self->stack, x);
6449 [ # # ]: 0 : if (!slice) {
6450 : 0 : Py_DECREF(extend_func);
6451 : 0 : return -1;
6452 : : }
6453 : 0 : result = _Pickle_FastCall(extend_func, slice);
6454 : 0 : Py_DECREF(extend_func);
6455 [ # # ]: 0 : if (result == NULL)
6456 : 0 : return -1;
6457 : 0 : Py_DECREF(result);
6458 : : }
6459 : : else {
6460 : : PyObject *append_func;
6461 : :
6462 : : /* Even if the PEP 307 requires extend() and append() methods,
6463 : : fall back on append() if the object has no extend() method
6464 : : for backward compatibility. */
6465 : 0 : append_func = PyObject_GetAttr(list, &_Py_ID(append));
6466 [ # # ]: 0 : if (append_func == NULL)
6467 : 0 : return -1;
6468 [ # # ]: 0 : for (i = x; i < len; i++) {
6469 : 0 : value = self->stack->data[i];
6470 : 0 : result = _Pickle_FastCall(append_func, value);
6471 [ # # ]: 0 : if (result == NULL) {
6472 : 0 : Pdata_clear(self->stack, i + 1);
6473 : 0 : Py_SET_SIZE(self->stack, x);
6474 : 0 : Py_DECREF(append_func);
6475 : 0 : return -1;
6476 : : }
6477 : 0 : Py_DECREF(result);
6478 : : }
6479 : 0 : Py_SET_SIZE(self->stack, x);
6480 : 0 : Py_DECREF(append_func);
6481 : : }
6482 : : }
6483 : :
6484 : 0 : return 0;
6485 : : }
6486 : :
6487 : : static int
6488 : 0 : load_append(UnpicklerObject *self)
6489 : : {
6490 [ # # ]: 0 : if (Py_SIZE(self->stack) - 1 <= self->stack->fence)
6491 : 0 : return Pdata_stack_underflow(self->stack);
6492 : 0 : return do_append(self, Py_SIZE(self->stack) - 1);
6493 : : }
6494 : :
6495 : : static int
6496 : 0 : load_appends(UnpicklerObject *self)
6497 : : {
6498 : 0 : Py_ssize_t i = marker(self);
6499 [ # # ]: 0 : if (i < 0)
6500 : 0 : return -1;
6501 : 0 : return do_append(self, i);
6502 : : }
6503 : :
6504 : : static int
6505 : 0 : do_setitems(UnpicklerObject *self, Py_ssize_t x)
6506 : : {
6507 : : PyObject *value, *key;
6508 : : PyObject *dict;
6509 : : Py_ssize_t len, i;
6510 : 0 : int status = 0;
6511 : :
6512 : 0 : len = Py_SIZE(self->stack);
6513 [ # # # # ]: 0 : if (x > len || x <= self->stack->fence)
6514 : 0 : return Pdata_stack_underflow(self->stack);
6515 [ # # ]: 0 : if (len == x) /* nothing to do */
6516 : 0 : return 0;
6517 [ # # ]: 0 : if ((len - x) % 2 != 0) {
6518 : 0 : PickleState *st = _Pickle_GetGlobalState();
6519 : : /* Corrupt or hostile pickle -- we never write one like this. */
6520 : 0 : PyErr_SetString(st->UnpicklingError,
6521 : : "odd number of items for SETITEMS");
6522 : 0 : return -1;
6523 : : }
6524 : :
6525 : : /* Here, dict does not actually need to be a PyDict; it could be anything
6526 : : that supports the __setitem__ attribute. */
6527 : 0 : dict = self->stack->data[x - 1];
6528 : :
6529 [ # # ]: 0 : for (i = x + 1; i < len; i += 2) {
6530 : 0 : key = self->stack->data[i - 1];
6531 : 0 : value = self->stack->data[i];
6532 [ # # ]: 0 : if (PyObject_SetItem(dict, key, value) < 0) {
6533 : 0 : status = -1;
6534 : 0 : break;
6535 : : }
6536 : : }
6537 : :
6538 : 0 : Pdata_clear(self->stack, x);
6539 : 0 : return status;
6540 : : }
6541 : :
6542 : : static int
6543 : 0 : load_setitem(UnpicklerObject *self)
6544 : : {
6545 : 0 : return do_setitems(self, Py_SIZE(self->stack) - 2);
6546 : : }
6547 : :
6548 : : static int
6549 : 0 : load_setitems(UnpicklerObject *self)
6550 : : {
6551 : 0 : Py_ssize_t i = marker(self);
6552 [ # # ]: 0 : if (i < 0)
6553 : 0 : return -1;
6554 : 0 : return do_setitems(self, i);
6555 : : }
6556 : :
6557 : : static int
6558 : 0 : load_additems(UnpicklerObject *self)
6559 : : {
6560 : : PyObject *set;
6561 : : Py_ssize_t mark, len, i;
6562 : :
6563 : 0 : mark = marker(self);
6564 [ # # ]: 0 : if (mark < 0)
6565 : 0 : return -1;
6566 : 0 : len = Py_SIZE(self->stack);
6567 [ # # # # ]: 0 : if (mark > len || mark <= self->stack->fence)
6568 : 0 : return Pdata_stack_underflow(self->stack);
6569 [ # # ]: 0 : if (len == mark) /* nothing to do */
6570 : 0 : return 0;
6571 : :
6572 : 0 : set = self->stack->data[mark - 1];
6573 : :
6574 [ # # # # ]: 0 : if (PySet_Check(set)) {
6575 : : PyObject *items;
6576 : : int status;
6577 : :
6578 : 0 : items = Pdata_poptuple(self->stack, mark);
6579 [ # # ]: 0 : if (items == NULL)
6580 : 0 : return -1;
6581 : :
6582 : 0 : status = _PySet_Update(set, items);
6583 : 0 : Py_DECREF(items);
6584 : 0 : return status;
6585 : : }
6586 : : else {
6587 : : PyObject *add_func;
6588 : :
6589 : 0 : add_func = PyObject_GetAttr(set, &_Py_ID(add));
6590 [ # # ]: 0 : if (add_func == NULL)
6591 : 0 : return -1;
6592 [ # # ]: 0 : for (i = mark; i < len; i++) {
6593 : : PyObject *result;
6594 : : PyObject *item;
6595 : :
6596 : 0 : item = self->stack->data[i];
6597 : 0 : result = _Pickle_FastCall(add_func, item);
6598 [ # # ]: 0 : if (result == NULL) {
6599 : 0 : Pdata_clear(self->stack, i + 1);
6600 : 0 : Py_SET_SIZE(self->stack, mark);
6601 : 0 : return -1;
6602 : : }
6603 : 0 : Py_DECREF(result);
6604 : : }
6605 : 0 : Py_SET_SIZE(self->stack, mark);
6606 : : }
6607 : :
6608 : 0 : return 0;
6609 : : }
6610 : :
6611 : : static int
6612 : 0 : load_build(UnpicklerObject *self)
6613 : : {
6614 : : PyObject *state, *inst, *slotstate;
6615 : : PyObject *setstate;
6616 : 0 : int status = 0;
6617 : :
6618 : : /* Stack is ... instance, state. We want to leave instance at
6619 : : * the stack top, possibly mutated via instance.__setstate__(state).
6620 : : */
6621 [ # # ]: 0 : if (Py_SIZE(self->stack) - 2 < self->stack->fence)
6622 : 0 : return Pdata_stack_underflow(self->stack);
6623 : :
6624 : 0 : PDATA_POP(self->stack, state);
6625 [ # # ]: 0 : if (state == NULL)
6626 : 0 : return -1;
6627 : :
6628 : 0 : inst = self->stack->data[Py_SIZE(self->stack) - 1];
6629 : :
6630 [ # # ]: 0 : if (_PyObject_LookupAttr(inst, &_Py_ID(__setstate__), &setstate) < 0) {
6631 : 0 : Py_DECREF(state);
6632 : 0 : return -1;
6633 : : }
6634 [ # # ]: 0 : if (setstate != NULL) {
6635 : : PyObject *result;
6636 : :
6637 : : /* The explicit __setstate__ is responsible for everything. */
6638 : 0 : result = _Pickle_FastCall(setstate, state);
6639 : 0 : Py_DECREF(setstate);
6640 [ # # ]: 0 : if (result == NULL)
6641 : 0 : return -1;
6642 : 0 : Py_DECREF(result);
6643 : 0 : return 0;
6644 : : }
6645 : :
6646 : : /* A default __setstate__. First see whether state embeds a
6647 : : * slot state dict too (a proto 2 addition).
6648 : : */
6649 [ # # # # ]: 0 : if (PyTuple_Check(state) && PyTuple_GET_SIZE(state) == 2) {
6650 : 0 : PyObject *tmp = state;
6651 : :
6652 : 0 : state = PyTuple_GET_ITEM(tmp, 0);
6653 : 0 : slotstate = PyTuple_GET_ITEM(tmp, 1);
6654 : 0 : Py_INCREF(state);
6655 : 0 : Py_INCREF(slotstate);
6656 : 0 : Py_DECREF(tmp);
6657 : : }
6658 : : else
6659 : 0 : slotstate = NULL;
6660 : :
6661 : : /* Set inst.__dict__ from the state dict (if any). */
6662 [ # # ]: 0 : if (state != Py_None) {
6663 : : PyObject *dict;
6664 : : PyObject *d_key, *d_value;
6665 : : Py_ssize_t i;
6666 : :
6667 [ # # ]: 0 : if (!PyDict_Check(state)) {
6668 : 0 : PickleState *st = _Pickle_GetGlobalState();
6669 : 0 : PyErr_SetString(st->UnpicklingError, "state is not a dictionary");
6670 : 0 : goto error;
6671 : : }
6672 : 0 : dict = PyObject_GetAttr(inst, &_Py_ID(__dict__));
6673 [ # # ]: 0 : if (dict == NULL)
6674 : 0 : goto error;
6675 : :
6676 : 0 : i = 0;
6677 [ # # ]: 0 : while (PyDict_Next(state, &i, &d_key, &d_value)) {
6678 : : /* normally the keys for instance attributes are
6679 : : interned. we should try to do that here. */
6680 : 0 : Py_INCREF(d_key);
6681 [ # # ]: 0 : if (PyUnicode_CheckExact(d_key))
6682 : 0 : PyUnicode_InternInPlace(&d_key);
6683 [ # # ]: 0 : if (PyObject_SetItem(dict, d_key, d_value) < 0) {
6684 : 0 : Py_DECREF(d_key);
6685 : 0 : goto error;
6686 : : }
6687 : 0 : Py_DECREF(d_key);
6688 : : }
6689 : 0 : Py_DECREF(dict);
6690 : : }
6691 : :
6692 : : /* Also set instance attributes from the slotstate dict (if any). */
6693 [ # # ]: 0 : if (slotstate != NULL) {
6694 : : PyObject *d_key, *d_value;
6695 : : Py_ssize_t i;
6696 : :
6697 [ # # ]: 0 : if (!PyDict_Check(slotstate)) {
6698 : 0 : PickleState *st = _Pickle_GetGlobalState();
6699 : 0 : PyErr_SetString(st->UnpicklingError,
6700 : : "slot state is not a dictionary");
6701 : 0 : goto error;
6702 : : }
6703 : 0 : i = 0;
6704 [ # # ]: 0 : while (PyDict_Next(slotstate, &i, &d_key, &d_value)) {
6705 [ # # ]: 0 : if (PyObject_SetAttr(inst, d_key, d_value) < 0)
6706 : 0 : goto error;
6707 : : }
6708 : : }
6709 : :
6710 : : if (0) {
6711 : 0 : error:
6712 : 0 : status = -1;
6713 : : }
6714 : :
6715 : 0 : Py_DECREF(state);
6716 : 0 : Py_XDECREF(slotstate);
6717 : 0 : return status;
6718 : : }
6719 : :
6720 : : static int
6721 : 0 : load_mark(UnpicklerObject *self)
6722 : : {
6723 : :
6724 : : /* Note that we split the (pickle.py) stack into two stacks, an
6725 : : * object stack and a mark stack. Here we push a mark onto the
6726 : : * mark stack.
6727 : : */
6728 : :
6729 [ # # ]: 0 : if (self->num_marks >= self->marks_size) {
6730 : 0 : size_t alloc = ((size_t)self->num_marks << 1) + 20;
6731 : 0 : Py_ssize_t *marks_new = self->marks;
6732 [ # # ]: 0 : PyMem_RESIZE(marks_new, Py_ssize_t, alloc);
6733 [ # # ]: 0 : if (marks_new == NULL) {
6734 : 0 : PyErr_NoMemory();
6735 : 0 : return -1;
6736 : : }
6737 : 0 : self->marks = marks_new;
6738 : 0 : self->marks_size = (Py_ssize_t)alloc;
6739 : : }
6740 : :
6741 : 0 : self->stack->mark_set = 1;
6742 : 0 : self->marks[self->num_marks++] = self->stack->fence = Py_SIZE(self->stack);
6743 : :
6744 : 0 : return 0;
6745 : : }
6746 : :
6747 : : static int
6748 : 0 : load_reduce(UnpicklerObject *self)
6749 : : {
6750 : 0 : PyObject *callable = NULL;
6751 : 0 : PyObject *argtup = NULL;
6752 : 0 : PyObject *obj = NULL;
6753 : :
6754 : 0 : PDATA_POP(self->stack, argtup);
6755 [ # # ]: 0 : if (argtup == NULL)
6756 : 0 : return -1;
6757 : 0 : PDATA_POP(self->stack, callable);
6758 [ # # ]: 0 : if (callable) {
6759 : 0 : obj = PyObject_CallObject(callable, argtup);
6760 : 0 : Py_DECREF(callable);
6761 : : }
6762 : 0 : Py_DECREF(argtup);
6763 : :
6764 [ # # ]: 0 : if (obj == NULL)
6765 : 0 : return -1;
6766 : :
6767 [ # # ]: 0 : PDATA_PUSH(self->stack, obj, -1);
6768 : 0 : return 0;
6769 : : }
6770 : :
6771 : : /* Just raises an error if we don't know the protocol specified. PROTO
6772 : : * is the first opcode for protocols >= 2.
6773 : : */
6774 : : static int
6775 : 0 : load_proto(UnpicklerObject *self)
6776 : : {
6777 : : char *s;
6778 : : int i;
6779 : :
6780 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 1) < 0)
6781 : 0 : return -1;
6782 : :
6783 : 0 : i = (unsigned char)s[0];
6784 [ # # ]: 0 : if (i <= HIGHEST_PROTOCOL) {
6785 : 0 : self->proto = i;
6786 : 0 : return 0;
6787 : : }
6788 : :
6789 : 0 : PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
6790 : 0 : return -1;
6791 : : }
6792 : :
6793 : : static int
6794 : 0 : load_frame(UnpicklerObject *self)
6795 : : {
6796 : : char *s;
6797 : : Py_ssize_t frame_len;
6798 : :
6799 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 8) < 0)
6800 : 0 : return -1;
6801 : :
6802 : 0 : frame_len = calc_binsize(s, 8);
6803 [ # # ]: 0 : if (frame_len < 0) {
6804 : 0 : PyErr_Format(PyExc_OverflowError,
6805 : : "FRAME length exceeds system's maximum of %zd bytes",
6806 : : PY_SSIZE_T_MAX);
6807 : 0 : return -1;
6808 : : }
6809 : :
6810 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, frame_len) < 0)
6811 : 0 : return -1;
6812 : :
6813 : : /* Rewind to start of frame */
6814 : 0 : self->next_read_idx -= frame_len;
6815 : 0 : return 0;
6816 : : }
6817 : :
6818 : : static PyObject *
6819 : 0 : load(UnpicklerObject *self)
6820 : : {
6821 : 0 : PyObject *value = NULL;
6822 : 0 : char *s = NULL;
6823 : :
6824 : 0 : self->num_marks = 0;
6825 : 0 : self->stack->mark_set = 0;
6826 : 0 : self->stack->fence = 0;
6827 : 0 : self->proto = 0;
6828 [ # # ]: 0 : if (Py_SIZE(self->stack))
6829 : 0 : Pdata_clear(self->stack, 0);
6830 : :
6831 : : /* Convenient macros for the dispatch while-switch loop just below. */
6832 : : #define OP(opcode, load_func) \
6833 : : case opcode: if (load_func(self) < 0) break; continue;
6834 : :
6835 : : #define OP_ARG(opcode, load_func, arg) \
6836 : : case opcode: if (load_func(self, (arg)) < 0) break; continue;
6837 : :
6838 : : while (1) {
6839 [ # # # # ]: 0 : if (_Unpickler_Read(self, &s, 1) < 0) {
6840 : 0 : PickleState *st = _Pickle_GetGlobalState();
6841 [ # # ]: 0 : if (PyErr_ExceptionMatches(st->UnpicklingError)) {
6842 : 0 : PyErr_Format(PyExc_EOFError, "Ran out of input");
6843 : : }
6844 : 0 : return NULL;
6845 : : }
6846 : :
6847 [ # # # # : 0 : switch ((enum opcode)s[0]) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
6848 [ # # ]: 0 : OP(NONE, load_none)
6849 [ # # ]: 0 : OP(BININT, load_binint)
6850 [ # # ]: 0 : OP(BININT1, load_binint1)
6851 [ # # ]: 0 : OP(BININT2, load_binint2)
6852 [ # # ]: 0 : OP(INT, load_int)
6853 [ # # ]: 0 : OP(LONG, load_long)
6854 [ # # ]: 0 : OP_ARG(LONG1, load_counted_long, 1)
6855 [ # # ]: 0 : OP_ARG(LONG4, load_counted_long, 4)
6856 [ # # ]: 0 : OP(FLOAT, load_float)
6857 [ # # ]: 0 : OP(BINFLOAT, load_binfloat)
6858 [ # # ]: 0 : OP_ARG(SHORT_BINBYTES, load_counted_binbytes, 1)
6859 [ # # ]: 0 : OP_ARG(BINBYTES, load_counted_binbytes, 4)
6860 [ # # ]: 0 : OP_ARG(BINBYTES8, load_counted_binbytes, 8)
6861 [ # # ]: 0 : OP(BYTEARRAY8, load_counted_bytearray)
6862 [ # # ]: 0 : OP(NEXT_BUFFER, load_next_buffer)
6863 [ # # ]: 0 : OP(READONLY_BUFFER, load_readonly_buffer)
6864 [ # # ]: 0 : OP_ARG(SHORT_BINSTRING, load_counted_binstring, 1)
6865 [ # # ]: 0 : OP_ARG(BINSTRING, load_counted_binstring, 4)
6866 [ # # ]: 0 : OP(STRING, load_string)
6867 [ # # ]: 0 : OP(UNICODE, load_unicode)
6868 [ # # ]: 0 : OP_ARG(SHORT_BINUNICODE, load_counted_binunicode, 1)
6869 [ # # ]: 0 : OP_ARG(BINUNICODE, load_counted_binunicode, 4)
6870 [ # # ]: 0 : OP_ARG(BINUNICODE8, load_counted_binunicode, 8)
6871 [ # # ]: 0 : OP_ARG(EMPTY_TUPLE, load_counted_tuple, 0)
6872 [ # # ]: 0 : OP_ARG(TUPLE1, load_counted_tuple, 1)
6873 [ # # ]: 0 : OP_ARG(TUPLE2, load_counted_tuple, 2)
6874 [ # # ]: 0 : OP_ARG(TUPLE3, load_counted_tuple, 3)
6875 [ # # ]: 0 : OP(TUPLE, load_tuple)
6876 [ # # ]: 0 : OP(EMPTY_LIST, load_empty_list)
6877 [ # # ]: 0 : OP(LIST, load_list)
6878 [ # # ]: 0 : OP(EMPTY_DICT, load_empty_dict)
6879 [ # # ]: 0 : OP(DICT, load_dict)
6880 [ # # ]: 0 : OP(EMPTY_SET, load_empty_set)
6881 [ # # ]: 0 : OP(ADDITEMS, load_additems)
6882 [ # # ]: 0 : OP(FROZENSET, load_frozenset)
6883 [ # # ]: 0 : OP(OBJ, load_obj)
6884 [ # # ]: 0 : OP(INST, load_inst)
6885 [ # # ]: 0 : OP_ARG(NEWOBJ, load_newobj, 0)
6886 [ # # ]: 0 : OP_ARG(NEWOBJ_EX, load_newobj, 1)
6887 [ # # ]: 0 : OP(GLOBAL, load_global)
6888 [ # # ]: 0 : OP(STACK_GLOBAL, load_stack_global)
6889 [ # # ]: 0 : OP(APPEND, load_append)
6890 [ # # ]: 0 : OP(APPENDS, load_appends)
6891 [ # # ]: 0 : OP(BUILD, load_build)
6892 [ # # ]: 0 : OP(DUP, load_dup)
6893 [ # # ]: 0 : OP(BINGET, load_binget)
6894 [ # # ]: 0 : OP(LONG_BINGET, load_long_binget)
6895 [ # # ]: 0 : OP(GET, load_get)
6896 [ # # ]: 0 : OP(MARK, load_mark)
6897 [ # # ]: 0 : OP(BINPUT, load_binput)
6898 [ # # ]: 0 : OP(LONG_BINPUT, load_long_binput)
6899 [ # # ]: 0 : OP(PUT, load_put)
6900 [ # # ]: 0 : OP(MEMOIZE, load_memoize)
6901 [ # # ]: 0 : OP(POP, load_pop)
6902 [ # # ]: 0 : OP(POP_MARK, load_pop_mark)
6903 [ # # ]: 0 : OP(SETITEM, load_setitem)
6904 [ # # ]: 0 : OP(SETITEMS, load_setitems)
6905 [ # # ]: 0 : OP(PERSID, load_persid)
6906 [ # # ]: 0 : OP(BINPERSID, load_binpersid)
6907 [ # # ]: 0 : OP(REDUCE, load_reduce)
6908 [ # # ]: 0 : OP(PROTO, load_proto)
6909 [ # # ]: 0 : OP(FRAME, load_frame)
6910 [ # # ]: 0 : OP_ARG(EXT1, load_extension, 1)
6911 [ # # ]: 0 : OP_ARG(EXT2, load_extension, 2)
6912 [ # # ]: 0 : OP_ARG(EXT4, load_extension, 4)
6913 [ # # ]: 0 : OP_ARG(NEWTRUE, load_bool, Py_True)
6914 [ # # ]: 0 : OP_ARG(NEWFALSE, load_bool, Py_False)
6915 : :
6916 : 0 : case STOP:
6917 : 0 : break;
6918 : :
6919 : 0 : default:
6920 : : {
6921 : 0 : PickleState *st = _Pickle_GetGlobalState();
6922 : 0 : unsigned char c = (unsigned char) *s;
6923 [ # # # # : 0 : if (0x20 <= c && c <= 0x7e && c != '\'' && c != '\\') {
# # # # ]
6924 : 0 : PyErr_Format(st->UnpicklingError,
6925 : : "invalid load key, '%c'.", c);
6926 : : }
6927 : : else {
6928 : 0 : PyErr_Format(st->UnpicklingError,
6929 : : "invalid load key, '\\x%02x'.", c);
6930 : : }
6931 : 0 : return NULL;
6932 : : }
6933 : : }
6934 : :
6935 : 0 : break; /* and we are done! */
6936 : : }
6937 : :
6938 [ # # ]: 0 : if (PyErr_Occurred()) {
6939 : 0 : return NULL;
6940 : : }
6941 : :
6942 [ # # ]: 0 : if (_Unpickler_SkipConsumed(self) < 0)
6943 : 0 : return NULL;
6944 : :
6945 : 0 : PDATA_POP(self->stack, value);
6946 : 0 : return value;
6947 : : }
6948 : :
6949 : : /*[clinic input]
6950 : :
6951 : : _pickle.Unpickler.load
6952 : :
6953 : : Load a pickle.
6954 : :
6955 : : Read a pickled object representation from the open file object given
6956 : : in the constructor, and return the reconstituted object hierarchy
6957 : : specified therein.
6958 : : [clinic start generated code]*/
6959 : :
6960 : : static PyObject *
6961 : 0 : _pickle_Unpickler_load_impl(UnpicklerObject *self)
6962 : : /*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/
6963 : : {
6964 : 0 : UnpicklerObject *unpickler = (UnpicklerObject*)self;
6965 : :
6966 : : /* Check whether the Unpickler was initialized correctly. This prevents
6967 : : segfaulting if a subclass overridden __init__ with a function that does
6968 : : not call Unpickler.__init__(). Here, we simply ensure that self->read
6969 : : is not NULL. */
6970 [ # # ]: 0 : if (unpickler->read == NULL) {
6971 : 0 : PickleState *st = _Pickle_GetGlobalState();
6972 : 0 : PyErr_Format(st->UnpicklingError,
6973 : : "Unpickler.__init__() was not called by %s.__init__()",
6974 : 0 : Py_TYPE(unpickler)->tp_name);
6975 : 0 : return NULL;
6976 : : }
6977 : :
6978 : 0 : return load(unpickler);
6979 : : }
6980 : :
6981 : : /* The name of find_class() is misleading. In newer pickle protocols, this
6982 : : function is used for loading any global (i.e., functions), not just
6983 : : classes. The name is kept only for backward compatibility. */
6984 : :
6985 : : /*[clinic input]
6986 : :
6987 : : _pickle.Unpickler.find_class
6988 : :
6989 : : module_name: object
6990 : : global_name: object
6991 : : /
6992 : :
6993 : : Return an object from a specified module.
6994 : :
6995 : : If necessary, the module will be imported. Subclasses may override
6996 : : this method (e.g. to restrict unpickling of arbitrary classes and
6997 : : functions).
6998 : :
6999 : : This method is called whenever a class or a function object is
7000 : : needed. Both arguments passed are str objects.
7001 : : [clinic start generated code]*/
7002 : :
7003 : : static PyObject *
7004 : 0 : _pickle_Unpickler_find_class_impl(UnpicklerObject *self,
7005 : : PyObject *module_name,
7006 : : PyObject *global_name)
7007 : : /*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/
7008 : : {
7009 : : PyObject *global;
7010 : : PyObject *module;
7011 : :
7012 [ # # ]: 0 : if (PySys_Audit("pickle.find_class", "OO",
7013 : : module_name, global_name) < 0) {
7014 : 0 : return NULL;
7015 : : }
7016 : :
7017 : : /* Try to map the old names used in Python 2.x to the new ones used in
7018 : : Python 3.x. We do this only with old pickle protocols and when the
7019 : : user has not disabled the feature. */
7020 [ # # # # ]: 0 : if (self->proto < 3 && self->fix_imports) {
7021 : : PyObject *key;
7022 : : PyObject *item;
7023 : 0 : PickleState *st = _Pickle_GetGlobalState();
7024 : :
7025 : : /* Check if the global (i.e., a function or a class) was renamed
7026 : : or moved to another module. */
7027 : 0 : key = PyTuple_Pack(2, module_name, global_name);
7028 [ # # ]: 0 : if (key == NULL)
7029 : 0 : return NULL;
7030 : 0 : item = PyDict_GetItemWithError(st->name_mapping_2to3, key);
7031 : 0 : Py_DECREF(key);
7032 [ # # ]: 0 : if (item) {
7033 [ # # # # ]: 0 : if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) {
7034 : 0 : PyErr_Format(PyExc_RuntimeError,
7035 : : "_compat_pickle.NAME_MAPPING values should be "
7036 : 0 : "2-tuples, not %.200s", Py_TYPE(item)->tp_name);
7037 : 0 : return NULL;
7038 : : }
7039 : 0 : module_name = PyTuple_GET_ITEM(item, 0);
7040 : 0 : global_name = PyTuple_GET_ITEM(item, 1);
7041 [ # # # # ]: 0 : if (!PyUnicode_Check(module_name) ||
7042 : 0 : !PyUnicode_Check(global_name)) {
7043 : 0 : PyErr_Format(PyExc_RuntimeError,
7044 : : "_compat_pickle.NAME_MAPPING values should be "
7045 : : "pairs of str, not (%.200s, %.200s)",
7046 : 0 : Py_TYPE(module_name)->tp_name,
7047 : 0 : Py_TYPE(global_name)->tp_name);
7048 : 0 : return NULL;
7049 : : }
7050 : : }
7051 [ # # ]: 0 : else if (PyErr_Occurred()) {
7052 : 0 : return NULL;
7053 : : }
7054 : : else {
7055 : : /* Check if the module was renamed. */
7056 : 0 : item = PyDict_GetItemWithError(st->import_mapping_2to3, module_name);
7057 [ # # ]: 0 : if (item) {
7058 [ # # ]: 0 : if (!PyUnicode_Check(item)) {
7059 : 0 : PyErr_Format(PyExc_RuntimeError,
7060 : : "_compat_pickle.IMPORT_MAPPING values should be "
7061 : 0 : "strings, not %.200s", Py_TYPE(item)->tp_name);
7062 : 0 : return NULL;
7063 : : }
7064 : 0 : module_name = item;
7065 : : }
7066 [ # # ]: 0 : else if (PyErr_Occurred()) {
7067 : 0 : return NULL;
7068 : : }
7069 : : }
7070 : : }
7071 : :
7072 : : /*
7073 : : * we don't use PyImport_GetModule here, because it can return partially-
7074 : : * initialised modules, which then cause the getattribute to fail.
7075 : : */
7076 : 0 : module = PyImport_Import(module_name);
7077 [ # # ]: 0 : if (module == NULL) {
7078 : 0 : return NULL;
7079 : : }
7080 : 0 : global = getattribute(module, global_name, self->proto >= 4);
7081 : 0 : Py_DECREF(module);
7082 : 0 : return global;
7083 : : }
7084 : :
7085 : : /*[clinic input]
7086 : :
7087 : : _pickle.Unpickler.__sizeof__ -> size_t
7088 : :
7089 : : Returns size in memory, in bytes.
7090 : : [clinic start generated code]*/
7091 : :
7092 : : static size_t
7093 : 0 : _pickle_Unpickler___sizeof___impl(UnpicklerObject *self)
7094 : : /*[clinic end generated code: output=4648d84c228196df input=27180b2b6b524012]*/
7095 : : {
7096 : 0 : size_t res = _PyObject_SIZE(Py_TYPE(self));
7097 [ # # ]: 0 : if (self->memo != NULL)
7098 : 0 : res += self->memo_size * sizeof(PyObject *);
7099 [ # # ]: 0 : if (self->marks != NULL)
7100 : 0 : res += (size_t)self->marks_size * sizeof(Py_ssize_t);
7101 [ # # ]: 0 : if (self->input_line != NULL)
7102 : 0 : res += strlen(self->input_line) + 1;
7103 [ # # ]: 0 : if (self->encoding != NULL)
7104 : 0 : res += strlen(self->encoding) + 1;
7105 [ # # ]: 0 : if (self->errors != NULL)
7106 : 0 : res += strlen(self->errors) + 1;
7107 : 0 : return res;
7108 : : }
7109 : :
7110 : : static struct PyMethodDef Unpickler_methods[] = {
7111 : : _PICKLE_UNPICKLER_LOAD_METHODDEF
7112 : : _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF
7113 : : _PICKLE_UNPICKLER___SIZEOF___METHODDEF
7114 : : {NULL, NULL} /* sentinel */
7115 : : };
7116 : :
7117 : : static void
7118 : 0 : Unpickler_dealloc(UnpicklerObject *self)
7119 : : {
7120 : 0 : PyObject_GC_UnTrack((PyObject *)self);
7121 : 0 : Py_XDECREF(self->readline);
7122 : 0 : Py_XDECREF(self->readinto);
7123 : 0 : Py_XDECREF(self->read);
7124 : 0 : Py_XDECREF(self->peek);
7125 : 0 : Py_XDECREF(self->stack);
7126 : 0 : Py_XDECREF(self->pers_func);
7127 : 0 : Py_XDECREF(self->buffers);
7128 [ # # ]: 0 : if (self->buffer.buf != NULL) {
7129 : 0 : PyBuffer_Release(&self->buffer);
7130 : 0 : self->buffer.buf = NULL;
7131 : : }
7132 : :
7133 : 0 : _Unpickler_MemoCleanup(self);
7134 : 0 : PyMem_Free(self->marks);
7135 : 0 : PyMem_Free(self->input_line);
7136 : 0 : PyMem_Free(self->encoding);
7137 : 0 : PyMem_Free(self->errors);
7138 : :
7139 : 0 : Py_TYPE(self)->tp_free((PyObject *)self);
7140 : 0 : }
7141 : :
7142 : : static int
7143 : 0 : Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg)
7144 : : {
7145 [ # # # # ]: 0 : Py_VISIT(self->readline);
7146 [ # # # # ]: 0 : Py_VISIT(self->readinto);
7147 [ # # # # ]: 0 : Py_VISIT(self->read);
7148 [ # # # # ]: 0 : Py_VISIT(self->peek);
7149 [ # # # # ]: 0 : Py_VISIT(self->stack);
7150 [ # # # # ]: 0 : Py_VISIT(self->pers_func);
7151 [ # # # # ]: 0 : Py_VISIT(self->buffers);
7152 : 0 : return 0;
7153 : : }
7154 : :
7155 : : static int
7156 : 0 : Unpickler_clear(UnpicklerObject *self)
7157 : : {
7158 [ # # ]: 0 : Py_CLEAR(self->readline);
7159 [ # # ]: 0 : Py_CLEAR(self->readinto);
7160 [ # # ]: 0 : Py_CLEAR(self->read);
7161 [ # # ]: 0 : Py_CLEAR(self->peek);
7162 [ # # ]: 0 : Py_CLEAR(self->stack);
7163 [ # # ]: 0 : Py_CLEAR(self->pers_func);
7164 [ # # ]: 0 : Py_CLEAR(self->buffers);
7165 [ # # ]: 0 : if (self->buffer.buf != NULL) {
7166 : 0 : PyBuffer_Release(&self->buffer);
7167 : 0 : self->buffer.buf = NULL;
7168 : : }
7169 : :
7170 : 0 : _Unpickler_MemoCleanup(self);
7171 : 0 : PyMem_Free(self->marks);
7172 : 0 : self->marks = NULL;
7173 : 0 : PyMem_Free(self->input_line);
7174 : 0 : self->input_line = NULL;
7175 : 0 : PyMem_Free(self->encoding);
7176 : 0 : self->encoding = NULL;
7177 : 0 : PyMem_Free(self->errors);
7178 : 0 : self->errors = NULL;
7179 : :
7180 : 0 : return 0;
7181 : : }
7182 : :
7183 : : /*[clinic input]
7184 : :
7185 : : _pickle.Unpickler.__init__
7186 : :
7187 : : file: object
7188 : : *
7189 : : fix_imports: bool = True
7190 : : encoding: str = 'ASCII'
7191 : : errors: str = 'strict'
7192 : : buffers: object(c_default="NULL") = ()
7193 : :
7194 : : This takes a binary file for reading a pickle data stream.
7195 : :
7196 : : The protocol version of the pickle is detected automatically, so no
7197 : : protocol argument is needed. Bytes past the pickled object's
7198 : : representation are ignored.
7199 : :
7200 : : The argument *file* must have two methods, a read() method that takes
7201 : : an integer argument, and a readline() method that requires no
7202 : : arguments. Both methods should return bytes. Thus *file* can be a
7203 : : binary file object opened for reading, an io.BytesIO object, or any
7204 : : other custom object that meets this interface.
7205 : :
7206 : : Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
7207 : : which are used to control compatibility support for pickle stream
7208 : : generated by Python 2. If *fix_imports* is True, pickle will try to
7209 : : map the old Python 2 names to the new names used in Python 3. The
7210 : : *encoding* and *errors* tell pickle how to decode 8-bit string
7211 : : instances pickled by Python 2; these default to 'ASCII' and 'strict',
7212 : : respectively. The *encoding* can be 'bytes' to read these 8-bit
7213 : : string instances as bytes objects.
7214 : : [clinic start generated code]*/
7215 : :
7216 : : static int
7217 : 0 : _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file,
7218 : : int fix_imports, const char *encoding,
7219 : : const char *errors, PyObject *buffers)
7220 : : /*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/
7221 : : {
7222 : : /* In case of multiple __init__() calls, clear previous content. */
7223 [ # # ]: 0 : if (self->read != NULL)
7224 : 0 : (void)Unpickler_clear(self);
7225 : :
7226 [ # # ]: 0 : if (_Unpickler_SetInputStream(self, file) < 0)
7227 : 0 : return -1;
7228 : :
7229 [ # # ]: 0 : if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0)
7230 : 0 : return -1;
7231 : :
7232 [ # # ]: 0 : if (_Unpickler_SetBuffers(self, buffers) < 0)
7233 : 0 : return -1;
7234 : :
7235 : 0 : self->fix_imports = fix_imports;
7236 : :
7237 [ # # ]: 0 : if (init_method_ref((PyObject *)self, &_Py_ID(persistent_load),
7238 : : &self->pers_func, &self->pers_func_self) < 0)
7239 : : {
7240 : 0 : return -1;
7241 : : }
7242 : :
7243 : 0 : self->stack = (Pdata *)Pdata_New();
7244 [ # # ]: 0 : if (self->stack == NULL)
7245 : 0 : return -1;
7246 : :
7247 : 0 : self->memo_size = 32;
7248 : 0 : self->memo = _Unpickler_NewMemo(self->memo_size);
7249 [ # # ]: 0 : if (self->memo == NULL)
7250 : 0 : return -1;
7251 : :
7252 : 0 : self->proto = 0;
7253 : :
7254 : 0 : return 0;
7255 : : }
7256 : :
7257 : :
7258 : : /* Define a proxy object for the Unpickler's internal memo object. This is to
7259 : : * avoid breaking code like:
7260 : : * unpickler.memo.clear()
7261 : : * and
7262 : : * unpickler.memo = saved_memo
7263 : : * Is this a good idea? Not really, but we don't want to break code that uses
7264 : : * it. Note that we don't implement the entire mapping API here. This is
7265 : : * intentional, as these should be treated as black-box implementation details.
7266 : : *
7267 : : * We do, however, have to implement pickling/unpickling support because of
7268 : : * real-world code like cvs2svn.
7269 : : */
7270 : :
7271 : : /*[clinic input]
7272 : : _pickle.UnpicklerMemoProxy.clear
7273 : :
7274 : : Remove all items from memo.
7275 : : [clinic start generated code]*/
7276 : :
7277 : : static PyObject *
7278 : 0 : _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self)
7279 : : /*[clinic end generated code: output=d20cd43f4ba1fb1f input=b1df7c52e7afd9bd]*/
7280 : : {
7281 : 0 : _Unpickler_MemoCleanup(self->unpickler);
7282 : 0 : self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
7283 [ # # ]: 0 : if (self->unpickler->memo == NULL)
7284 : 0 : return NULL;
7285 : 0 : Py_RETURN_NONE;
7286 : : }
7287 : :
7288 : : /*[clinic input]
7289 : : _pickle.UnpicklerMemoProxy.copy
7290 : :
7291 : : Copy the memo to a new object.
7292 : : [clinic start generated code]*/
7293 : :
7294 : : static PyObject *
7295 : 0 : _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self)
7296 : : /*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/
7297 : : {
7298 : : size_t i;
7299 : 0 : PyObject *new_memo = PyDict_New();
7300 [ # # ]: 0 : if (new_memo == NULL)
7301 : 0 : return NULL;
7302 : :
7303 [ # # ]: 0 : for (i = 0; i < self->unpickler->memo_size; i++) {
7304 : : int status;
7305 : : PyObject *key, *value;
7306 : :
7307 : 0 : value = self->unpickler->memo[i];
7308 [ # # ]: 0 : if (value == NULL)
7309 : 0 : continue;
7310 : :
7311 : 0 : key = PyLong_FromSsize_t(i);
7312 [ # # ]: 0 : if (key == NULL)
7313 : 0 : goto error;
7314 : 0 : status = PyDict_SetItem(new_memo, key, value);
7315 : 0 : Py_DECREF(key);
7316 [ # # ]: 0 : if (status < 0)
7317 : 0 : goto error;
7318 : : }
7319 : 0 : return new_memo;
7320 : :
7321 : 0 : error:
7322 : 0 : Py_DECREF(new_memo);
7323 : 0 : return NULL;
7324 : : }
7325 : :
7326 : : /*[clinic input]
7327 : : _pickle.UnpicklerMemoProxy.__reduce__
7328 : :
7329 : : Implement pickling support.
7330 : : [clinic start generated code]*/
7331 : :
7332 : : static PyObject *
7333 : 0 : _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self)
7334 : : /*[clinic end generated code: output=6da34ac048d94cca input=6920862413407199]*/
7335 : : {
7336 : : PyObject *reduce_value;
7337 : : PyObject *constructor_args;
7338 : 0 : PyObject *contents = _pickle_UnpicklerMemoProxy_copy_impl(self);
7339 [ # # ]: 0 : if (contents == NULL)
7340 : 0 : return NULL;
7341 : :
7342 : 0 : reduce_value = PyTuple_New(2);
7343 [ # # ]: 0 : if (reduce_value == NULL) {
7344 : 0 : Py_DECREF(contents);
7345 : 0 : return NULL;
7346 : : }
7347 : 0 : constructor_args = PyTuple_New(1);
7348 [ # # ]: 0 : if (constructor_args == NULL) {
7349 : 0 : Py_DECREF(contents);
7350 : 0 : Py_DECREF(reduce_value);
7351 : 0 : return NULL;
7352 : : }
7353 : 0 : PyTuple_SET_ITEM(constructor_args, 0, contents);
7354 : 0 : PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type));
7355 : 0 : PyTuple_SET_ITEM(reduce_value, 1, constructor_args);
7356 : 0 : return reduce_value;
7357 : : }
7358 : :
7359 : : static PyMethodDef unpicklerproxy_methods[] = {
7360 : : _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF
7361 : : _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF
7362 : : _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF
7363 : : {NULL, NULL} /* sentinel */
7364 : : };
7365 : :
7366 : : static void
7367 : 0 : UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self)
7368 : : {
7369 : 0 : PyObject_GC_UnTrack(self);
7370 : 0 : Py_XDECREF(self->unpickler);
7371 : 0 : PyObject_GC_Del((PyObject *)self);
7372 : 0 : }
7373 : :
7374 : : static int
7375 : 0 : UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self,
7376 : : visitproc visit, void *arg)
7377 : : {
7378 [ # # # # ]: 0 : Py_VISIT(self->unpickler);
7379 : 0 : return 0;
7380 : : }
7381 : :
7382 : : static int
7383 : 0 : UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self)
7384 : : {
7385 [ # # ]: 0 : Py_CLEAR(self->unpickler);
7386 : 0 : return 0;
7387 : : }
7388 : :
7389 : : static PyTypeObject UnpicklerMemoProxyType = {
7390 : : PyVarObject_HEAD_INIT(NULL, 0)
7391 : : "_pickle.UnpicklerMemoProxy", /*tp_name*/
7392 : : sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/
7393 : : 0,
7394 : : (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */
7395 : : 0, /* tp_vectorcall_offset */
7396 : : 0, /* tp_getattr */
7397 : : 0, /* tp_setattr */
7398 : : 0, /* tp_as_async */
7399 : : 0, /* tp_repr */
7400 : : 0, /* tp_as_number */
7401 : : 0, /* tp_as_sequence */
7402 : : 0, /* tp_as_mapping */
7403 : : PyObject_HashNotImplemented, /* tp_hash */
7404 : : 0, /* tp_call */
7405 : : 0, /* tp_str */
7406 : : PyObject_GenericGetAttr, /* tp_getattro */
7407 : : PyObject_GenericSetAttr, /* tp_setattro */
7408 : : 0, /* tp_as_buffer */
7409 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
7410 : : 0, /* tp_doc */
7411 : : (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */
7412 : : (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */
7413 : : 0, /* tp_richcompare */
7414 : : 0, /* tp_weaklistoffset */
7415 : : 0, /* tp_iter */
7416 : : 0, /* tp_iternext */
7417 : : unpicklerproxy_methods, /* tp_methods */
7418 : : };
7419 : :
7420 : : static PyObject *
7421 : 0 : UnpicklerMemoProxy_New(UnpicklerObject *unpickler)
7422 : : {
7423 : : UnpicklerMemoProxyObject *self;
7424 : :
7425 : 0 : self = PyObject_GC_New(UnpicklerMemoProxyObject,
7426 : : &UnpicklerMemoProxyType);
7427 [ # # ]: 0 : if (self == NULL)
7428 : 0 : return NULL;
7429 : 0 : self->unpickler = (UnpicklerObject*)Py_NewRef(unpickler);
7430 : 0 : PyObject_GC_Track(self);
7431 : 0 : return (PyObject *)self;
7432 : : }
7433 : :
7434 : : /*****************************************************************************/
7435 : :
7436 : :
7437 : : static PyObject *
7438 : 0 : Unpickler_get_memo(UnpicklerObject *self, void *Py_UNUSED(ignored))
7439 : : {
7440 : 0 : return UnpicklerMemoProxy_New(self);
7441 : : }
7442 : :
7443 : : static int
7444 : 0 : Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored))
7445 : : {
7446 : : PyObject **new_memo;
7447 : 0 : size_t new_memo_size = 0;
7448 : :
7449 [ # # ]: 0 : if (obj == NULL) {
7450 : 0 : PyErr_SetString(PyExc_TypeError,
7451 : : "attribute deletion is not supported");
7452 : 0 : return -1;
7453 : : }
7454 : :
7455 [ # # ]: 0 : if (Py_IS_TYPE(obj, &UnpicklerMemoProxyType)) {
7456 : 0 : UnpicklerObject *unpickler =
7457 : : ((UnpicklerMemoProxyObject *)obj)->unpickler;
7458 : :
7459 : 0 : new_memo_size = unpickler->memo_size;
7460 : 0 : new_memo = _Unpickler_NewMemo(new_memo_size);
7461 [ # # ]: 0 : if (new_memo == NULL)
7462 : 0 : return -1;
7463 : :
7464 [ # # ]: 0 : for (size_t i = 0; i < new_memo_size; i++) {
7465 : 0 : new_memo[i] = Py_XNewRef(unpickler->memo[i]);
7466 : : }
7467 : : }
7468 [ # # ]: 0 : else if (PyDict_Check(obj)) {
7469 : 0 : Py_ssize_t i = 0;
7470 : : PyObject *key, *value;
7471 : :
7472 : 0 : new_memo_size = PyDict_GET_SIZE(obj);
7473 : 0 : new_memo = _Unpickler_NewMemo(new_memo_size);
7474 [ # # ]: 0 : if (new_memo == NULL)
7475 : 0 : return -1;
7476 : :
7477 [ # # ]: 0 : while (PyDict_Next(obj, &i, &key, &value)) {
7478 : : Py_ssize_t idx;
7479 [ # # ]: 0 : if (!PyLong_Check(key)) {
7480 : 0 : PyErr_SetString(PyExc_TypeError,
7481 : : "memo key must be integers");
7482 : 0 : goto error;
7483 : : }
7484 : 0 : idx = PyLong_AsSsize_t(key);
7485 [ # # # # ]: 0 : if (idx == -1 && PyErr_Occurred())
7486 : 0 : goto error;
7487 [ # # ]: 0 : if (idx < 0) {
7488 : 0 : PyErr_SetString(PyExc_ValueError,
7489 : : "memo key must be positive integers.");
7490 : 0 : goto error;
7491 : : }
7492 [ # # ]: 0 : if (_Unpickler_MemoPut(self, idx, value) < 0)
7493 : 0 : goto error;
7494 : : }
7495 : : }
7496 : : else {
7497 : 0 : PyErr_Format(PyExc_TypeError,
7498 : : "'memo' attribute must be an UnpicklerMemoProxy object "
7499 : 0 : "or dict, not %.200s", Py_TYPE(obj)->tp_name);
7500 : 0 : return -1;
7501 : : }
7502 : :
7503 : 0 : _Unpickler_MemoCleanup(self);
7504 : 0 : self->memo_size = new_memo_size;
7505 : 0 : self->memo = new_memo;
7506 : :
7507 : 0 : return 0;
7508 : :
7509 : 0 : error:
7510 [ # # ]: 0 : if (new_memo_size) {
7511 [ # # ]: 0 : for (size_t i = new_memo_size - 1; i != SIZE_MAX; i--) {
7512 : 0 : Py_XDECREF(new_memo[i]);
7513 : : }
7514 : 0 : PyMem_Free(new_memo);
7515 : : }
7516 : 0 : return -1;
7517 : : }
7518 : :
7519 : : static PyObject *
7520 : 0 : Unpickler_get_persload(UnpicklerObject *self, void *Py_UNUSED(ignored))
7521 : : {
7522 [ # # ]: 0 : if (self->pers_func == NULL) {
7523 : 0 : PyErr_SetString(PyExc_AttributeError, "persistent_load");
7524 : 0 : return NULL;
7525 : : }
7526 : 0 : return reconstruct_method(self->pers_func, self->pers_func_self);
7527 : : }
7528 : :
7529 : : static int
7530 : 0 : Unpickler_set_persload(UnpicklerObject *self, PyObject *value, void *Py_UNUSED(ignored))
7531 : : {
7532 [ # # ]: 0 : if (value == NULL) {
7533 : 0 : PyErr_SetString(PyExc_TypeError,
7534 : : "attribute deletion is not supported");
7535 : 0 : return -1;
7536 : : }
7537 [ # # ]: 0 : if (!PyCallable_Check(value)) {
7538 : 0 : PyErr_SetString(PyExc_TypeError,
7539 : : "persistent_load must be a callable taking "
7540 : : "one argument");
7541 : 0 : return -1;
7542 : : }
7543 : :
7544 : 0 : self->pers_func_self = NULL;
7545 : 0 : Py_XSETREF(self->pers_func, Py_NewRef(value));
7546 : :
7547 : 0 : return 0;
7548 : : }
7549 : :
7550 : : static PyGetSetDef Unpickler_getsets[] = {
7551 : : {"memo", (getter)Unpickler_get_memo, (setter)Unpickler_set_memo},
7552 : : {"persistent_load", (getter)Unpickler_get_persload,
7553 : : (setter)Unpickler_set_persload},
7554 : : {NULL}
7555 : : };
7556 : :
7557 : : static PyTypeObject Unpickler_Type = {
7558 : : PyVarObject_HEAD_INIT(NULL, 0)
7559 : : "_pickle.Unpickler", /*tp_name*/
7560 : : sizeof(UnpicklerObject), /*tp_basicsize*/
7561 : : 0, /*tp_itemsize*/
7562 : : (destructor)Unpickler_dealloc, /*tp_dealloc*/
7563 : : 0, /*tp_vectorcall_offset*/
7564 : : 0, /*tp_getattr*/
7565 : : 0, /*tp_setattr*/
7566 : : 0, /*tp_as_async*/
7567 : : 0, /*tp_repr*/
7568 : : 0, /*tp_as_number*/
7569 : : 0, /*tp_as_sequence*/
7570 : : 0, /*tp_as_mapping*/
7571 : : 0, /*tp_hash*/
7572 : : 0, /*tp_call*/
7573 : : 0, /*tp_str*/
7574 : : 0, /*tp_getattro*/
7575 : : 0, /*tp_setattro*/
7576 : : 0, /*tp_as_buffer*/
7577 : : Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
7578 : : _pickle_Unpickler___init____doc__, /*tp_doc*/
7579 : : (traverseproc)Unpickler_traverse, /*tp_traverse*/
7580 : : (inquiry)Unpickler_clear, /*tp_clear*/
7581 : : 0, /*tp_richcompare*/
7582 : : 0, /*tp_weaklistoffset*/
7583 : : 0, /*tp_iter*/
7584 : : 0, /*tp_iternext*/
7585 : : Unpickler_methods, /*tp_methods*/
7586 : : 0, /*tp_members*/
7587 : : Unpickler_getsets, /*tp_getset*/
7588 : : 0, /*tp_base*/
7589 : : 0, /*tp_dict*/
7590 : : 0, /*tp_descr_get*/
7591 : : 0, /*tp_descr_set*/
7592 : : 0, /*tp_dictoffset*/
7593 : : _pickle_Unpickler___init__, /*tp_init*/
7594 : : PyType_GenericAlloc, /*tp_alloc*/
7595 : : PyType_GenericNew, /*tp_new*/
7596 : : PyObject_GC_Del, /*tp_free*/
7597 : : 0, /*tp_is_gc*/
7598 : : };
7599 : :
7600 : : /*[clinic input]
7601 : :
7602 : : _pickle.dump
7603 : :
7604 : : obj: object
7605 : : file: object
7606 : : protocol: object = None
7607 : : *
7608 : : fix_imports: bool = True
7609 : : buffer_callback: object = None
7610 : :
7611 : : Write a pickled representation of obj to the open file object file.
7612 : :
7613 : : This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may
7614 : : be more efficient.
7615 : :
7616 : : The optional *protocol* argument tells the pickler to use the given
7617 : : protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default
7618 : : protocol is 4. It was introduced in Python 3.4, and is incompatible
7619 : : with previous versions.
7620 : :
7621 : : Specifying a negative protocol version selects the highest protocol
7622 : : version supported. The higher the protocol used, the more recent the
7623 : : version of Python needed to read the pickle produced.
7624 : :
7625 : : The *file* argument must have a write() method that accepts a single
7626 : : bytes argument. It can thus be a file object opened for binary
7627 : : writing, an io.BytesIO instance, or any other custom object that meets
7628 : : this interface.
7629 : :
7630 : : If *fix_imports* is True and protocol is less than 3, pickle will try
7631 : : to map the new Python 3 names to the old module names used in Python
7632 : : 2, so that the pickle data stream is readable with Python 2.
7633 : :
7634 : : If *buffer_callback* is None (the default), buffer views are serialized
7635 : : into *file* as part of the pickle stream. It is an error if
7636 : : *buffer_callback* is not None and *protocol* is None or smaller than 5.
7637 : :
7638 : : [clinic start generated code]*/
7639 : :
7640 : : static PyObject *
7641 : 0 : _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file,
7642 : : PyObject *protocol, int fix_imports,
7643 : : PyObject *buffer_callback)
7644 : : /*[clinic end generated code: output=706186dba996490c input=5ed6653da99cd97c]*/
7645 : : {
7646 : 0 : PicklerObject *pickler = _Pickler_New();
7647 : :
7648 [ # # ]: 0 : if (pickler == NULL)
7649 : 0 : return NULL;
7650 : :
7651 [ # # ]: 0 : if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0)
7652 : 0 : goto error;
7653 : :
7654 [ # # ]: 0 : if (_Pickler_SetOutputStream(pickler, file) < 0)
7655 : 0 : goto error;
7656 : :
7657 [ # # ]: 0 : if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0)
7658 : 0 : goto error;
7659 : :
7660 [ # # ]: 0 : if (dump(pickler, obj) < 0)
7661 : 0 : goto error;
7662 : :
7663 [ # # ]: 0 : if (_Pickler_FlushToFile(pickler) < 0)
7664 : 0 : goto error;
7665 : :
7666 : 0 : Py_DECREF(pickler);
7667 : 0 : Py_RETURN_NONE;
7668 : :
7669 : 0 : error:
7670 : 0 : Py_XDECREF(pickler);
7671 : 0 : return NULL;
7672 : : }
7673 : :
7674 : : /*[clinic input]
7675 : :
7676 : : _pickle.dumps
7677 : :
7678 : : obj: object
7679 : : protocol: object = None
7680 : : *
7681 : : fix_imports: bool = True
7682 : : buffer_callback: object = None
7683 : :
7684 : : Return the pickled representation of the object as a bytes object.
7685 : :
7686 : : The optional *protocol* argument tells the pickler to use the given
7687 : : protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default
7688 : : protocol is 4. It was introduced in Python 3.4, and is incompatible
7689 : : with previous versions.
7690 : :
7691 : : Specifying a negative protocol version selects the highest protocol
7692 : : version supported. The higher the protocol used, the more recent the
7693 : : version of Python needed to read the pickle produced.
7694 : :
7695 : : If *fix_imports* is True and *protocol* is less than 3, pickle will
7696 : : try to map the new Python 3 names to the old module names used in
7697 : : Python 2, so that the pickle data stream is readable with Python 2.
7698 : :
7699 : : If *buffer_callback* is None (the default), buffer views are serialized
7700 : : into *file* as part of the pickle stream. It is an error if
7701 : : *buffer_callback* is not None and *protocol* is None or smaller than 5.
7702 : :
7703 : : [clinic start generated code]*/
7704 : :
7705 : : static PyObject *
7706 : 0 : _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol,
7707 : : int fix_imports, PyObject *buffer_callback)
7708 : : /*[clinic end generated code: output=fbab0093a5580fdf input=e543272436c6f987]*/
7709 : : {
7710 : : PyObject *result;
7711 : 0 : PicklerObject *pickler = _Pickler_New();
7712 : :
7713 [ # # ]: 0 : if (pickler == NULL)
7714 : 0 : return NULL;
7715 : :
7716 [ # # ]: 0 : if (_Pickler_SetProtocol(pickler, protocol, fix_imports) < 0)
7717 : 0 : goto error;
7718 : :
7719 [ # # ]: 0 : if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0)
7720 : 0 : goto error;
7721 : :
7722 [ # # ]: 0 : if (dump(pickler, obj) < 0)
7723 : 0 : goto error;
7724 : :
7725 : 0 : result = _Pickler_GetString(pickler);
7726 : 0 : Py_DECREF(pickler);
7727 : 0 : return result;
7728 : :
7729 : 0 : error:
7730 : 0 : Py_XDECREF(pickler);
7731 : 0 : return NULL;
7732 : : }
7733 : :
7734 : : /*[clinic input]
7735 : :
7736 : : _pickle.load
7737 : :
7738 : : file: object
7739 : : *
7740 : : fix_imports: bool = True
7741 : : encoding: str = 'ASCII'
7742 : : errors: str = 'strict'
7743 : : buffers: object(c_default="NULL") = ()
7744 : :
7745 : : Read and return an object from the pickle data stored in a file.
7746 : :
7747 : : This is equivalent to ``Unpickler(file).load()``, but may be more
7748 : : efficient.
7749 : :
7750 : : The protocol version of the pickle is detected automatically, so no
7751 : : protocol argument is needed. Bytes past the pickled object's
7752 : : representation are ignored.
7753 : :
7754 : : The argument *file* must have two methods, a read() method that takes
7755 : : an integer argument, and a readline() method that requires no
7756 : : arguments. Both methods should return bytes. Thus *file* can be a
7757 : : binary file object opened for reading, an io.BytesIO object, or any
7758 : : other custom object that meets this interface.
7759 : :
7760 : : Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
7761 : : which are used to control compatibility support for pickle stream
7762 : : generated by Python 2. If *fix_imports* is True, pickle will try to
7763 : : map the old Python 2 names to the new names used in Python 3. The
7764 : : *encoding* and *errors* tell pickle how to decode 8-bit string
7765 : : instances pickled by Python 2; these default to 'ASCII' and 'strict',
7766 : : respectively. The *encoding* can be 'bytes' to read these 8-bit
7767 : : string instances as bytes objects.
7768 : : [clinic start generated code]*/
7769 : :
7770 : : static PyObject *
7771 : 0 : _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports,
7772 : : const char *encoding, const char *errors,
7773 : : PyObject *buffers)
7774 : : /*[clinic end generated code: output=250452d141c23e76 input=46c7c31c92f4f371]*/
7775 : : {
7776 : : PyObject *result;
7777 : 0 : UnpicklerObject *unpickler = _Unpickler_New();
7778 : :
7779 [ # # ]: 0 : if (unpickler == NULL)
7780 : 0 : return NULL;
7781 : :
7782 [ # # ]: 0 : if (_Unpickler_SetInputStream(unpickler, file) < 0)
7783 : 0 : goto error;
7784 : :
7785 [ # # ]: 0 : if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
7786 : 0 : goto error;
7787 : :
7788 [ # # ]: 0 : if (_Unpickler_SetBuffers(unpickler, buffers) < 0)
7789 : 0 : goto error;
7790 : :
7791 : 0 : unpickler->fix_imports = fix_imports;
7792 : :
7793 : 0 : result = load(unpickler);
7794 : 0 : Py_DECREF(unpickler);
7795 : 0 : return result;
7796 : :
7797 : 0 : error:
7798 : 0 : Py_XDECREF(unpickler);
7799 : 0 : return NULL;
7800 : : }
7801 : :
7802 : : /*[clinic input]
7803 : :
7804 : : _pickle.loads
7805 : :
7806 : : data: object
7807 : : /
7808 : : *
7809 : : fix_imports: bool = True
7810 : : encoding: str = 'ASCII'
7811 : : errors: str = 'strict'
7812 : : buffers: object(c_default="NULL") = ()
7813 : :
7814 : : Read and return an object from the given pickle data.
7815 : :
7816 : : The protocol version of the pickle is detected automatically, so no
7817 : : protocol argument is needed. Bytes past the pickled object's
7818 : : representation are ignored.
7819 : :
7820 : : Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
7821 : : which are used to control compatibility support for pickle stream
7822 : : generated by Python 2. If *fix_imports* is True, pickle will try to
7823 : : map the old Python 2 names to the new names used in Python 3. The
7824 : : *encoding* and *errors* tell pickle how to decode 8-bit string
7825 : : instances pickled by Python 2; these default to 'ASCII' and 'strict',
7826 : : respectively. The *encoding* can be 'bytes' to read these 8-bit
7827 : : string instances as bytes objects.
7828 : : [clinic start generated code]*/
7829 : :
7830 : : static PyObject *
7831 : 0 : _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports,
7832 : : const char *encoding, const char *errors,
7833 : : PyObject *buffers)
7834 : : /*[clinic end generated code: output=82ac1e6b588e6d02 input=b3615540d0535087]*/
7835 : : {
7836 : : PyObject *result;
7837 : 0 : UnpicklerObject *unpickler = _Unpickler_New();
7838 : :
7839 [ # # ]: 0 : if (unpickler == NULL)
7840 : 0 : return NULL;
7841 : :
7842 [ # # ]: 0 : if (_Unpickler_SetStringInput(unpickler, data) < 0)
7843 : 0 : goto error;
7844 : :
7845 [ # # ]: 0 : if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
7846 : 0 : goto error;
7847 : :
7848 [ # # ]: 0 : if (_Unpickler_SetBuffers(unpickler, buffers) < 0)
7849 : 0 : goto error;
7850 : :
7851 : 0 : unpickler->fix_imports = fix_imports;
7852 : :
7853 : 0 : result = load(unpickler);
7854 : 0 : Py_DECREF(unpickler);
7855 : 0 : return result;
7856 : :
7857 : 0 : error:
7858 : 0 : Py_XDECREF(unpickler);
7859 : 0 : return NULL;
7860 : : }
7861 : :
7862 : : static struct PyMethodDef pickle_methods[] = {
7863 : : _PICKLE_DUMP_METHODDEF
7864 : : _PICKLE_DUMPS_METHODDEF
7865 : : _PICKLE_LOAD_METHODDEF
7866 : : _PICKLE_LOADS_METHODDEF
7867 : : {NULL, NULL} /* sentinel */
7868 : : };
7869 : :
7870 : : static int
7871 : 0 : pickle_clear(PyObject *m)
7872 : : {
7873 : 0 : _Pickle_ClearState(_Pickle_GetState(m));
7874 : 0 : return 0;
7875 : : }
7876 : :
7877 : : static void
7878 : 1 : pickle_free(PyObject *m)
7879 : : {
7880 : 1 : _Pickle_ClearState(_Pickle_GetState(m));
7881 : 1 : }
7882 : :
7883 : : static int
7884 : 8 : pickle_traverse(PyObject *m, visitproc visit, void *arg)
7885 : : {
7886 : 8 : PickleState *st = _Pickle_GetState(m);
7887 [ + - - + ]: 8 : Py_VISIT(st->PickleError);
7888 [ + - - + ]: 8 : Py_VISIT(st->PicklingError);
7889 [ + - - + ]: 8 : Py_VISIT(st->UnpicklingError);
7890 [ + - - + ]: 8 : Py_VISIT(st->dispatch_table);
7891 [ + - - + ]: 8 : Py_VISIT(st->extension_registry);
7892 [ + - - + ]: 8 : Py_VISIT(st->extension_cache);
7893 [ + - - + ]: 8 : Py_VISIT(st->inverted_registry);
7894 [ + - - + ]: 8 : Py_VISIT(st->name_mapping_2to3);
7895 [ + - - + ]: 8 : Py_VISIT(st->import_mapping_2to3);
7896 [ + - - + ]: 8 : Py_VISIT(st->name_mapping_3to2);
7897 [ + - - + ]: 8 : Py_VISIT(st->import_mapping_3to2);
7898 [ + - - + ]: 8 : Py_VISIT(st->codecs_encode);
7899 [ + - - + ]: 8 : Py_VISIT(st->getattr);
7900 [ + - - + ]: 8 : Py_VISIT(st->partial);
7901 : 8 : return 0;
7902 : : }
7903 : :
7904 : : static struct PyModuleDef _picklemodule = {
7905 : : PyModuleDef_HEAD_INIT,
7906 : : "_pickle", /* m_name */
7907 : : pickle_module_doc, /* m_doc */
7908 : : sizeof(PickleState), /* m_size */
7909 : : pickle_methods, /* m_methods */
7910 : : NULL, /* m_reload */
7911 : : pickle_traverse, /* m_traverse */
7912 : : pickle_clear, /* m_clear */
7913 : : (freefunc)pickle_free /* m_free */
7914 : : };
7915 : :
7916 : : PyMODINIT_FUNC
7917 : 1 : PyInit__pickle(void)
7918 : : {
7919 : : PyObject *m;
7920 : : PickleState *st;
7921 : :
7922 : 1 : m = PyState_FindModule(&_picklemodule);
7923 [ - + ]: 1 : if (m) {
7924 : 0 : return Py_NewRef(m);
7925 : : }
7926 : :
7927 [ - + ]: 1 : if (PyType_Ready(&Pdata_Type) < 0)
7928 : 0 : return NULL;
7929 [ - + ]: 1 : if (PyType_Ready(&PicklerMemoProxyType) < 0)
7930 : 0 : return NULL;
7931 [ - + ]: 1 : if (PyType_Ready(&UnpicklerMemoProxyType) < 0)
7932 : 0 : return NULL;
7933 : :
7934 : : /* Create the module and add the functions. */
7935 : 1 : m = PyModule_Create(&_picklemodule);
7936 [ - + ]: 1 : if (m == NULL)
7937 : 0 : return NULL;
7938 : :
7939 : : /* Add types */
7940 [ - + ]: 1 : if (PyModule_AddType(m, &Pickler_Type) < 0) {
7941 : 0 : return NULL;
7942 : : }
7943 [ - + ]: 1 : if (PyModule_AddType(m, &Unpickler_Type) < 0) {
7944 : 0 : return NULL;
7945 : : }
7946 [ - + ]: 1 : if (PyModule_AddType(m, &PyPickleBuffer_Type) < 0) {
7947 : 0 : return NULL;
7948 : : }
7949 : :
7950 : 1 : st = _Pickle_GetState(m);
7951 : :
7952 : : /* Initialize the exceptions. */
7953 : 1 : st->PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL);
7954 [ - + ]: 1 : if (st->PickleError == NULL)
7955 : 0 : return NULL;
7956 : 1 : st->PicklingError = \
7957 : 1 : PyErr_NewException("_pickle.PicklingError", st->PickleError, NULL);
7958 [ - + ]: 1 : if (st->PicklingError == NULL)
7959 : 0 : return NULL;
7960 : 1 : st->UnpicklingError = \
7961 : 1 : PyErr_NewException("_pickle.UnpicklingError", st->PickleError, NULL);
7962 [ - + ]: 1 : if (st->UnpicklingError == NULL)
7963 : 0 : return NULL;
7964 : :
7965 [ - + ]: 1 : if (PyModule_AddObjectRef(m, "PickleError", st->PickleError) < 0) {
7966 : 0 : return NULL;
7967 : : }
7968 [ - + ]: 1 : if (PyModule_AddObjectRef(m, "PicklingError", st->PicklingError) < 0) {
7969 : 0 : return NULL;
7970 : : }
7971 [ - + ]: 1 : if (PyModule_AddObjectRef(m, "UnpicklingError", st->UnpicklingError) < 0) {
7972 : 0 : return NULL;
7973 : : }
7974 [ - + ]: 1 : if (_Pickle_InitState(st) < 0)
7975 : 0 : return NULL;
7976 : :
7977 : 1 : return m;
7978 : : }
|