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