blob: 1e901ae7c3133e02e5bf70c292b9d8f8e8790405 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001
2/* Write Python objects to files and read them back.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07003 This is primarily intended for writing and reading compiled Python code,
4 even though dicts, lists, sets and frozensets, not commonly seen in
5 code objects, are supported.
6 Version 3 of this protocol properly supports circular links
7 and sharing. */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00008
Thomas Wouters695934a2006-03-01 23:49:13 +00009#define PY_SSIZE_T_CLEAN
10
Guido van Rossum79f25d91997-04-29 20:08:16 +000011#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000012#include "longintrepr.h"
Jeremy Hylton3e0055f2005-10-20 19:59:25 +000013#include "code.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000014#include "marshal.h"
Victor Stinnerb6179932020-05-12 02:42:19 +020015#include "pycore_hashtable.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000016
Serhiy Storchaka0767ad42017-03-12 09:20:15 +020017/*[clinic input]
18module marshal
19[clinic start generated code]*/
20/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]*/
21
22#include "clinic/marshal.c.h"
23
Fred Drake6da0b912000-06-28 18:47:56 +000024/* High water mark to determine when the marshalled object is dangerously deep
25 * and risks coring the interpreter. When the object stack gets this deep,
26 * raise an exception instead of continuing.
Guido van Rossum63175a12007-08-29 20:39:13 +000027 * On Windows debug builds, reduce this value.
Steve Dower2a4a62b2018-06-04 13:25:00 -070028 *
29 * BUG: https://bugs.python.org/issue33720
30 * On Windows PGO builds, the r_object function overallocates its stack and
31 * can cause a stack overflow. We reduce the maximum depth for all Windows
32 * releases to protect against this.
33 * #if defined(MS_WINDOWS) && defined(_DEBUG)
Fred Drake6da0b912000-06-28 18:47:56 +000034 */
Steve Dower2a4a62b2018-06-04 13:25:00 -070035#if defined(MS_WINDOWS)
Steve Dowerf6c69e62014-11-01 15:15:16 -070036#define MAX_MARSHAL_STACK_DEPTH 1000
Guido van Rossum63175a12007-08-29 20:39:13 +000037#else
Guido van Rossumd59da4b2007-05-22 18:11:13 +000038#define MAX_MARSHAL_STACK_DEPTH 2000
Guido van Rossum63175a12007-08-29 20:39:13 +000039#endif
Fred Drake6da0b912000-06-28 18:47:56 +000040
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041#define TYPE_NULL '0'
42#define TYPE_NONE 'N'
43#define TYPE_FALSE 'F'
44#define TYPE_TRUE 'T'
45#define TYPE_STOPITER 'S'
46#define TYPE_ELLIPSIS '.'
47#define TYPE_INT 'i'
Serhiy Storchaka00987f62017-11-15 17:41:05 +020048/* TYPE_INT64 is not generated anymore.
49 Supported for backward compatibility only. */
50#define TYPE_INT64 'I'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051#define TYPE_FLOAT 'f'
52#define TYPE_BINARY_FLOAT 'g'
53#define TYPE_COMPLEX 'x'
54#define TYPE_BINARY_COMPLEX 'y'
55#define TYPE_LONG 'l'
56#define TYPE_STRING 's'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070057#define TYPE_INTERNED 't'
58#define TYPE_REF 'r'
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000059#define TYPE_TUPLE '('
60#define TYPE_LIST '['
61#define TYPE_DICT '{'
62#define TYPE_CODE 'c'
63#define TYPE_UNICODE 'u'
64#define TYPE_UNKNOWN '?'
65#define TYPE_SET '<'
66#define TYPE_FROZENSET '>'
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -070067#define FLAG_REF '\x80' /* with a type, add obj to index */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000068
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020069#define TYPE_ASCII 'a'
70#define TYPE_ASCII_INTERNED 'A'
71#define TYPE_SMALL_TUPLE ')'
72#define TYPE_SHORT_ASCII 'z'
73#define TYPE_SHORT_ASCII_INTERNED 'Z'
74
Eric Smithb1a03cf2009-04-21 11:57:38 +000075#define WFERR_OK 0
76#define WFERR_UNMARSHALLABLE 1
77#define WFERR_NESTEDTOODEEP 2
78#define WFERR_NOMEMORY 3
79
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000080typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 FILE *fp;
82 int error; /* see WFERR_* values */
83 int depth;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 PyObject *str;
85 char *ptr;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +030086 const char *end;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +020087 char *buf;
Serhiy Storchakace921c622015-02-11 15:53:31 +020088 _Py_hashtable_t *hashtable;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 int version;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000090} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000091
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020092#define w_byte(c, p) do { \
93 if ((p)->ptr != (p)->end || w_reserve((p), 1)) \
94 *(p)->ptr++ = (c); \
95 } while(0)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000096
97static void
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +020098w_flush(WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000099{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200100 assert(p->fp != NULL);
101 fwrite(p->buf, 1, p->ptr - p->buf, p->fp);
102 p->ptr = p->buf;
103}
104
105static int
106w_reserve(WFILE *p, Py_ssize_t needed)
107{
108 Py_ssize_t pos, size, delta;
109 if (p->ptr == NULL)
110 return 0; /* An error already occurred */
111 if (p->fp != NULL) {
112 w_flush(p);
113 return needed <= p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 }
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200115 assert(p->str != NULL);
116 pos = p->ptr - p->buf;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300117 size = PyBytes_GET_SIZE(p->str);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200118 if (size > 16*1024*1024)
119 delta = (size >> 3); /* 12.5% overallocation */
120 else
121 delta = size + 1024;
122 delta = Py_MAX(delta, needed);
123 if (delta > PY_SSIZE_T_MAX - size) {
124 p->error = WFERR_NOMEMORY;
125 return 0;
126 }
127 size += delta;
128 if (_PyBytes_Resize(&p->str, size) != 0) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300129 p->end = p->ptr = p->buf = NULL;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200130 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 }
132 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200133 p->buf = PyBytes_AS_STRING(p->str);
134 p->ptr = p->buf + pos;
135 p->end = p->buf + size;
136 return 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000138}
139
140static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300141w_string(const void *s, Py_ssize_t n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200143 Py_ssize_t m;
144 if (!n || p->ptr == NULL)
145 return;
146 m = p->end - p->ptr;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 if (p->fp != NULL) {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200148 if (n <= m) {
Christian Heimesf051e432016-09-13 20:22:02 +0200149 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200150 p->ptr += n;
151 }
152 else {
153 w_flush(p);
154 fwrite(s, 1, n, p->fp);
155 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 }
157 else {
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200158 if (n <= m || w_reserve(p, n - m)) {
Christian Heimesf051e432016-09-13 20:22:02 +0200159 memcpy(p->ptr, s, n);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200160 p->ptr += n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 }
162 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000163}
164
165static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000166w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 w_byte((char)( x & 0xff), p);
169 w_byte((char)((x>> 8) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170}
171
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000172static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000173w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 w_byte((char)( x & 0xff), p);
176 w_byte((char)((x>> 8) & 0xff), p);
177 w_byte((char)((x>>16) & 0xff), p);
178 w_byte((char)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000179}
180
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200181#define SIZE32_MAX 0x7FFFFFFF
182
183#if SIZEOF_SIZE_T > 4
184# define W_SIZE(n, p) do { \
185 if ((n) > SIZE32_MAX) { \
186 (p)->depth--; \
187 (p)->error = WFERR_UNMARSHALLABLE; \
188 return; \
189 } \
190 w_long((long)(n), p); \
191 } while(0)
192#else
193# define W_SIZE w_long
194#endif
195
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300196static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300197w_pstring(const void *s, Py_ssize_t n, WFILE *p)
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300198{
199 W_SIZE(n, p);
200 w_string(s, n, p);
201}
202
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200203static void
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300204w_short_pstring(const void *s, Py_ssize_t n, WFILE *p)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200205{
Antoine Pitroub30f2712013-10-12 23:14:47 +0200206 w_byte(Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char), p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200207 w_string(s, n, p);
208}
209
Serhiy Storchaka95949422013-08-27 19:40:23 +0300210/* We assume that Python ints are stored internally in base some power of
Mark Dickinsonbd792642009-03-18 20:06:12 +0000211 2**15; for the sake of portability we'll always read and write them in base
212 exactly 2**15. */
213
214#define PyLong_MARSHAL_SHIFT 15
215#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
216#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
217#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
218#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
219#endif
220#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
221
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700222#define W_TYPE(t, p) do { \
223 w_byte((t) | flag, (p)); \
224} while(0)
225
Mark Dickinsonbd792642009-03-18 20:06:12 +0000226static void
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700227w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
Mark Dickinsonbd792642009-03-18 20:06:12 +0000228{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 Py_ssize_t i, j, n, l;
230 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000231
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700232 W_TYPE(TYPE_LONG, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 if (Py_SIZE(ob) == 0) {
234 w_long((long)0, p);
235 return;
236 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 /* set l to number of base PyLong_MARSHAL_BASE digits */
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200239 n = Py_ABS(Py_SIZE(ob));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 l = (n-1) * PyLong_MARSHAL_RATIO;
241 d = ob->ob_digit[n-1];
242 assert(d != 0); /* a PyLong is always normalized */
243 do {
244 d >>= PyLong_MARSHAL_SHIFT;
245 l++;
246 } while (d != 0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200247 if (l > SIZE32_MAX) {
248 p->depth--;
249 p->error = WFERR_UNMARSHALLABLE;
250 return;
251 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 for (i=0; i < n-1; i++) {
255 d = ob->ob_digit[i];
256 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
257 w_short(d & PyLong_MARSHAL_MASK, p);
258 d >>= PyLong_MARSHAL_SHIFT;
259 }
260 assert (d == 0);
261 }
262 d = ob->ob_digit[n-1];
263 do {
264 w_short(d & PyLong_MARSHAL_MASK, p);
265 d >>= PyLong_MARSHAL_SHIFT;
266 } while (d != 0);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000267}
268
Serhiy Storchakac5734992018-07-24 10:55:47 +0300269static void
270w_float_bin(double v, WFILE *p)
271{
272 unsigned char buf[8];
273 if (_PyFloat_Pack8(v, buf, 1) < 0) {
274 p->error = WFERR_UNMARSHALLABLE;
275 return;
276 }
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300277 w_string(buf, 8, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300278}
279
280static void
281w_float_str(double v, WFILE *p)
282{
Serhiy Storchakac5734992018-07-24 10:55:47 +0300283 char *buf = PyOS_double_to_string(v, 'g', 17, 0, NULL);
284 if (!buf) {
285 p->error = WFERR_NOMEMORY;
286 return;
287 }
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300288 w_short_pstring(buf, strlen(buf), p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300289 PyMem_Free(buf);
290}
291
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700292static int
293w_ref(PyObject *v, char *flag, WFILE *p)
294{
Serhiy Storchakace921c622015-02-11 15:53:31 +0200295 _Py_hashtable_entry_t *entry;
296 int w;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700297
Serhiy Storchakace921c622015-02-11 15:53:31 +0200298 if (p->version < 3 || p->hashtable == NULL)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700299 return 0; /* not writing object references */
300
301 /* if it has only one reference, it definitely isn't shared */
302 if (Py_REFCNT(v) == 1)
303 return 0;
304
Victor Stinner285cf0a2016-03-21 22:00:58 +0100305 entry = _Py_HASHTABLE_GET_ENTRY(p->hashtable, v);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200306 if (entry != NULL) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700307 /* write the reference index to the stream */
Victor Stinnere8c6b2f2016-03-23 09:25:01 +0100308 _Py_HASHTABLE_ENTRY_READ_DATA(p->hashtable, entry, w);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700309 /* we don't store "long" indices in the dict */
310 assert(0 <= w && w <= 0x7fffffff);
311 w_byte(TYPE_REF, p);
312 w_long(w, p);
313 return 1;
314 } else {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200315 size_t s = p->hashtable->entries;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700316 /* we don't support long indices */
317 if (s >= 0x7fffffff) {
318 PyErr_SetString(PyExc_ValueError, "too many objects");
319 goto err;
320 }
Serhiy Storchaka26861b02015-02-16 20:52:17 +0200321 w = (int)s;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200322 Py_INCREF(v);
323 if (_Py_HASHTABLE_SET(p->hashtable, v, w) < 0) {
324 Py_DECREF(v);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700325 goto err;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200326 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700327 *flag |= FLAG_REF;
328 return 0;
329 }
330err:
331 p->error = WFERR_UNMARSHALLABLE;
332 return 1;
333}
334
335static void
336w_complex_object(PyObject *v, char flag, WFILE *p);
337
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000338static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000339w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340{
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700341 char flag = '\0';
Fred Drake6da0b912000-06-28 18:47:56 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 p->depth++;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000345 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
346 p->error = WFERR_NESTEDTOODEEP;
347 }
348 else if (v == NULL) {
349 w_byte(TYPE_NULL, p);
350 }
351 else if (v == Py_None) {
352 w_byte(TYPE_NONE, p);
353 }
354 else if (v == PyExc_StopIteration) {
355 w_byte(TYPE_STOPITER, p);
356 }
357 else if (v == Py_Ellipsis) {
358 w_byte(TYPE_ELLIPSIS, p);
359 }
360 else if (v == Py_False) {
361 w_byte(TYPE_FALSE, p);
362 }
363 else if (v == Py_True) {
364 w_byte(TYPE_TRUE, p);
365 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700366 else if (!w_ref(v, &flag, p))
367 w_complex_object(v, flag, p);
368
369 p->depth--;
370}
371
372static void
373w_complex_object(PyObject *v, char flag, WFILE *p)
374{
375 Py_ssize_t i, n;
376
377 if (PyLong_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300378 int overflow;
379 long x = PyLong_AsLongAndOverflow(v, &overflow);
380 if (overflow) {
381 w_PyLong((PyLongObject *)v, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 }
383 else {
Guido van Rossumc1547d91996-12-10 15:39:04 +0000384#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
386 if (y && y != -1) {
Martin v. Löwis7e395722012-07-28 19:44:05 +0200387 /* Too large for TYPE_INT */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700388 w_PyLong((PyLongObject*)v, flag, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 }
390 else
Guido van Rossumc1547d91996-12-10 15:39:04 +0000391#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000392 {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700393 W_TYPE(TYPE_INT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 w_long(x, p);
395 }
396 }
397 }
398 else if (PyFloat_CheckExact(v)) {
399 if (p->version > 1) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700400 W_TYPE(TYPE_BINARY_FLOAT, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300401 w_float_bin(PyFloat_AS_DOUBLE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000402 }
403 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700404 W_TYPE(TYPE_FLOAT, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300405 w_float_str(PyFloat_AS_DOUBLE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 }
407 }
408 else if (PyComplex_CheckExact(v)) {
409 if (p->version > 1) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700410 W_TYPE(TYPE_BINARY_COMPLEX, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300411 w_float_bin(PyComplex_RealAsDouble(v), p);
412 w_float_bin(PyComplex_ImagAsDouble(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 }
414 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700415 W_TYPE(TYPE_COMPLEX, p);
Serhiy Storchakac5734992018-07-24 10:55:47 +0300416 w_float_str(PyComplex_RealAsDouble(v), p);
417 w_float_str(PyComplex_ImagAsDouble(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 }
419 }
420 else if (PyBytes_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700421 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300422 w_pstring(PyBytes_AS_STRING(v), PyBytes_GET_SIZE(v), p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 }
424 else if (PyUnicode_CheckExact(v)) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200425 if (p->version >= 4 && PyUnicode_IS_ASCII(v)) {
426 int is_short = PyUnicode_GET_LENGTH(v) < 256;
427 if (is_short) {
428 if (PyUnicode_CHECK_INTERNED(v))
429 W_TYPE(TYPE_SHORT_ASCII_INTERNED, p);
430 else
431 W_TYPE(TYPE_SHORT_ASCII, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300432 w_short_pstring(PyUnicode_1BYTE_DATA(v),
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200433 PyUnicode_GET_LENGTH(v), p);
434 }
435 else {
436 if (PyUnicode_CHECK_INTERNED(v))
437 W_TYPE(TYPE_ASCII_INTERNED, p);
438 else
439 W_TYPE(TYPE_ASCII, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300440 w_pstring(PyUnicode_1BYTE_DATA(v),
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200441 PyUnicode_GET_LENGTH(v), p);
442 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200444 else {
445 PyObject *utf8;
446 utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
447 if (utf8 == NULL) {
448 p->depth--;
449 p->error = WFERR_UNMARSHALLABLE;
450 return;
451 }
452 if (p->version >= 3 && PyUnicode_CHECK_INTERNED(v))
453 W_TYPE(TYPE_INTERNED, p);
454 else
455 W_TYPE(TYPE_UNICODE, p);
456 w_pstring(PyBytes_AS_STRING(utf8), PyBytes_GET_SIZE(utf8), p);
457 Py_DECREF(utf8);
458 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000459 }
460 else if (PyTuple_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300461 n = PyTuple_GET_SIZE(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200462 if (p->version >= 4 && n < 256) {
463 W_TYPE(TYPE_SMALL_TUPLE, p);
Victor Stinnerda062552013-11-16 00:13:29 +0100464 w_byte((unsigned char)n, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200465 }
466 else {
467 W_TYPE(TYPE_TUPLE, p);
468 W_SIZE(n, p);
469 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 for (i = 0; i < n; i++) {
471 w_object(PyTuple_GET_ITEM(v, i), p);
472 }
473 }
474 else if (PyList_CheckExact(v)) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700475 W_TYPE(TYPE_LIST, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 n = PyList_GET_SIZE(v);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200477 W_SIZE(n, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 for (i = 0; i < n; i++) {
479 w_object(PyList_GET_ITEM(v, i), p);
480 }
481 }
482 else if (PyDict_CheckExact(v)) {
483 Py_ssize_t pos;
484 PyObject *key, *value;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700485 W_TYPE(TYPE_DICT, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 /* This one is NULL object terminated! */
487 pos = 0;
488 while (PyDict_Next(v, &pos, &key, &value)) {
489 w_object(key, p);
490 w_object(value, p);
491 }
492 w_object((PyObject *)NULL, p);
493 }
494 else if (PyAnySet_CheckExact(v)) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300495 PyObject *value;
496 Py_ssize_t pos = 0;
497 Py_hash_t hash;
Raymond Hettingera422c342005-01-11 03:03:27 +0000498
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300499 if (PyFrozenSet_CheckExact(v))
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700500 W_TYPE(TYPE_FROZENSET, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300501 else
502 W_TYPE(TYPE_SET, p);
503 n = PySet_GET_SIZE(v);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200504 W_SIZE(n, p);
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300505 while (_PySet_NextEntry(v, &pos, &value, &hash)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 w_object(value, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 }
508 }
509 else if (PyCode_Check(v)) {
510 PyCodeObject *co = (PyCodeObject *)v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700511 W_TYPE(TYPE_CODE, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 w_long(co->co_argcount, p);
Pablo Galindo8c77b8c2019-04-29 13:36:57 +0100513 w_long(co->co_posonlyargcount, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 w_long(co->co_kwonlyargcount, p);
515 w_long(co->co_nlocals, p);
516 w_long(co->co_stacksize, p);
517 w_long(co->co_flags, p);
518 w_object(co->co_code, p);
519 w_object(co->co_consts, p);
520 w_object(co->co_names, p);
521 w_object(co->co_varnames, p);
522 w_object(co->co_freevars, p);
523 w_object(co->co_cellvars, p);
524 w_object(co->co_filename, p);
525 w_object(co->co_name, p);
526 w_long(co->co_firstlineno, p);
527 w_object(co->co_lnotab, p);
528 }
529 else if (PyObject_CheckBuffer(v)) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +0200530 /* Write unknown bytes-like objects as a bytes object */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 Py_buffer view;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100532 if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 w_byte(TYPE_UNKNOWN, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100534 p->depth--;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 p->error = WFERR_UNMARSHALLABLE;
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100536 return;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 }
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700538 W_TYPE(TYPE_STRING, p);
Serhiy Storchakadfde2152013-07-11 19:14:26 +0300539 w_pstring(view.buf, view.len, p);
Antoine Pitrou679e9d32012-03-02 18:12:43 +0100540 PyBuffer_Release(&view);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 }
542 else {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700543 W_TYPE(TYPE_UNKNOWN, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 p->error = WFERR_UNMARSHALLABLE;
545 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000546}
547
Serhiy Storchakace921c622015-02-11 15:53:31 +0200548static int
549w_init_refs(WFILE *wf, int version)
550{
551 if (version >= 3) {
Victor Stinnerf9b3b582020-05-13 02:26:02 +0200552 wf->hashtable = _Py_hashtable_new(sizeof(int),
Victor Stinner285cf0a2016-03-21 22:00:58 +0100553 _Py_hashtable_hash_ptr,
Serhiy Storchakace921c622015-02-11 15:53:31 +0200554 _Py_hashtable_compare_direct);
555 if (wf->hashtable == NULL) {
556 PyErr_NoMemory();
557 return -1;
558 }
559 }
560 return 0;
561}
562
563static int
Victor Stinner285cf0a2016-03-21 22:00:58 +0100564w_decref_entry(_Py_hashtable_t *ht, _Py_hashtable_entry_t *entry,
565 void *Py_UNUSED(data))
Serhiy Storchakace921c622015-02-11 15:53:31 +0200566{
Victor Stinnerf9b3b582020-05-13 02:26:02 +0200567 PyObject *entry_key = (PyObject *)entry->key;
Victor Stinner285cf0a2016-03-21 22:00:58 +0100568 Py_XDECREF(entry_key);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200569 return 0;
570}
571
572static void
573w_clear_refs(WFILE *wf)
574{
575 if (wf->hashtable != NULL) {
576 _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL);
577 _Py_hashtable_destroy(wf->hashtable);
578 }
579}
580
Serhiy Storchaka95949422013-08-27 19:40:23 +0300581/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000582void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000583PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000584{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200585 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200587 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200589 wf.ptr = wf.buf = buf;
590 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000592 wf.version = version;
593 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200594 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000595}
596
597void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000598PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000599{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200600 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200602 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200604 wf.ptr = wf.buf = buf;
605 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200608 if (w_init_refs(&wf, version))
609 return; /* caller mush check PyErr_Occurred() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000610 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200611 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200612 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000613}
614
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200615typedef struct {
616 FILE *fp;
617 int depth;
618 PyObject *readable; /* Stream-like object being read from */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300619 const char *ptr;
620 const char *end;
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200621 char *buf;
622 Py_ssize_t buf_size;
623 PyObject *refs; /* a list */
624} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000625
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200626static const char *
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200627r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000628{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200629 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100630
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200631 if (p->ptr != NULL) {
632 /* Fast path for loads() */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300633 const char *res = p->ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200634 Py_ssize_t left = p->end - p->ptr;
635 if (left < n) {
636 PyErr_SetString(PyExc_EOFError,
637 "marshal data too short");
638 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100639 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200640 p->ptr += n;
641 return res;
642 }
643 if (p->buf == NULL) {
644 p->buf = PyMem_MALLOC(n);
645 if (p->buf == NULL) {
646 PyErr_NoMemory();
647 return NULL;
648 }
649 p->buf_size = n;
650 }
651 else if (p->buf_size < n) {
Zackery Spytz4c49da02018-12-07 03:11:30 -0700652 char *tmp = PyMem_REALLOC(p->buf, n);
653 if (tmp == NULL) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200654 PyErr_NoMemory();
655 return NULL;
656 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700657 p->buf = tmp;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200658 p->buf_size = n;
659 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100660
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200661 if (!p->readable) {
662 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200663 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100664 }
665 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200666 _Py_IDENTIFIER(readinto);
667 PyObject *res, *mview;
668 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200669
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200670 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
671 return NULL;
672 mview = PyMemoryView_FromBuffer(&buf);
673 if (mview == NULL)
674 return NULL;
675
676 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
677 if (res != NULL) {
678 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
679 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100680 }
681 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200682 if (read != n) {
683 if (!PyErr_Occurred()) {
684 if (read > n)
685 PyErr_Format(PyExc_ValueError,
686 "read() returned too much data: "
687 "%zd bytes requested, %zd returned",
688 n, read);
689 else
690 PyErr_SetString(PyExc_EOFError,
691 "EOF read where not expected");
692 }
693 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100694 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200695 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100696}
697
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100698static int
699r_byte(RFILE *p)
700{
701 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100702
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200703 if (p->ptr != NULL) {
704 if (p->ptr < p->end)
705 c = (unsigned char) *p->ptr++;
706 return c;
707 }
708 if (!p->readable) {
709 assert(p->fp);
710 c = getc(p->fp);
711 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100712 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200713 const char *ptr = r_string(1, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200714 if (ptr != NULL)
Andy Lestere6be9b52020-02-11 20:28:35 -0600715 c = *(const unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100716 }
717 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000718}
719
720static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000721r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000722{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200723 short x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200724 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100725
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200726 buffer = (const unsigned char *) r_string(2, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200727 if (buffer != NULL) {
728 x = buffer[0];
729 x |= buffer[1] << 8;
730 /* Sign-extension, in case short greater than 16 bits */
731 x |= -(x & 0x8000);
732 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000734}
735
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000736static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000737r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000738{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200739 long x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200740 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100741
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200742 buffer = (const unsigned char *) r_string(4, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200743 if (buffer != NULL) {
744 x = buffer[0];
745 x |= (long)buffer[1] << 8;
746 x |= (long)buffer[2] << 16;
747 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000748#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200749 /* Sign extension for 64-bit machines */
750 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000751#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200752 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000753 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000754}
755
Serhiy Storchaka00987f62017-11-15 17:41:05 +0200756/* r_long64 deals with the TYPE_INT64 code. */
757static PyObject *
758r_long64(RFILE *p)
759{
760 const unsigned char *buffer = (const unsigned char *) r_string(8, p);
761 if (buffer == NULL) {
762 return NULL;
763 }
764 return _PyLong_FromByteArray(buffer, 8,
765 1 /* little endian */,
766 1 /* signed */);
767}
768
Guido van Rossum79f25d91997-04-29 20:08:16 +0000769static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000770r_PyLong(RFILE *p)
771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200773 long n, size, i;
774 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100778 if (PyErr_Occurred())
779 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 if (n == 0)
781 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200782 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 PyErr_SetString(PyExc_ValueError,
784 "bad marshal data (long size out of range)");
785 return NULL;
786 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000787
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200788 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
789 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000790 ob = _PyLong_New(size);
791 if (ob == NULL)
792 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100793
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100794 Py_SET_SIZE(ob, n > 0 ? size : -size);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 for (i = 0; i < size-1; i++) {
797 d = 0;
798 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
799 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100800 if (PyErr_Occurred()) {
801 Py_DECREF(ob);
802 return NULL;
803 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000804 if (md < 0 || md > PyLong_MARSHAL_BASE)
805 goto bad_digit;
806 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
807 }
808 ob->ob_digit[i] = d;
809 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100810
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 d = 0;
812 for (j=0; j < shorts_in_top_digit; j++) {
813 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100814 if (PyErr_Occurred()) {
815 Py_DECREF(ob);
816 return NULL;
817 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 if (md < 0 || md > PyLong_MARSHAL_BASE)
819 goto bad_digit;
820 /* topmost marshal digit should be nonzero */
821 if (md == 0 && j == shorts_in_top_digit - 1) {
822 Py_DECREF(ob);
823 PyErr_SetString(PyExc_ValueError,
824 "bad marshal data (unnormalized long data)");
825 return NULL;
826 }
827 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
828 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100829 if (PyErr_Occurred()) {
830 Py_DECREF(ob);
831 return NULL;
832 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 /* top digit should be nonzero, else the resulting PyLong won't be
834 normalized */
835 ob->ob_digit[size-1] = d;
836 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000837 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000838 Py_DECREF(ob);
839 PyErr_SetString(PyExc_ValueError,
840 "bad marshal data (digit out of range in long)");
841 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000842}
843
Serhiy Storchakac5734992018-07-24 10:55:47 +0300844static double
845r_float_bin(RFILE *p)
846{
847 const unsigned char *buf = (const unsigned char *) r_string(8, p);
848 if (buf == NULL)
849 return -1;
850 return _PyFloat_Unpack8(buf, 1);
851}
852
853/* Issue #33720: Disable inlining for reducing the C stack consumption
854 on PGO builds. */
855_Py_NO_INLINE static double
856r_float_str(RFILE *p)
857{
858 int n;
859 char buf[256];
860 const char *ptr;
861 n = r_byte(p);
862 if (n == EOF) {
863 PyErr_SetString(PyExc_EOFError,
864 "EOF read where object expected");
865 return -1;
866 }
867 ptr = r_string(n, p);
868 if (ptr == NULL) {
869 return -1;
870 }
871 memcpy(buf, ptr, n);
872 buf[n] = '\0';
873 return PyOS_string_to_double(buf, NULL, NULL);
874}
875
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700876/* allocate the reflist index for a new object. Return -1 on failure */
877static Py_ssize_t
878r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700879{
880 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200881 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700882 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700883 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700884 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700885 }
886 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700887 return -1;
888 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700889 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700890 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700891}
892
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700893/* insert the new object 'o' to the reflist at previously
894 * allocated index 'idx'.
895 * 'o' can be NULL, in which case nothing is done.
896 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
897 * if 'o' was non-NULL, and the function fails, 'o' is released and
898 * NULL returned. This simplifies error checking at the call site since
899 * a single test for NULL for the function result is enough.
900 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700901static PyObject *
902r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
903{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700904 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200905 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
906 Py_INCREF(o);
907 PyList_SET_ITEM(p->refs, idx, o);
908 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700909 }
910 return o;
911}
912
913/* combination of both above, used when an object can be
914 * created whenever it is seen in the file, as opposed to
915 * after having loaded its sub-objects.
916 */
917static PyObject *
918r_ref(PyObject *o, int flag, RFILE *p)
919{
Victor Stinner359fabc2013-10-31 17:09:01 +0100920 assert(flag & FLAG_REF);
921 if (o == NULL)
922 return NULL;
923 if (PyList_Append(p->refs, o) < 0) {
924 Py_DECREF(o); /* release the new object */
925 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700926 }
927 return o;
928}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000929
930static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000931r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 /* NULL is a valid return value, it does not necessarily means that
934 an exception is set. */
935 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500936 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700938 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200939 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200940 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000941
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700942 if (code == EOF) {
943 PyErr_SetString(PyExc_EOFError,
944 "EOF read where object expected");
945 return NULL;
946 }
947
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
951 p->depth--;
952 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
953 return NULL;
954 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000955
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700956 flag = code & FLAG_REF;
957 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700958
959#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700960 if (flag) \
961 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700962} while (0)
963
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000968
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 case TYPE_NONE:
970 Py_INCREF(Py_None);
971 retval = Py_None;
972 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 case TYPE_STOPITER:
975 Py_INCREF(PyExc_StopIteration);
976 retval = PyExc_StopIteration;
977 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 case TYPE_ELLIPSIS:
980 Py_INCREF(Py_Ellipsis);
981 retval = Py_Ellipsis;
982 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 case TYPE_FALSE:
985 Py_INCREF(Py_False);
986 retval = Py_False;
987 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 case TYPE_TRUE:
990 Py_INCREF(Py_True);
991 retval = Py_True;
992 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000993
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100995 n = r_long(p);
996 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700997 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000999
Serhiy Storchaka00987f62017-11-15 17:41:05 +02001000 case TYPE_INT64:
1001 retval = r_long64(p);
1002 R_REF(retval);
1003 break;
1004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 case TYPE_LONG:
1006 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001007 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001009
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 case TYPE_FLOAT:
1011 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001012 double x = r_float_str(p);
1013 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001015 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001016 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 break;
1018 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 case TYPE_BINARY_FLOAT:
1021 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001022 double x = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001023 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001026 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 break;
1028 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001029
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 case TYPE_COMPLEX:
1031 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001033 c.real = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 if (c.real == -1.0 && PyErr_Occurred())
1035 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001036 c.imag = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001037 if (c.imag == -1.0 && PyErr_Occurred())
1038 break;
1039 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001040 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 break;
1042 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 case TYPE_BINARY_COMPLEX:
1045 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001047 c.real = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001048 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001050 c.imag = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001051 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001054 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 break;
1056 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001059 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001060 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001061 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001062 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001063 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001064 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001065 PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001066 break;
1067 }
1068 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001069 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001070 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001071 ptr = r_string(n, p);
1072 if (ptr == NULL) {
1073 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001074 break;
1075 }
1076 memcpy(PyBytes_AS_STRING(v), ptr, n);
1077 retval = v;
1078 R_REF(retval);
1079 break;
1080 }
1081
1082 case TYPE_ASCII_INTERNED:
1083 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001084 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001085 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001087 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001088 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001089 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001090 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 break;
1092 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001093 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001094
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001095 case TYPE_SHORT_ASCII_INTERNED:
1096 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001097 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001098 case TYPE_SHORT_ASCII:
1099 n = r_byte(p);
1100 if (n == EOF) {
1101 PyErr_SetString(PyExc_EOFError,
1102 "EOF read where object expected");
1103 break;
1104 }
1105 _read_ascii:
1106 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001107 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001108 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001109 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001110 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001111 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001112 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001113 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001114 if (is_interned)
1115 PyUnicode_InternInPlace(&v);
1116 retval = v;
1117 R_REF(retval);
1118 break;
1119 }
1120
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001121 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001122 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001123 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001124 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001126 const char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001129 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001130 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001131 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001132 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 break;
1134 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001135 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001136 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001137 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001138 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001139 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001141 else {
1142 v = PyUnicode_New(0, 0);
1143 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001144 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001145 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001146 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001147 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001149 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 break;
1151 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001152
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001153 case TYPE_SMALL_TUPLE:
1154 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001155 if (PyErr_Occurred())
1156 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001157 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 case TYPE_TUPLE:
1159 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001160 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001161 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001162 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 break;
1165 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001166 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001167 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001168 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001169 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 for (i = 0; i < n; i++) {
1173 v2 = r_object(p);
1174 if ( v2 == NULL ) {
1175 if (!PyErr_Occurred())
1176 PyErr_SetString(PyExc_TypeError,
1177 "NULL object in marshal data for tuple");
1178 Py_DECREF(v);
1179 v = NULL;
1180 break;
1181 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001182 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 }
1184 retval = v;
1185 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001186
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 case TYPE_LIST:
1188 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001189 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001190 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001191 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 break;
1194 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001195 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001196 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001197 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 for (i = 0; i < n; i++) {
1200 v2 = r_object(p);
1201 if ( v2 == NULL ) {
1202 if (!PyErr_Occurred())
1203 PyErr_SetString(PyExc_TypeError,
1204 "NULL object in marshal data for list");
1205 Py_DECREF(v);
1206 v = NULL;
1207 break;
1208 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001209 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 }
1211 retval = v;
1212 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 case TYPE_DICT:
1215 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001216 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001217 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 for (;;) {
1220 PyObject *key, *val;
1221 key = r_object(p);
1222 if (key == NULL)
1223 break;
1224 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001225 if (val == NULL) {
1226 Py_DECREF(key);
1227 break;
1228 }
1229 if (PyDict_SetItem(v, key, val) < 0) {
1230 Py_DECREF(key);
1231 Py_DECREF(val);
1232 break;
1233 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001235 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 }
1237 if (PyErr_Occurred()) {
1238 Py_DECREF(v);
1239 v = NULL;
1240 }
1241 retval = v;
1242 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001243
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 case TYPE_SET:
1245 case TYPE_FROZENSET:
1246 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001247 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001248 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001249 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 break;
1252 }
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001253
Victor Stinner1aa78932016-01-23 14:15:48 +01001254 if (n == 0 && type == TYPE_FROZENSET) {
1255 /* call frozenset() to get the empty frozenset singleton */
Victor Stinner4778eab2016-12-01 14:51:04 +01001256 v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type);
Victor Stinner1aa78932016-01-23 14:15:48 +01001257 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 break;
Victor Stinner1aa78932016-01-23 14:15:48 +01001259 R_REF(v);
1260 retval = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 }
Victor Stinner1aa78932016-01-23 14:15:48 +01001262 else {
1263 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1264 if (type == TYPE_SET) {
1265 R_REF(v);
1266 } else {
1267 /* must use delayed registration of frozensets because they must
1268 * be init with a refcount of 1
1269 */
1270 idx = r_ref_reserve(flag, p);
1271 if (idx < 0)
1272 Py_CLEAR(v); /* signal error */
1273 }
1274 if (v == NULL)
1275 break;
1276
1277 for (i = 0; i < n; i++) {
1278 v2 = r_object(p);
1279 if ( v2 == NULL ) {
1280 if (!PyErr_Occurred())
1281 PyErr_SetString(PyExc_TypeError,
1282 "NULL object in marshal data for set");
1283 Py_DECREF(v);
1284 v = NULL;
1285 break;
1286 }
1287 if (PySet_Add(v, v2) == -1) {
1288 Py_DECREF(v);
1289 Py_DECREF(v2);
1290 v = NULL;
1291 break;
1292 }
1293 Py_DECREF(v2);
1294 }
1295 if (type != TYPE_SET)
1296 v = r_ref_insert(v, idx, flag, p);
1297 retval = v;
1298 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 case TYPE_CODE:
1302 {
1303 int argcount;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001304 int posonlyargcount;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001305 int kwonlyargcount;
1306 int nlocals;
1307 int stacksize;
1308 int flags;
1309 PyObject *code = NULL;
1310 PyObject *consts = NULL;
1311 PyObject *names = NULL;
1312 PyObject *varnames = NULL;
1313 PyObject *freevars = NULL;
1314 PyObject *cellvars = NULL;
1315 PyObject *filename = NULL;
1316 PyObject *name = NULL;
1317 int firstlineno;
1318 PyObject *lnotab = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001319
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001320 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001321 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001322 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 /* XXX ignore long->int overflows for now */
1327 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001328 if (PyErr_Occurred())
1329 goto code_error;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001330 posonlyargcount = (int)r_long(p);
1331 if (PyErr_Occurred()) {
1332 goto code_error;
1333 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 kwonlyargcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001335 if (PyErr_Occurred())
1336 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 nlocals = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001338 if (PyErr_Occurred())
1339 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 stacksize = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001341 if (PyErr_Occurred())
1342 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 flags = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001344 if (PyErr_Occurred())
1345 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 code = r_object(p);
1347 if (code == NULL)
1348 goto code_error;
1349 consts = r_object(p);
1350 if (consts == NULL)
1351 goto code_error;
1352 names = r_object(p);
1353 if (names == NULL)
1354 goto code_error;
1355 varnames = r_object(p);
1356 if (varnames == NULL)
1357 goto code_error;
1358 freevars = r_object(p);
1359 if (freevars == NULL)
1360 goto code_error;
1361 cellvars = r_object(p);
1362 if (cellvars == NULL)
1363 goto code_error;
1364 filename = r_object(p);
1365 if (filename == NULL)
1366 goto code_error;
1367 name = r_object(p);
1368 if (name == NULL)
1369 goto code_error;
1370 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001371 if (firstlineno == -1 && PyErr_Occurred())
1372 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 lnotab = r_object(p);
1374 if (lnotab == NULL)
1375 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001376
Pablo Galindo4a2edc32019-07-01 11:35:05 +01001377 v = (PyObject *) PyCode_NewWithPosOnlyArgs(
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001378 argcount, posonlyargcount, kwonlyargcount,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 nlocals, stacksize, flags,
1380 code, consts, names, varnames,
1381 freevars, cellvars, filename, name,
1382 firstlineno, lnotab);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001383 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 code_error:
1386 Py_XDECREF(code);
1387 Py_XDECREF(consts);
1388 Py_XDECREF(names);
1389 Py_XDECREF(varnames);
1390 Py_XDECREF(freevars);
1391 Py_XDECREF(cellvars);
1392 Py_XDECREF(filename);
1393 Py_XDECREF(name);
1394 Py_XDECREF(lnotab);
1395 }
1396 retval = v;
1397 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001398
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001399 case TYPE_REF:
1400 n = r_long(p);
1401 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001402 if (n == -1 && PyErr_Occurred())
1403 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001404 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001405 break;
1406 }
1407 v = PyList_GET_ITEM(p->refs, n);
1408 if (v == Py_None) {
1409 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001410 break;
1411 }
1412 Py_INCREF(v);
1413 retval = v;
1414 break;
1415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 default:
1417 /* Bogus data got written, which isn't ideal.
1418 This will let you keep working and recover. */
1419 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 break;
1421
1422 }
1423 p->depth--;
1424 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001425}
1426
Neal Norwitzd85c4522004-06-13 20:31:49 +00001427static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001428read_object(RFILE *p)
1429{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001430 PyObject *v;
1431 if (PyErr_Occurred()) {
1432 fprintf(stderr, "XXX readobject called with exception set\n");
1433 return NULL;
1434 }
1435 v = r_object(p);
1436 if (v == NULL && !PyErr_Occurred())
1437 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1438 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001439}
1440
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001441int
1442PyMarshal_ReadShortFromFile(FILE *fp)
1443{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001445 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001447 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 rf.fp = fp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001449 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001450 rf.buf = NULL;
1451 res = r_short(&rf);
1452 if (rf.buf != NULL)
1453 PyMem_FREE(rf.buf);
1454 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001455}
1456
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001457long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001458PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001461 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001463 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001465 rf.buf = NULL;
1466 res = r_long(&rf);
1467 if (rf.buf != NULL)
1468 PyMem_FREE(rf.buf);
1469 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001470}
1471
Steve Dowerf2f373f2015-02-21 08:44:05 -08001472/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001473static off_t
1474getfilesize(FILE *fp)
1475{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001476 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001477 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001479#if SIZEOF_OFF_T == 4
1480 else if (st.st_size >= INT_MAX)
1481 return (off_t)INT_MAX;
1482#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001484 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001485}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001486
Tim Peters691e0e92001-01-18 04:39:16 +00001487/* If we can get the size of the file up-front, and it's reasonably small,
1488 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1489 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001490 * CAUTION: since this may read the entire remainder of the file, don't
1491 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001492 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001493PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001494PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001495{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001496/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001497#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 off_t filesize;
1499 filesize = getfilesize(fp);
1500 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1501 char* pBuf = (char *)PyMem_MALLOC(filesize);
1502 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001503 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1504 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 PyMem_FREE(pBuf);
1506 return v;
1507 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 /* We don't have fstat, or we do but the file is larger than
1511 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1512 */
1513 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001514
Tim Peters691e0e92001-01-18 04:39:16 +00001515#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001516}
1517
Guido van Rossum79f25d91997-04-29 20:08:16 +00001518PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001519PyMarshal_ReadObjectFromFile(FILE *fp)
1520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 RFILE rf;
1522 PyObject *result;
1523 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001524 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 rf.depth = 0;
1526 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001527 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001528 rf.refs = PyList_New(0);
1529 if (rf.refs == NULL)
1530 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001532 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001533 if (rf.buf != NULL)
1534 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001536}
1537
1538PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001539PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001540{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 RFILE rf;
1542 PyObject *result;
1543 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001544 rf.readable = NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001545 rf.ptr = str;
1546 rf.end = str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001547 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001549 rf.refs = PyList_New(0);
1550 if (rf.refs == NULL)
1551 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001553 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001554 if (rf.buf != NULL)
1555 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001556 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001557}
1558
Guido van Rossum79f25d91997-04-29 20:08:16 +00001559PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001560PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001561{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001563
Serhiy Storchakace921c622015-02-11 15:53:31 +02001564 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1566 if (wf.str == NULL)
1567 return NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001568 wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
1569 wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001572 if (w_init_refs(&wf, version)) {
1573 Py_DECREF(wf.str);
1574 return NULL;
1575 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001577 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 if (wf.str != NULL) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001579 const char *base = PyBytes_AS_STRING(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1581 return NULL;
1582 }
1583 if (wf.error != WFERR_OK) {
1584 Py_XDECREF(wf.str);
1585 if (wf.error == WFERR_NOMEMORY)
1586 PyErr_NoMemory();
1587 else
1588 PyErr_SetString(PyExc_ValueError,
1589 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1590 :"object too deeply nested to marshal");
1591 return NULL;
1592 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001593 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001594}
1595
Guido van Rossum64b45521991-06-07 13:58:22 +00001596/* And an interface for Python programs... */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001597/*[clinic input]
1598marshal.dump
1599
1600 value: object
1601 Must be a supported type.
1602 file: object
1603 Must be a writeable binary file.
1604 version: int(c_default="Py_MARSHAL_VERSION") = version
1605 Indicates the data format that dump should use.
1606 /
1607
1608Write the value on the open file.
1609
1610If the value has (or contains an object that has) an unsupported type, a
1611ValueError exception is raised - but garbage data will also be written
1612to the file. The object will not be properly read back by load().
1613[clinic start generated code]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001614
Guido van Rossum79f25d91997-04-29 20:08:16 +00001615static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001616marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
1617 int version)
1618/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001619{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001620 /* XXX Quick hack -- need to do this differently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001621 PyObject *s;
1622 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001623 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001624
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001625 s = PyMarshal_WriteObjectToString(value, version);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001626 if (s == NULL)
1627 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001628 res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001629 Py_DECREF(s);
1630 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001631}
1632
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001633/*[clinic input]
1634marshal.load
1635
1636 file: object
1637 Must be readable binary file.
1638 /
1639
1640Read one value from the open file and return it.
1641
1642If no valid value is read (e.g. because the data has a different Python
1643version's incompatible marshal format), raise EOFError, ValueError or
1644TypeError.
1645
1646Note: If an object containing an unsupported type was marshalled with
1647dump(), load() will substitute None for the unmarshallable type.
1648[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001649
Guido van Rossum79f25d91997-04-29 20:08:16 +00001650static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001651marshal_load(PyObject *module, PyObject *file)
1652/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001655 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001657
1658 /*
1659 * Make a call to the read method, but read zero bytes.
1660 * This is to ensure that the object passed in at least
1661 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001662 * This can be removed if we guarantee good error handling
1663 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001664 */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001665 data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001666 if (data == NULL)
1667 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001668 if (!PyBytes_Check(data)) {
1669 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001670 "file.read() returned not bytes but %.100s",
Victor Stinnera102ed72020-02-07 02:24:48 +01001671 Py_TYPE(data)->tp_name);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001672 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001673 }
1674 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001675 rf.depth = 0;
1676 rf.fp = NULL;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001677 rf.readable = file;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001678 rf.ptr = rf.end = NULL;
1679 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001680 if ((rf.refs = PyList_New(0)) != NULL) {
1681 result = read_object(&rf);
1682 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001683 if (rf.buf != NULL)
1684 PyMem_FREE(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001685 } else
1686 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001687 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001688 Py_DECREF(data);
1689 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001690}
1691
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001692/*[clinic input]
1693marshal.dumps
R. David Murraydd226ea2009-05-13 12:27:21 +00001694
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001695 value: object
1696 Must be a supported type.
1697 version: int(c_default="Py_MARSHAL_VERSION") = version
1698 Indicates the data format that dumps should use.
1699 /
1700
1701Return the bytes object that would be written to a file by dump(value, file).
1702
1703Raise a ValueError exception if value has (or contains an object that has) an
1704unsupported type.
1705[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001706
Guido van Rossum79f25d91997-04-29 20:08:16 +00001707static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001708marshal_dumps_impl(PyObject *module, PyObject *value, int version)
1709/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001710{
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001711 return PyMarshal_WriteObjectToString(value, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001712}
1713
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001714/*[clinic input]
1715marshal.loads
R. David Murraydd226ea2009-05-13 12:27:21 +00001716
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001717 bytes: Py_buffer
1718 /
1719
1720Convert the bytes-like object to a value.
1721
1722If no valid value is found, raise EOFError, ValueError or TypeError. Extra
1723bytes in the input are ignored.
1724[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001725
Guido van Rossum79f25d91997-04-29 20:08:16 +00001726static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001727marshal_loads_impl(PyObject *module, Py_buffer *bytes)
1728/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001730 RFILE rf;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001731 char *s = bytes->buf;
1732 Py_ssize_t n = bytes->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001733 PyObject* result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001734 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001735 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 rf.ptr = s;
1737 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001739 if ((rf.refs = PyList_New(0)) == NULL)
1740 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001741 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001742 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001744}
1745
Guido van Rossum79f25d91997-04-29 20:08:16 +00001746static PyMethodDef marshal_methods[] = {
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001747 MARSHAL_DUMP_METHODDEF
1748 MARSHAL_LOAD_METHODDEF
1749 MARSHAL_DUMPS_METHODDEF
1750 MARSHAL_LOADS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001752};
1753
R. David Murraydd226ea2009-05-13 12:27:21 +00001754
1755PyDoc_STRVAR(module_doc,
1756"This module contains functions that can read and write Python values in\n\
1757a binary format. The format is specific to Python, but independent of\n\
1758machine architecture issues.\n\
1759\n\
1760Not all Python object types are supported; in general, only objects\n\
1761whose value is independent from a particular invocation of Python can be\n\
1762written and read by this module. The following types are supported:\n\
1763None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1764tuples, lists, sets, dictionaries, and code objects, where it\n\
1765should be understood that tuples, lists and dictionaries are only\n\
1766supported as long as the values contained therein are themselves\n\
1767supported; and recursive lists and dictionaries should not be written\n\
1768(they will cause infinite loops).\n\
1769\n\
1770Variables:\n\
1771\n\
1772version -- indicates the format that the module uses. Version 0 is the\n\
1773 historical format, version 1 shares interned strings and version 2\n\
1774 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001775 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001776\n\
1777Functions:\n\
1778\n\
1779dump() -- write value to a file\n\
1780load() -- read value from a file\n\
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001781dumps() -- marshal value as a bytes object\n\
1782loads() -- read value from a bytes-like object");
R. David Murraydd226ea2009-05-13 12:27:21 +00001783
1784
1785
Brett Cannon429ef652008-06-27 00:35:35 +00001786static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001787 PyModuleDef_HEAD_INIT,
1788 "marshal",
1789 module_doc,
1790 0,
1791 marshal_methods,
1792 NULL,
1793 NULL,
1794 NULL,
1795 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001796};
1797
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001798PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001799PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001800{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 PyObject *mod = PyModule_Create(&marshalmodule);
1802 if (mod == NULL)
1803 return NULL;
Brandt Bucher33b671e2019-11-19 16:59:32 -08001804 if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1805 Py_DECREF(mod);
1806 return NULL;
1807 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001808 return mod;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001809}