blob: 41252406060def50e232ee9857afa81f36205a37 [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 Stinner5b0a3032020-05-13 04:40:30 +0200305 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 Stinner5b0a3032020-05-13 04:40:30 +0200308 w = (int)(uintptr_t)entry->value;
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 {
Victor Stinnera482dc52020-05-14 21:55:47 +0200315 size_t s = p->hashtable->nentries;
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);
Victor Stinner5b0a3032020-05-13 04:40:30 +0200323 if (_Py_hashtable_set(p->hashtable, v, (void *)(uintptr_t)w) < 0) {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200324 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);
Mark Shannon877df852020-11-12 09:43:29 +0000527 w_object(co->co_linetable, p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 }
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
Victor Stinner2d0a3d62020-05-13 02:50:18 +0200548static void
549w_decref_entry(void *key)
550{
551 PyObject *entry_key = (PyObject *)key;
552 Py_XDECREF(entry_key);
553}
554
Serhiy Storchakace921c622015-02-11 15:53:31 +0200555static int
556w_init_refs(WFILE *wf, int version)
557{
558 if (version >= 3) {
Victor Stinner5b0a3032020-05-13 04:40:30 +0200559 wf->hashtable = _Py_hashtable_new_full(_Py_hashtable_hash_ptr,
Victor Stinner2d0a3d62020-05-13 02:50:18 +0200560 _Py_hashtable_compare_direct,
561 w_decref_entry, NULL, NULL);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200562 if (wf->hashtable == NULL) {
563 PyErr_NoMemory();
564 return -1;
565 }
566 }
567 return 0;
568}
569
Serhiy Storchakace921c622015-02-11 15:53:31 +0200570static void
571w_clear_refs(WFILE *wf)
572{
573 if (wf->hashtable != NULL) {
Serhiy Storchakace921c622015-02-11 15:53:31 +0200574 _Py_hashtable_destroy(wf->hashtable);
575 }
576}
577
Serhiy Storchaka95949422013-08-27 19:40:23 +0300578/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000579void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000580PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000581{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200582 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200584 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200586 wf.ptr = wf.buf = buf;
587 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 wf.version = version;
590 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200591 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000592}
593
594void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000595PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000596{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200597 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000598 WFILE wf;
Steve Dowera5764d32021-06-30 18:52:25 +0100599 if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
600 return; /* caller must check PyErr_Occurred() */
601 }
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;
Steve Dowera5764d32021-06-30 18:52:25 +0100608 if (w_init_refs(&wf, version)) {
609 return; /* caller must check PyErr_Occurred() */
610 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200612 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200613 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000614}
615
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200616typedef struct {
617 FILE *fp;
618 int depth;
619 PyObject *readable; /* Stream-like object being read from */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300620 const char *ptr;
621 const char *end;
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200622 char *buf;
623 Py_ssize_t buf_size;
624 PyObject *refs; /* a list */
625} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000626
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200627static const char *
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200628r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200630 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100631
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200632 if (p->ptr != NULL) {
633 /* Fast path for loads() */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300634 const char *res = p->ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200635 Py_ssize_t left = p->end - p->ptr;
636 if (left < n) {
637 PyErr_SetString(PyExc_EOFError,
638 "marshal data too short");
639 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100640 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200641 p->ptr += n;
642 return res;
643 }
644 if (p->buf == NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +0100645 p->buf = PyMem_Malloc(n);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200646 if (p->buf == NULL) {
647 PyErr_NoMemory();
648 return NULL;
649 }
650 p->buf_size = n;
651 }
652 else if (p->buf_size < n) {
Victor Stinner00d7abd2020-12-01 09:56:42 +0100653 char *tmp = PyMem_Realloc(p->buf, n);
Zackery Spytz4c49da02018-12-07 03:11:30 -0700654 if (tmp == NULL) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200655 PyErr_NoMemory();
656 return NULL;
657 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700658 p->buf = tmp;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200659 p->buf_size = n;
660 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100661
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200662 if (!p->readable) {
663 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200664 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100665 }
666 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200667 _Py_IDENTIFIER(readinto);
668 PyObject *res, *mview;
669 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200670
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200671 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
672 return NULL;
673 mview = PyMemoryView_FromBuffer(&buf);
674 if (mview == NULL)
675 return NULL;
676
677 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
678 if (res != NULL) {
679 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
680 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100681 }
682 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200683 if (read != n) {
684 if (!PyErr_Occurred()) {
685 if (read > n)
686 PyErr_Format(PyExc_ValueError,
687 "read() returned too much data: "
688 "%zd bytes requested, %zd returned",
689 n, read);
690 else
691 PyErr_SetString(PyExc_EOFError,
692 "EOF read where not expected");
693 }
694 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100695 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200696 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100697}
698
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100699static int
700r_byte(RFILE *p)
701{
702 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100703
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200704 if (p->ptr != NULL) {
705 if (p->ptr < p->end)
706 c = (unsigned char) *p->ptr++;
707 return c;
708 }
709 if (!p->readable) {
710 assert(p->fp);
711 c = getc(p->fp);
712 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100713 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200714 const char *ptr = r_string(1, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200715 if (ptr != NULL)
Andy Lestere6be9b52020-02-11 20:28:35 -0600716 c = *(const unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100717 }
718 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000719}
720
721static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000722r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000723{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200724 short x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200725 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100726
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200727 buffer = (const unsigned char *) r_string(2, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200728 if (buffer != NULL) {
729 x = buffer[0];
730 x |= buffer[1] << 8;
731 /* Sign-extension, in case short greater than 16 bits */
732 x |= -(x & 0x8000);
733 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000735}
736
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000737static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000738r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000739{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200740 long x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200741 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100742
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200743 buffer = (const unsigned char *) r_string(4, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200744 if (buffer != NULL) {
745 x = buffer[0];
746 x |= (long)buffer[1] << 8;
747 x |= (long)buffer[2] << 16;
748 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000749#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200750 /* Sign extension for 64-bit machines */
751 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000752#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200753 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000755}
756
Serhiy Storchaka00987f62017-11-15 17:41:05 +0200757/* r_long64 deals with the TYPE_INT64 code. */
758static PyObject *
759r_long64(RFILE *p)
760{
761 const unsigned char *buffer = (const unsigned char *) r_string(8, p);
762 if (buffer == NULL) {
763 return NULL;
764 }
765 return _PyLong_FromByteArray(buffer, 8,
766 1 /* little endian */,
767 1 /* signed */);
768}
769
Guido van Rossum79f25d91997-04-29 20:08:16 +0000770static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000771r_PyLong(RFILE *p)
772{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200774 long n, size, i;
775 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100779 if (PyErr_Occurred())
780 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 if (n == 0)
782 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200783 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 PyErr_SetString(PyExc_ValueError,
785 "bad marshal data (long size out of range)");
786 return NULL;
787 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000788
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200789 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
790 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000791 ob = _PyLong_New(size);
792 if (ob == NULL)
793 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100794
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100795 Py_SET_SIZE(ob, n > 0 ? size : -size);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000796
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 for (i = 0; i < size-1; i++) {
798 d = 0;
799 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
800 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100801 if (PyErr_Occurred()) {
802 Py_DECREF(ob);
803 return NULL;
804 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 if (md < 0 || md > PyLong_MARSHAL_BASE)
806 goto bad_digit;
807 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
808 }
809 ob->ob_digit[i] = d;
810 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100811
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000812 d = 0;
813 for (j=0; j < shorts_in_top_digit; j++) {
814 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100815 if (PyErr_Occurred()) {
816 Py_DECREF(ob);
817 return NULL;
818 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 if (md < 0 || md > PyLong_MARSHAL_BASE)
820 goto bad_digit;
821 /* topmost marshal digit should be nonzero */
822 if (md == 0 && j == shorts_in_top_digit - 1) {
823 Py_DECREF(ob);
824 PyErr_SetString(PyExc_ValueError,
825 "bad marshal data (unnormalized long data)");
826 return NULL;
827 }
828 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
829 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100830 if (PyErr_Occurred()) {
831 Py_DECREF(ob);
832 return NULL;
833 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 /* top digit should be nonzero, else the resulting PyLong won't be
835 normalized */
836 ob->ob_digit[size-1] = d;
837 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000838 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 Py_DECREF(ob);
840 PyErr_SetString(PyExc_ValueError,
841 "bad marshal data (digit out of range in long)");
842 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000843}
844
Serhiy Storchakac5734992018-07-24 10:55:47 +0300845static double
846r_float_bin(RFILE *p)
847{
848 const unsigned char *buf = (const unsigned char *) r_string(8, p);
849 if (buf == NULL)
850 return -1;
851 return _PyFloat_Unpack8(buf, 1);
852}
853
854/* Issue #33720: Disable inlining for reducing the C stack consumption
855 on PGO builds. */
856_Py_NO_INLINE static double
857r_float_str(RFILE *p)
858{
859 int n;
860 char buf[256];
861 const char *ptr;
862 n = r_byte(p);
863 if (n == EOF) {
864 PyErr_SetString(PyExc_EOFError,
865 "EOF read where object expected");
866 return -1;
867 }
868 ptr = r_string(n, p);
869 if (ptr == NULL) {
870 return -1;
871 }
872 memcpy(buf, ptr, n);
873 buf[n] = '\0';
874 return PyOS_string_to_double(buf, NULL, NULL);
875}
876
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700877/* allocate the reflist index for a new object. Return -1 on failure */
878static Py_ssize_t
879r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700880{
881 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200882 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700883 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700884 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700885 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700886 }
887 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700888 return -1;
889 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700890 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700891 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700892}
893
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700894/* insert the new object 'o' to the reflist at previously
895 * allocated index 'idx'.
896 * 'o' can be NULL, in which case nothing is done.
897 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
898 * if 'o' was non-NULL, and the function fails, 'o' is released and
899 * NULL returned. This simplifies error checking at the call site since
900 * a single test for NULL for the function result is enough.
901 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700902static PyObject *
903r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
904{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700905 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200906 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
907 Py_INCREF(o);
908 PyList_SET_ITEM(p->refs, idx, o);
909 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700910 }
911 return o;
912}
913
914/* combination of both above, used when an object can be
915 * created whenever it is seen in the file, as opposed to
916 * after having loaded its sub-objects.
917 */
918static PyObject *
919r_ref(PyObject *o, int flag, RFILE *p)
920{
Victor Stinner359fabc2013-10-31 17:09:01 +0100921 assert(flag & FLAG_REF);
922 if (o == NULL)
923 return NULL;
924 if (PyList_Append(p->refs, o) < 0) {
925 Py_DECREF(o); /* release the new object */
926 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700927 }
928 return o;
929}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000930
931static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000932r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000933{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 /* NULL is a valid return value, it does not necessarily means that
935 an exception is set. */
936 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500937 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700939 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200940 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200941 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000942
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700943 if (code == EOF) {
944 PyErr_SetString(PyExc_EOFError,
945 "EOF read where object expected");
946 return NULL;
947 }
948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
952 p->depth--;
953 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
954 return NULL;
955 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000956
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700957 flag = code & FLAG_REF;
958 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700959
960#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700961 if (flag) \
962 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700963} while (0)
964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 case TYPE_NONE:
971 Py_INCREF(Py_None);
972 retval = Py_None;
973 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000974
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 case TYPE_STOPITER:
976 Py_INCREF(PyExc_StopIteration);
977 retval = PyExc_StopIteration;
978 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000979
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000980 case TYPE_ELLIPSIS:
981 Py_INCREF(Py_Ellipsis);
982 retval = Py_Ellipsis;
983 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000984
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 case TYPE_FALSE:
986 Py_INCREF(Py_False);
987 retval = Py_False;
988 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 case TYPE_TRUE:
991 Py_INCREF(Py_True);
992 retval = Py_True;
993 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000994
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100996 n = r_long(p);
997 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700998 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001000
Serhiy Storchaka00987f62017-11-15 17:41:05 +02001001 case TYPE_INT64:
1002 retval = r_long64(p);
1003 R_REF(retval);
1004 break;
1005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 case TYPE_LONG:
1007 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001008 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001010
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001011 case TYPE_FLOAT:
1012 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001013 double x = r_float_str(p);
1014 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001015 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001016 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001017 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 break;
1019 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 case TYPE_BINARY_FLOAT:
1022 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001023 double x = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001024 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001025 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001027 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 break;
1029 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001030
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 case TYPE_COMPLEX:
1032 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001034 c.real = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 if (c.real == -1.0 && PyErr_Occurred())
1036 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001037 c.imag = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001038 if (c.imag == -1.0 && PyErr_Occurred())
1039 break;
1040 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001041 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 break;
1043 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 case TYPE_BINARY_COMPLEX:
1046 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001048 c.real = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001049 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001050 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001051 c.imag = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001052 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001055 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 break;
1057 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001060 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001061 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001062 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001063 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001064 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001065 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001066 PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001067 break;
1068 }
1069 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001070 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001071 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001072 ptr = r_string(n, p);
1073 if (ptr == NULL) {
1074 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001075 break;
1076 }
1077 memcpy(PyBytes_AS_STRING(v), ptr, n);
1078 retval = v;
1079 R_REF(retval);
1080 break;
1081 }
1082
1083 case TYPE_ASCII_INTERNED:
1084 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001085 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001086 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001088 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001089 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001090 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001091 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 break;
1093 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001094 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001095
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001096 case TYPE_SHORT_ASCII_INTERNED:
1097 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001098 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001099 case TYPE_SHORT_ASCII:
1100 n = r_byte(p);
1101 if (n == EOF) {
1102 PyErr_SetString(PyExc_EOFError,
1103 "EOF read where object expected");
1104 break;
1105 }
1106 _read_ascii:
1107 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001108 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001109 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001110 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001111 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001112 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001113 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001114 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001115 if (is_interned)
1116 PyUnicode_InternInPlace(&v);
1117 retval = v;
1118 R_REF(retval);
1119 break;
1120 }
1121
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001122 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001123 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001124 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001125 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001127 const char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001128
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001130 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001131 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001132 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001133 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 break;
1135 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001136 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001137 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001138 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001139 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001140 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001141 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001142 else {
1143 v = PyUnicode_New(0, 0);
1144 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001145 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001146 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001147 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001148 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001150 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 break;
1152 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001153
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001154 case TYPE_SMALL_TUPLE:
1155 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001156 if (PyErr_Occurred())
1157 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001158 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 case TYPE_TUPLE:
1160 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001161 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001162 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001163 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 break;
1166 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001167 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001168 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001169 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001170 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001171 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 for (i = 0; i < n; i++) {
1174 v2 = r_object(p);
1175 if ( v2 == NULL ) {
1176 if (!PyErr_Occurred())
1177 PyErr_SetString(PyExc_TypeError,
1178 "NULL object in marshal data for tuple");
1179 Py_DECREF(v);
1180 v = NULL;
1181 break;
1182 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001183 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 }
1185 retval = v;
1186 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001187
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 case TYPE_LIST:
1189 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001190 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001191 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001192 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001193 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 break;
1195 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001196 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001197 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001198 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 for (i = 0; i < n; i++) {
1201 v2 = r_object(p);
1202 if ( v2 == NULL ) {
1203 if (!PyErr_Occurred())
1204 PyErr_SetString(PyExc_TypeError,
1205 "NULL object in marshal data for list");
1206 Py_DECREF(v);
1207 v = NULL;
1208 break;
1209 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001210 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 }
1212 retval = v;
1213 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 case TYPE_DICT:
1216 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001217 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001218 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 for (;;) {
1221 PyObject *key, *val;
1222 key = r_object(p);
1223 if (key == NULL)
1224 break;
1225 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001226 if (val == NULL) {
1227 Py_DECREF(key);
1228 break;
1229 }
1230 if (PyDict_SetItem(v, key, val) < 0) {
1231 Py_DECREF(key);
1232 Py_DECREF(val);
1233 break;
1234 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001236 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 }
1238 if (PyErr_Occurred()) {
1239 Py_DECREF(v);
1240 v = NULL;
1241 }
1242 retval = v;
1243 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 case TYPE_SET:
1246 case TYPE_FROZENSET:
1247 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001248 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001249 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001250 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 break;
1253 }
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001254
Victor Stinner1aa78932016-01-23 14:15:48 +01001255 if (n == 0 && type == TYPE_FROZENSET) {
1256 /* call frozenset() to get the empty frozenset singleton */
Victor Stinner4778eab2016-12-01 14:51:04 +01001257 v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type);
Victor Stinner1aa78932016-01-23 14:15:48 +01001258 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 break;
Victor Stinner1aa78932016-01-23 14:15:48 +01001260 R_REF(v);
1261 retval = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 }
Victor Stinner1aa78932016-01-23 14:15:48 +01001263 else {
1264 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1265 if (type == TYPE_SET) {
1266 R_REF(v);
1267 } else {
1268 /* must use delayed registration of frozensets because they must
1269 * be init with a refcount of 1
1270 */
1271 idx = r_ref_reserve(flag, p);
1272 if (idx < 0)
1273 Py_CLEAR(v); /* signal error */
1274 }
1275 if (v == NULL)
1276 break;
1277
1278 for (i = 0; i < n; i++) {
1279 v2 = r_object(p);
1280 if ( v2 == NULL ) {
1281 if (!PyErr_Occurred())
1282 PyErr_SetString(PyExc_TypeError,
1283 "NULL object in marshal data for set");
1284 Py_DECREF(v);
1285 v = NULL;
1286 break;
1287 }
1288 if (PySet_Add(v, v2) == -1) {
1289 Py_DECREF(v);
1290 Py_DECREF(v2);
1291 v = NULL;
1292 break;
1293 }
1294 Py_DECREF(v2);
1295 }
1296 if (type != TYPE_SET)
1297 v = r_ref_insert(v, idx, flag, p);
1298 retval = v;
1299 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 case TYPE_CODE:
1303 {
1304 int argcount;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001305 int posonlyargcount;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 int kwonlyargcount;
1307 int nlocals;
1308 int stacksize;
1309 int flags;
1310 PyObject *code = NULL;
1311 PyObject *consts = NULL;
1312 PyObject *names = NULL;
1313 PyObject *varnames = NULL;
1314 PyObject *freevars = NULL;
1315 PyObject *cellvars = NULL;
1316 PyObject *filename = NULL;
1317 PyObject *name = NULL;
1318 int firstlineno;
Mark Shannon877df852020-11-12 09:43:29 +00001319 PyObject *linetable = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001320
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001321 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001322 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001323 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 /* XXX ignore long->int overflows for now */
1328 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001329 if (PyErr_Occurred())
1330 goto code_error;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001331 posonlyargcount = (int)r_long(p);
1332 if (PyErr_Occurred()) {
1333 goto code_error;
1334 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 kwonlyargcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001336 if (PyErr_Occurred())
1337 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 nlocals = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001339 if (PyErr_Occurred())
1340 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 stacksize = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001342 if (PyErr_Occurred())
1343 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 flags = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001345 if (PyErr_Occurred())
1346 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 code = r_object(p);
1348 if (code == NULL)
1349 goto code_error;
1350 consts = r_object(p);
1351 if (consts == NULL)
1352 goto code_error;
1353 names = r_object(p);
1354 if (names == NULL)
1355 goto code_error;
1356 varnames = r_object(p);
1357 if (varnames == NULL)
1358 goto code_error;
1359 freevars = r_object(p);
1360 if (freevars == NULL)
1361 goto code_error;
1362 cellvars = r_object(p);
1363 if (cellvars == NULL)
1364 goto code_error;
1365 filename = r_object(p);
1366 if (filename == NULL)
1367 goto code_error;
1368 name = r_object(p);
1369 if (name == NULL)
1370 goto code_error;
1371 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001372 if (firstlineno == -1 && PyErr_Occurred())
1373 break;
Mark Shannon877df852020-11-12 09:43:29 +00001374 linetable = r_object(p);
1375 if (linetable == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001377
Pablo Galindo4a2edc32019-07-01 11:35:05 +01001378 v = (PyObject *) PyCode_NewWithPosOnlyArgs(
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001379 argcount, posonlyargcount, kwonlyargcount,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 nlocals, stacksize, flags,
1381 code, consts, names, varnames,
1382 freevars, cellvars, filename, name,
Mark Shannon877df852020-11-12 09:43:29 +00001383 firstlineno, linetable);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001384 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 code_error:
1387 Py_XDECREF(code);
1388 Py_XDECREF(consts);
1389 Py_XDECREF(names);
1390 Py_XDECREF(varnames);
1391 Py_XDECREF(freevars);
1392 Py_XDECREF(cellvars);
1393 Py_XDECREF(filename);
1394 Py_XDECREF(name);
Mark Shannon877df852020-11-12 09:43:29 +00001395 Py_XDECREF(linetable);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 }
1397 retval = v;
1398 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001399
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001400 case TYPE_REF:
1401 n = r_long(p);
1402 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001403 if (n == -1 && PyErr_Occurred())
1404 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001405 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001406 break;
1407 }
1408 v = PyList_GET_ITEM(p->refs, n);
1409 if (v == Py_None) {
1410 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001411 break;
1412 }
1413 Py_INCREF(v);
1414 retval = v;
1415 break;
1416
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 default:
1418 /* Bogus data got written, which isn't ideal.
1419 This will let you keep working and recover. */
1420 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001421 break;
1422
1423 }
1424 p->depth--;
1425 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001426}
1427
Neal Norwitzd85c4522004-06-13 20:31:49 +00001428static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001429read_object(RFILE *p)
1430{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 PyObject *v;
1432 if (PyErr_Occurred()) {
1433 fprintf(stderr, "XXX readobject called with exception set\n");
1434 return NULL;
1435 }
Steve Dowera5764d32021-06-30 18:52:25 +01001436 if (p->ptr && p->end) {
1437 if (PySys_Audit("marshal.loads", "y#", p->ptr, (Py_ssize_t)(p->end - p->ptr)) < 0) {
1438 return NULL;
1439 }
1440 } else if (p->fp || p->readable) {
1441 if (PySys_Audit("marshal.load", NULL) < 0) {
1442 return NULL;
1443 }
1444 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 v = r_object(p);
1446 if (v == NULL && !PyErr_Occurred())
1447 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1448 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001449}
1450
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001451int
1452PyMarshal_ReadShortFromFile(FILE *fp)
1453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001455 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001457 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 rf.fp = fp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001460 rf.buf = NULL;
1461 res = r_short(&rf);
1462 if (rf.buf != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001463 PyMem_Free(rf.buf);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001464 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001465}
1466
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001467long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001468PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001471 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001473 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001475 rf.buf = NULL;
1476 res = r_long(&rf);
1477 if (rf.buf != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001478 PyMem_Free(rf.buf);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001479 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001480}
1481
Steve Dowerf2f373f2015-02-21 08:44:05 -08001482/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001483static off_t
1484getfilesize(FILE *fp)
1485{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001486 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001487 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001489#if SIZEOF_OFF_T == 4
1490 else if (st.st_size >= INT_MAX)
1491 return (off_t)INT_MAX;
1492#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001494 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001495}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001496
Tim Peters691e0e92001-01-18 04:39:16 +00001497/* If we can get the size of the file up-front, and it's reasonably small,
1498 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1499 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001500 * CAUTION: since this may read the entire remainder of the file, don't
1501 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001502 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001503PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001504PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001505{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001506/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001507#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 off_t filesize;
1509 filesize = getfilesize(fp);
1510 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001511 char* pBuf = (char *)PyMem_Malloc(filesize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001513 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1514 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Victor Stinner00d7abd2020-12-01 09:56:42 +01001515 PyMem_Free(pBuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 return v;
1517 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 /* We don't have fstat, or we do but the file is larger than
1521 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1522 */
1523 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001524
Tim Peters691e0e92001-01-18 04:39:16 +00001525#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001526}
1527
Guido van Rossum79f25d91997-04-29 20:08:16 +00001528PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001529PyMarshal_ReadObjectFromFile(FILE *fp)
1530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001531 RFILE rf;
1532 PyObject *result;
1533 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001534 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 rf.depth = 0;
1536 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001537 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001538 rf.refs = PyList_New(0);
1539 if (rf.refs == NULL)
1540 return NULL;
Steve Dowera5764d32021-06-30 18:52:25 +01001541 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001542 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001543 if (rf.buf != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001544 PyMem_Free(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001546}
1547
1548PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001549PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001550{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 RFILE rf;
1552 PyObject *result;
1553 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001554 rf.readable = NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001555 rf.ptr = str;
1556 rf.end = str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001557 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001559 rf.refs = PyList_New(0);
1560 if (rf.refs == NULL)
1561 return NULL;
Steve Dowera5764d32021-06-30 18:52:25 +01001562 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001563 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001564 if (rf.buf != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001565 PyMem_Free(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001566 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001567}
1568
Guido van Rossum79f25d91997-04-29 20:08:16 +00001569PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001570PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001573
Steve Dowera5764d32021-06-30 18:52:25 +01001574 if (PySys_Audit("marshal.dumps", "Oi", x, version) < 0) {
1575 return NULL;
1576 }
Serhiy Storchakace921c622015-02-11 15:53:31 +02001577 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1579 if (wf.str == NULL)
1580 return NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001581 wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
1582 wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001584 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001585 if (w_init_refs(&wf, version)) {
1586 Py_DECREF(wf.str);
1587 return NULL;
1588 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001590 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001591 if (wf.str != NULL) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001592 const char *base = PyBytes_AS_STRING(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1594 return NULL;
1595 }
1596 if (wf.error != WFERR_OK) {
1597 Py_XDECREF(wf.str);
1598 if (wf.error == WFERR_NOMEMORY)
1599 PyErr_NoMemory();
1600 else
1601 PyErr_SetString(PyExc_ValueError,
1602 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1603 :"object too deeply nested to marshal");
1604 return NULL;
1605 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001606 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001607}
1608
Guido van Rossum64b45521991-06-07 13:58:22 +00001609/* And an interface for Python programs... */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001610/*[clinic input]
1611marshal.dump
1612
1613 value: object
1614 Must be a supported type.
1615 file: object
1616 Must be a writeable binary file.
1617 version: int(c_default="Py_MARSHAL_VERSION") = version
1618 Indicates the data format that dump should use.
1619 /
1620
1621Write the value on the open file.
1622
1623If the value has (or contains an object that has) an unsupported type, a
1624ValueError exception is raised - but garbage data will also be written
1625to the file. The object will not be properly read back by load().
1626[clinic start generated code]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001627
Guido van Rossum79f25d91997-04-29 20:08:16 +00001628static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001629marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
1630 int version)
1631/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 /* XXX Quick hack -- need to do this differently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001634 PyObject *s;
1635 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001636 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001637
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001638 s = PyMarshal_WriteObjectToString(value, version);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001639 if (s == NULL)
1640 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001641 res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 Py_DECREF(s);
1643 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001644}
1645
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001646/*[clinic input]
1647marshal.load
1648
1649 file: object
1650 Must be readable binary file.
1651 /
1652
1653Read one value from the open file and return it.
1654
1655If no valid value is read (e.g. because the data has a different Python
1656version's incompatible marshal format), raise EOFError, ValueError or
1657TypeError.
1658
1659Note: If an object containing an unsupported type was marshalled with
1660dump(), load() will substitute None for the unmarshallable type.
1661[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001662
Guido van Rossum79f25d91997-04-29 20:08:16 +00001663static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001664marshal_load(PyObject *module, PyObject *file)
1665/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001666{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001667 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001668 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001669 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001670
1671 /*
1672 * Make a call to the read method, but read zero bytes.
1673 * This is to ensure that the object passed in at least
1674 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001675 * This can be removed if we guarantee good error handling
1676 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001677 */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001678 data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001679 if (data == NULL)
1680 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001681 if (!PyBytes_Check(data)) {
1682 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001683 "file.read() returned not bytes but %.100s",
Victor Stinnera102ed72020-02-07 02:24:48 +01001684 Py_TYPE(data)->tp_name);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001685 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001686 }
1687 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001688 rf.depth = 0;
1689 rf.fp = NULL;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001690 rf.readable = file;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001691 rf.ptr = rf.end = NULL;
1692 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001693 if ((rf.refs = PyList_New(0)) != NULL) {
1694 result = read_object(&rf);
1695 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001696 if (rf.buf != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001697 PyMem_Free(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001698 } else
1699 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001700 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001701 Py_DECREF(data);
1702 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001703}
1704
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001705/*[clinic input]
1706marshal.dumps
R. David Murraydd226ea2009-05-13 12:27:21 +00001707
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001708 value: object
1709 Must be a supported type.
1710 version: int(c_default="Py_MARSHAL_VERSION") = version
1711 Indicates the data format that dumps should use.
1712 /
1713
1714Return the bytes object that would be written to a file by dump(value, file).
1715
1716Raise a ValueError exception if value has (or contains an object that has) an
1717unsupported type.
1718[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001719
Guido van Rossum79f25d91997-04-29 20:08:16 +00001720static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001721marshal_dumps_impl(PyObject *module, PyObject *value, int version)
1722/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001723{
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001724 return PyMarshal_WriteObjectToString(value, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001725}
1726
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001727/*[clinic input]
1728marshal.loads
R. David Murraydd226ea2009-05-13 12:27:21 +00001729
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001730 bytes: Py_buffer
1731 /
1732
1733Convert the bytes-like object to a value.
1734
1735If no valid value is found, raise EOFError, ValueError or TypeError. Extra
1736bytes in the input are ignored.
1737[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001738
Guido van Rossum79f25d91997-04-29 20:08:16 +00001739static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001740marshal_loads_impl(PyObject *module, Py_buffer *bytes)
1741/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 RFILE rf;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001744 char *s = bytes->buf;
1745 Py_ssize_t n = bytes->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 PyObject* result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001747 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001748 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001749 rf.ptr = s;
1750 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001751 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001752 if ((rf.refs = PyList_New(0)) == NULL)
1753 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001754 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001755 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001757}
1758
Guido van Rossum79f25d91997-04-29 20:08:16 +00001759static PyMethodDef marshal_methods[] = {
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001760 MARSHAL_DUMP_METHODDEF
1761 MARSHAL_LOAD_METHODDEF
1762 MARSHAL_DUMPS_METHODDEF
1763 MARSHAL_LOADS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001764 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001765};
1766
R. David Murraydd226ea2009-05-13 12:27:21 +00001767
1768PyDoc_STRVAR(module_doc,
1769"This module contains functions that can read and write Python values in\n\
1770a binary format. The format is specific to Python, but independent of\n\
1771machine architecture issues.\n\
1772\n\
1773Not all Python object types are supported; in general, only objects\n\
1774whose value is independent from a particular invocation of Python can be\n\
1775written and read by this module. The following types are supported:\n\
1776None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1777tuples, lists, sets, dictionaries, and code objects, where it\n\
1778should be understood that tuples, lists and dictionaries are only\n\
1779supported as long as the values contained therein are themselves\n\
1780supported; and recursive lists and dictionaries should not be written\n\
1781(they will cause infinite loops).\n\
1782\n\
1783Variables:\n\
1784\n\
1785version -- indicates the format that the module uses. Version 0 is the\n\
1786 historical format, version 1 shares interned strings and version 2\n\
1787 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001788 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001789\n\
1790Functions:\n\
1791\n\
1792dump() -- write value to a file\n\
1793load() -- read value from a file\n\
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001794dumps() -- marshal value as a bytes object\n\
1795loads() -- read value from a bytes-like object");
R. David Murraydd226ea2009-05-13 12:27:21 +00001796
1797
Victor Stinnerf3151422020-09-08 15:33:52 +02001798static int
1799marshal_module_exec(PyObject *mod)
1800{
1801 if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1802 return -1;
1803 }
1804 return 0;
1805}
1806
1807static PyModuleDef_Slot marshalmodule_slots[] = {
1808 {Py_mod_exec, marshal_module_exec},
1809 {0, NULL}
1810};
R. David Murraydd226ea2009-05-13 12:27:21 +00001811
Brett Cannon429ef652008-06-27 00:35:35 +00001812static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001813 PyModuleDef_HEAD_INIT,
Victor Stinnerf3151422020-09-08 15:33:52 +02001814 .m_name = "marshal",
1815 .m_doc = module_doc,
1816 .m_methods = marshal_methods,
1817 .m_slots = marshalmodule_slots,
Martin v. Löwis1a214512008-06-11 05:26:20 +00001818};
1819
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001820PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001821PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001822{
Victor Stinnerf3151422020-09-08 15:33:52 +02001823 return PyModuleDef_Init(&marshalmodule);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001824}