blob: b4429aea502d3fcfe29e1f77296ed4a721736915 [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"
Serhiy Storchakace921c622015-02-11 15:53:31 +020015#include "../Modules/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 Stinner285cf0a2016-03-21 22:00:58 +0100552 wf->hashtable = _Py_hashtable_new(sizeof(PyObject *), sizeof(int),
553 _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 Stinner285cf0a2016-03-21 22:00:58 +0100567 PyObject *entry_key;
568
Victor Stinner5dacbd42016-03-23 09:52:13 +0100569 _Py_HASHTABLE_ENTRY_READ_KEY(ht, entry, entry_key);
Victor Stinner285cf0a2016-03-21 22:00:58 +0100570 Py_XDECREF(entry_key);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200571 return 0;
572}
573
574static void
575w_clear_refs(WFILE *wf)
576{
577 if (wf->hashtable != NULL) {
578 _Py_hashtable_foreach(wf->hashtable, w_decref_entry, NULL);
579 _Py_hashtable_destroy(wf->hashtable);
580 }
581}
582
Serhiy Storchaka95949422013-08-27 19:40:23 +0300583/* version currently has no effect for writing ints. */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000584void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000585PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000586{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200587 char buf[4];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200589 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200591 wf.ptr = wf.buf = buf;
592 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 wf.version = version;
595 w_long(x, &wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200596 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000597}
598
599void
Martin v. Löwisef82d2f2004-06-27 16:51:46 +0000600PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000601{
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200602 char buf[BUFSIZ];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 WFILE wf;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200604 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 wf.fp = fp;
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200606 wf.ptr = wf.buf = buf;
607 wf.end = wf.ptr + sizeof(buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +0200610 if (w_init_refs(&wf, version))
611 return; /* caller mush check PyErr_Occurred() */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +0200613 w_clear_refs(&wf);
Serhiy Storchakac1efe5f2015-02-11 15:54:54 +0200614 w_flush(&wf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000615}
616
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200617typedef struct {
618 FILE *fp;
619 int depth;
620 PyObject *readable; /* Stream-like object being read from */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300621 const char *ptr;
622 const char *end;
Serhiy Storchakac07422c2015-02-11 16:18:09 +0200623 char *buf;
624 Py_ssize_t buf_size;
625 PyObject *refs; /* a list */
626} RFILE;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000627
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200628static const char *
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200629r_string(Py_ssize_t n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000630{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200631 Py_ssize_t read = -1;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100632
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200633 if (p->ptr != NULL) {
634 /* Fast path for loads() */
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +0300635 const char *res = p->ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200636 Py_ssize_t left = p->end - p->ptr;
637 if (left < n) {
638 PyErr_SetString(PyExc_EOFError,
639 "marshal data too short");
640 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100641 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200642 p->ptr += n;
643 return res;
644 }
645 if (p->buf == NULL) {
646 p->buf = PyMem_MALLOC(n);
647 if (p->buf == NULL) {
648 PyErr_NoMemory();
649 return NULL;
650 }
651 p->buf_size = n;
652 }
653 else if (p->buf_size < n) {
Zackery Spytz4c49da02018-12-07 03:11:30 -0700654 char *tmp = PyMem_REALLOC(p->buf, n);
655 if (tmp == NULL) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200656 PyErr_NoMemory();
657 return NULL;
658 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700659 p->buf = tmp;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200660 p->buf_size = n;
661 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100662
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200663 if (!p->readable) {
664 assert(p->fp != NULL);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200665 read = fread(p->buf, 1, n, p->fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100666 }
667 else {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200668 _Py_IDENTIFIER(readinto);
669 PyObject *res, *mview;
670 Py_buffer buf;
Martin v. Löwisafe55bb2011-10-09 10:38:36 +0200671
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200672 if (PyBuffer_FillInfo(&buf, NULL, p->buf, n, 0, PyBUF_CONTIG) == -1)
673 return NULL;
674 mview = PyMemoryView_FromBuffer(&buf);
675 if (mview == NULL)
676 return NULL;
677
678 res = _PyObject_CallMethodId(p->readable, &PyId_readinto, "N", mview);
679 if (res != NULL) {
680 read = PyNumber_AsSsize_t(res, PyExc_ValueError);
681 Py_DECREF(res);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100682 }
683 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200684 if (read != n) {
685 if (!PyErr_Occurred()) {
686 if (read > n)
687 PyErr_Format(PyExc_ValueError,
688 "read() returned too much data: "
689 "%zd bytes requested, %zd returned",
690 n, read);
691 else
692 PyErr_SetString(PyExc_EOFError,
693 "EOF read where not expected");
694 }
695 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100696 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200697 return p->buf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100698}
699
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100700static int
701r_byte(RFILE *p)
702{
703 int c = EOF;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100704
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200705 if (p->ptr != NULL) {
706 if (p->ptr < p->end)
707 c = (unsigned char) *p->ptr++;
708 return c;
709 }
710 if (!p->readable) {
711 assert(p->fp);
712 c = getc(p->fp);
713 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100714 else {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200715 const char *ptr = r_string(1, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200716 if (ptr != NULL)
Andy Lestere6be9b52020-02-11 20:28:35 -0600717 c = *(const unsigned char *) ptr;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100718 }
719 return c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000720}
721
722static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000723r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000724{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200725 short x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200726 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100727
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200728 buffer = (const unsigned char *) r_string(2, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200729 if (buffer != NULL) {
730 x = buffer[0];
731 x |= buffer[1] << 8;
732 /* Sign-extension, in case short greater than 16 bits */
733 x |= -(x & 0x8000);
734 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 return x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000736}
737
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000738static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000739r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000740{
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200741 long x = -1;
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200742 const unsigned char *buffer;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100743
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200744 buffer = (const unsigned char *) r_string(4, p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200745 if (buffer != NULL) {
746 x = buffer[0];
747 x |= (long)buffer[1] << 8;
748 x |= (long)buffer[2] << 16;
749 x |= (long)buffer[3] << 24;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000750#if SIZEOF_LONG > 4
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200751 /* Sign extension for 64-bit machines */
752 x |= -(x & 0x80000000L);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000753#endif
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200754 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 return x;
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000756}
757
Serhiy Storchaka00987f62017-11-15 17:41:05 +0200758/* r_long64 deals with the TYPE_INT64 code. */
759static PyObject *
760r_long64(RFILE *p)
761{
762 const unsigned char *buffer = (const unsigned char *) r_string(8, p);
763 if (buffer == NULL) {
764 return NULL;
765 }
766 return _PyLong_FromByteArray(buffer, 8,
767 1 /* little endian */,
768 1 /* signed */);
769}
770
Guido van Rossum79f25d91997-04-29 20:08:16 +0000771static PyObject *
Mark Dickinsonbd792642009-03-18 20:06:12 +0000772r_PyLong(RFILE *p)
773{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 PyLongObject *ob;
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200775 long n, size, i;
776 int j, md, shorts_in_top_digit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000777 digit d;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 n = r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100780 if (PyErr_Occurred())
781 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 if (n == 0)
783 return (PyObject *)_PyLong_New(0);
Serhiy Storchaka7e019112013-02-13 12:08:15 +0200784 if (n < -SIZE32_MAX || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 PyErr_SetString(PyExc_ValueError,
786 "bad marshal data (long size out of range)");
787 return NULL;
788 }
Mark Dickinsonbd792642009-03-18 20:06:12 +0000789
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200790 size = 1 + (Py_ABS(n) - 1) / PyLong_MARSHAL_RATIO;
791 shorts_in_top_digit = 1 + (Py_ABS(n) - 1) % PyLong_MARSHAL_RATIO;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 ob = _PyLong_New(size);
793 if (ob == NULL)
794 return NULL;
Victor Stinner763b0d12013-10-31 16:56:38 +0100795
Victor Stinner60ac6ed2020-02-07 23:18:08 +0100796 Py_SET_SIZE(ob, n > 0 ? size : -size);
Mark Dickinsonbd792642009-03-18 20:06:12 +0000797
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 for (i = 0; i < size-1; i++) {
799 d = 0;
800 for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
801 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100802 if (PyErr_Occurred()) {
803 Py_DECREF(ob);
804 return NULL;
805 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 if (md < 0 || md > PyLong_MARSHAL_BASE)
807 goto bad_digit;
808 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
809 }
810 ob->ob_digit[i] = d;
811 }
Victor Stinner763b0d12013-10-31 16:56:38 +0100812
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 d = 0;
814 for (j=0; j < shorts_in_top_digit; j++) {
815 md = r_short(p);
Victor Stinner763b0d12013-10-31 16:56:38 +0100816 if (PyErr_Occurred()) {
817 Py_DECREF(ob);
818 return NULL;
819 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 if (md < 0 || md > PyLong_MARSHAL_BASE)
821 goto bad_digit;
822 /* topmost marshal digit should be nonzero */
823 if (md == 0 && j == shorts_in_top_digit - 1) {
824 Py_DECREF(ob);
825 PyErr_SetString(PyExc_ValueError,
826 "bad marshal data (unnormalized long data)");
827 return NULL;
828 }
829 d += (digit)md << j*PyLong_MARSHAL_SHIFT;
830 }
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100831 if (PyErr_Occurred()) {
832 Py_DECREF(ob);
833 return NULL;
834 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 /* top digit should be nonzero, else the resulting PyLong won't be
836 normalized */
837 ob->ob_digit[size-1] = d;
838 return (PyObject *)ob;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000839 bad_digit:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 Py_DECREF(ob);
841 PyErr_SetString(PyExc_ValueError,
842 "bad marshal data (digit out of range in long)");
843 return NULL;
Mark Dickinsonbd792642009-03-18 20:06:12 +0000844}
845
Serhiy Storchakac5734992018-07-24 10:55:47 +0300846static double
847r_float_bin(RFILE *p)
848{
849 const unsigned char *buf = (const unsigned char *) r_string(8, p);
850 if (buf == NULL)
851 return -1;
852 return _PyFloat_Unpack8(buf, 1);
853}
854
855/* Issue #33720: Disable inlining for reducing the C stack consumption
856 on PGO builds. */
857_Py_NO_INLINE static double
858r_float_str(RFILE *p)
859{
860 int n;
861 char buf[256];
862 const char *ptr;
863 n = r_byte(p);
864 if (n == EOF) {
865 PyErr_SetString(PyExc_EOFError,
866 "EOF read where object expected");
867 return -1;
868 }
869 ptr = r_string(n, p);
870 if (ptr == NULL) {
871 return -1;
872 }
873 memcpy(buf, ptr, n);
874 buf[n] = '\0';
875 return PyOS_string_to_double(buf, NULL, NULL);
876}
877
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700878/* allocate the reflist index for a new object. Return -1 on failure */
879static Py_ssize_t
880r_ref_reserve(int flag, RFILE *p)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700881{
882 if (flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200883 Py_ssize_t idx = PyList_GET_SIZE(p->refs);
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700884 if (idx >= 0x7ffffffe) {
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700885 PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700886 return -1;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700887 }
888 if (PyList_Append(p->refs, Py_None) < 0)
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700889 return -1;
890 return idx;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700891 } else
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700892 return 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700893}
894
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700895/* insert the new object 'o' to the reflist at previously
896 * allocated index 'idx'.
897 * 'o' can be NULL, in which case nothing is done.
898 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
899 * if 'o' was non-NULL, and the function fails, 'o' is released and
900 * NULL returned. This simplifies error checking at the call site since
901 * a single test for NULL for the function result is enough.
902 */
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700903static PyObject *
904r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
905{
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700906 if (o != NULL && flag) { /* currently only FLAG_REF is defined */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200907 PyObject *tmp = PyList_GET_ITEM(p->refs, idx);
908 Py_INCREF(o);
909 PyList_SET_ITEM(p->refs, idx, o);
910 Py_DECREF(tmp);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700911 }
912 return o;
913}
914
915/* combination of both above, used when an object can be
916 * created whenever it is seen in the file, as opposed to
917 * after having loaded its sub-objects.
918 */
919static PyObject *
920r_ref(PyObject *o, int flag, RFILE *p)
921{
Victor Stinner359fabc2013-10-31 17:09:01 +0100922 assert(flag & FLAG_REF);
923 if (o == NULL)
924 return NULL;
925 if (PyList_Append(p->refs, o) < 0) {
926 Py_DECREF(o); /* release the new object */
927 return NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700928 }
929 return o;
930}
Mark Dickinsonbd792642009-03-18 20:06:12 +0000931
932static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000933r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000934{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 /* NULL is a valid return value, it does not necessarily means that
936 an exception is set. */
937 PyObject *v, *v2;
Benjamin Petersoneddb0a72013-03-20 00:40:07 -0500938 Py_ssize_t idx = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 long i, n;
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700940 int type, code = r_byte(p);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +0200941 int flag, is_interned = 0;
Christian Heimes35728422013-10-13 02:29:06 +0200942 PyObject *retval = NULL;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000943
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700944 if (code == EOF) {
945 PyErr_SetString(PyExc_EOFError,
946 "EOF read where object expected");
947 return NULL;
948 }
949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 p->depth++;
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
953 p->depth--;
954 PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
955 return NULL;
956 }
Tim Petersd9b9ac82001-01-28 00:27:39 +0000957
Kristján Valur Jónsson61683622013-03-20 14:26:33 -0700958 flag = code & FLAG_REF;
959 type = code & ~FLAG_REF;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700960
961#define R_REF(O) do{\
Kristján Valur Jónssone1781872013-03-20 11:43:57 -0700962 if (flag) \
963 O = r_ref(O, flag, p);\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700964} while (0)
965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 switch (type) {
Tim Petersd9b9ac82001-01-28 00:27:39 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 case TYPE_NULL:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 case TYPE_NONE:
972 Py_INCREF(Py_None);
973 retval = Py_None;
974 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 case TYPE_STOPITER:
977 Py_INCREF(PyExc_StopIteration);
978 retval = PyExc_StopIteration;
979 break;
Tim Peters5ca576e2001-06-18 22:08:13 +0000980
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 case TYPE_ELLIPSIS:
982 Py_INCREF(Py_Ellipsis);
983 retval = Py_Ellipsis;
984 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +0000985
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 case TYPE_FALSE:
987 Py_INCREF(Py_False);
988 retval = Py_False;
989 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 case TYPE_TRUE:
992 Py_INCREF(Py_True);
993 retval = Py_True;
994 break;
Guido van Rossum77f6a652002-04-03 22:41:51 +0000995
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 case TYPE_INT:
Vinay Sajip5bdae3b2011-07-02 16:42:47 +0100997 n = r_long(p);
998 retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -0700999 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001001
Serhiy Storchaka00987f62017-11-15 17:41:05 +02001002 case TYPE_INT64:
1003 retval = r_long64(p);
1004 R_REF(retval);
1005 break;
1006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 case TYPE_LONG:
1008 retval = r_PyLong(p);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001009 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 case TYPE_FLOAT:
1013 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001014 double x = r_float_str(p);
1015 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001017 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001018 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 break;
1020 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 case TYPE_BINARY_FLOAT:
1023 {
Serhiy Storchakac5734992018-07-24 10:55:47 +03001024 double x = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001025 if (x == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 retval = PyFloat_FromDouble(x);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001028 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 break;
1030 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001031
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 case TYPE_COMPLEX:
1033 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001035 c.real = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 if (c.real == -1.0 && PyErr_Occurred())
1037 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001038 c.imag = r_float_str(p);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 if (c.imag == -1.0 && PyErr_Occurred())
1040 break;
1041 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001042 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 break;
1044 }
Michael W. Hudsondf888462005-06-03 14:41:55 +00001045
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 case TYPE_BINARY_COMPLEX:
1047 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 Py_complex c;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001049 c.real = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001050 if (c.real == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 break;
Serhiy Storchakac5734992018-07-24 10:55:47 +03001052 c.imag = r_float_bin(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001053 if (c.imag == -1.0 && PyErr_Occurred())
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 retval = PyComplex_FromCComplex(c);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001056 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 break;
1058 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001059
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 case TYPE_STRING:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001061 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001062 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001063 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001064 if (PyErr_Occurred())
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001065 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001066 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001067 PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)");
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001068 break;
1069 }
1070 v = PyBytes_FromStringAndSize((char *)NULL, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001071 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001072 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001073 ptr = r_string(n, p);
1074 if (ptr == NULL) {
1075 Py_DECREF(v);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001076 break;
1077 }
1078 memcpy(PyBytes_AS_STRING(v), ptr, n);
1079 retval = v;
1080 R_REF(retval);
1081 break;
1082 }
1083
1084 case TYPE_ASCII_INTERNED:
1085 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001086 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001087 case TYPE_ASCII:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001089 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001090 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001091 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001092 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 break;
1094 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001095 goto _read_ascii;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001096
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001097 case TYPE_SHORT_ASCII_INTERNED:
1098 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001099 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001100 case TYPE_SHORT_ASCII:
1101 n = r_byte(p);
1102 if (n == EOF) {
1103 PyErr_SetString(PyExc_EOFError,
1104 "EOF read where object expected");
1105 break;
1106 }
1107 _read_ascii:
1108 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001109 const char *ptr;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001110 ptr = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001111 if (ptr == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001112 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001113 v = PyUnicode_FromKindAndData(PyUnicode_1BYTE_KIND, ptr, n);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001114 if (v == NULL)
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001115 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001116 if (is_interned)
1117 PyUnicode_InternInPlace(&v);
1118 retval = v;
1119 R_REF(retval);
1120 break;
1121 }
1122
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001123 case TYPE_INTERNED:
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001124 is_interned = 1;
Stefan Krahf432a322017-08-21 13:09:59 +02001125 /* fall through */
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001126 case TYPE_UNICODE:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 {
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001128 const char *buffer;
Guido van Rossumc279b532000-03-10 23:03:02 +00001129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001131 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001132 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001133 if (n < 0 || n > SIZE32_MAX) {
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001134 PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 break;
1136 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001137 if (n != 0) {
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001138 buffer = r_string(n, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001139 if (buffer == NULL)
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001140 break;
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001141 v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 }
Victor Stinnerf1913ca2013-06-21 19:08:06 +02001143 else {
1144 v = PyUnicode_New(0, 0);
1145 }
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001146 if (v == NULL)
Victor Stinner3a8b79d2013-07-08 22:23:32 +02001147 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001148 if (is_interned)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001149 PyUnicode_InternInPlace(&v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 retval = v;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001151 R_REF(retval);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 break;
1153 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001154
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001155 case TYPE_SMALL_TUPLE:
1156 n = (unsigned char) r_byte(p);
Victor Stinnerb1b7b182013-10-31 17:07:08 +01001157 if (PyErr_Occurred())
1158 break;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001159 goto _read_tuple;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 case TYPE_TUPLE:
1161 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001162 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001163 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001164 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 break;
1167 }
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001168 _read_tuple:
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001169 v = PyTuple_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001170 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001171 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 break;
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 for (i = 0; i < n; i++) {
1175 v2 = r_object(p);
1176 if ( v2 == NULL ) {
1177 if (!PyErr_Occurred())
1178 PyErr_SetString(PyExc_TypeError,
1179 "NULL object in marshal data for tuple");
1180 Py_DECREF(v);
1181 v = NULL;
1182 break;
1183 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001184 PyTuple_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 }
1186 retval = v;
1187 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001188
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 case TYPE_LIST:
1190 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001191 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001192 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001193 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001194 PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 break;
1196 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001197 v = PyList_New(n);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001198 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001199 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 for (i = 0; i < n; i++) {
1202 v2 = r_object(p);
1203 if ( v2 == NULL ) {
1204 if (!PyErr_Occurred())
1205 PyErr_SetString(PyExc_TypeError,
1206 "NULL object in marshal data for list");
1207 Py_DECREF(v);
1208 v = NULL;
1209 break;
1210 }
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001211 PyList_SET_ITEM(v, i, v2);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 }
1213 retval = v;
1214 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 case TYPE_DICT:
1217 v = PyDict_New();
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001218 R_REF(v);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001219 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001221 for (;;) {
1222 PyObject *key, *val;
1223 key = r_object(p);
1224 if (key == NULL)
1225 break;
1226 val = r_object(p);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001227 if (val == NULL) {
1228 Py_DECREF(key);
1229 break;
1230 }
1231 if (PyDict_SetItem(v, key, val) < 0) {
1232 Py_DECREF(key);
1233 Py_DECREF(val);
1234 break;
1235 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 Py_DECREF(key);
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001237 Py_DECREF(val);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 }
1239 if (PyErr_Occurred()) {
1240 Py_DECREF(v);
1241 v = NULL;
1242 }
1243 retval = v;
1244 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 case TYPE_SET:
1247 case TYPE_FROZENSET:
1248 n = r_long(p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001249 if (PyErr_Occurred())
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001250 break;
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001251 if (n < 0 || n > SIZE32_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 break;
1254 }
Victor Stinnerd5cae6f2013-10-31 17:14:52 +01001255
Victor Stinner1aa78932016-01-23 14:15:48 +01001256 if (n == 0 && type == TYPE_FROZENSET) {
1257 /* call frozenset() to get the empty frozenset singleton */
Victor Stinner4778eab2016-12-01 14:51:04 +01001258 v = _PyObject_CallNoArg((PyObject*)&PyFrozenSet_Type);
Victor Stinner1aa78932016-01-23 14:15:48 +01001259 if (v == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 break;
Victor Stinner1aa78932016-01-23 14:15:48 +01001261 R_REF(v);
1262 retval = v;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 }
Victor Stinner1aa78932016-01-23 14:15:48 +01001264 else {
1265 v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
1266 if (type == TYPE_SET) {
1267 R_REF(v);
1268 } else {
1269 /* must use delayed registration of frozensets because they must
1270 * be init with a refcount of 1
1271 */
1272 idx = r_ref_reserve(flag, p);
1273 if (idx < 0)
1274 Py_CLEAR(v); /* signal error */
1275 }
1276 if (v == NULL)
1277 break;
1278
1279 for (i = 0; i < n; i++) {
1280 v2 = r_object(p);
1281 if ( v2 == NULL ) {
1282 if (!PyErr_Occurred())
1283 PyErr_SetString(PyExc_TypeError,
1284 "NULL object in marshal data for set");
1285 Py_DECREF(v);
1286 v = NULL;
1287 break;
1288 }
1289 if (PySet_Add(v, v2) == -1) {
1290 Py_DECREF(v);
1291 Py_DECREF(v2);
1292 v = NULL;
1293 break;
1294 }
1295 Py_DECREF(v2);
1296 }
1297 if (type != TYPE_SET)
1298 v = r_ref_insert(v, idx, flag, p);
1299 retval = v;
1300 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 break;
Raymond Hettingera422c342005-01-11 03:03:27 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 case TYPE_CODE:
1304 {
1305 int argcount;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001306 int posonlyargcount;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 int kwonlyargcount;
1308 int nlocals;
1309 int stacksize;
1310 int flags;
1311 PyObject *code = NULL;
1312 PyObject *consts = NULL;
1313 PyObject *names = NULL;
1314 PyObject *varnames = NULL;
1315 PyObject *freevars = NULL;
1316 PyObject *cellvars = NULL;
1317 PyObject *filename = NULL;
1318 PyObject *name = NULL;
1319 int firstlineno;
1320 PyObject *lnotab = NULL;
Antoine Pitroue9bbe8b2013-04-13 22:41:09 +02001321
Kristján Valur Jónssone1781872013-03-20 11:43:57 -07001322 idx = r_ref_reserve(flag, p);
Kristján Valur Jónsson59832582013-10-13 13:41:59 +00001323 if (idx < 0)
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001324 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 v = NULL;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 /* XXX ignore long->int overflows for now */
1329 argcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001330 if (PyErr_Occurred())
1331 goto code_error;
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001332 posonlyargcount = (int)r_long(p);
1333 if (PyErr_Occurred()) {
1334 goto code_error;
1335 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 kwonlyargcount = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001337 if (PyErr_Occurred())
1338 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 nlocals = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001340 if (PyErr_Occurred())
1341 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 stacksize = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001343 if (PyErr_Occurred())
1344 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 flags = (int)r_long(p);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001346 if (PyErr_Occurred())
1347 goto code_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 code = r_object(p);
1349 if (code == NULL)
1350 goto code_error;
1351 consts = r_object(p);
1352 if (consts == NULL)
1353 goto code_error;
1354 names = r_object(p);
1355 if (names == NULL)
1356 goto code_error;
1357 varnames = r_object(p);
1358 if (varnames == NULL)
1359 goto code_error;
1360 freevars = r_object(p);
1361 if (freevars == NULL)
1362 goto code_error;
1363 cellvars = r_object(p);
1364 if (cellvars == NULL)
1365 goto code_error;
1366 filename = r_object(p);
1367 if (filename == NULL)
1368 goto code_error;
1369 name = r_object(p);
1370 if (name == NULL)
1371 goto code_error;
1372 firstlineno = (int)r_long(p);
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001373 if (firstlineno == -1 && PyErr_Occurred())
1374 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 lnotab = r_object(p);
1376 if (lnotab == NULL)
1377 goto code_error;
Michael W. Hudsondf888462005-06-03 14:41:55 +00001378
Pablo Galindo4a2edc32019-07-01 11:35:05 +01001379 v = (PyObject *) PyCode_NewWithPosOnlyArgs(
Pablo Galindo8c77b8c2019-04-29 13:36:57 +01001380 argcount, posonlyargcount, kwonlyargcount,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 nlocals, stacksize, flags,
1382 code, consts, names, varnames,
1383 freevars, cellvars, filename, name,
1384 firstlineno, lnotab);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001385 v = r_ref_insert(v, idx, flag, p);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 code_error:
1388 Py_XDECREF(code);
1389 Py_XDECREF(consts);
1390 Py_XDECREF(names);
1391 Py_XDECREF(varnames);
1392 Py_XDECREF(freevars);
1393 Py_XDECREF(cellvars);
1394 Py_XDECREF(filename);
1395 Py_XDECREF(name);
1396 Py_XDECREF(lnotab);
1397 }
1398 retval = v;
1399 break;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001400
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001401 case TYPE_REF:
1402 n = r_long(p);
1403 if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
Kristján Valur Jónsson0a7697b2013-10-13 15:19:56 +00001404 if (n == -1 && PyErr_Occurred())
1405 break;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001406 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001407 break;
1408 }
1409 v = PyList_GET_ITEM(p->refs, n);
1410 if (v == Py_None) {
1411 PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001412 break;
1413 }
1414 Py_INCREF(v);
1415 retval = v;
1416 break;
1417
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 default:
1419 /* Bogus data got written, which isn't ideal.
1420 This will let you keep working and recover. */
1421 PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001422 break;
1423
1424 }
1425 p->depth--;
1426 return retval;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001427}
1428
Neal Norwitzd85c4522004-06-13 20:31:49 +00001429static PyObject *
Armin Rigo01ab2792004-03-26 15:09:27 +00001430read_object(RFILE *p)
1431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001432 PyObject *v;
1433 if (PyErr_Occurred()) {
1434 fprintf(stderr, "XXX readobject called with exception set\n");
1435 return NULL;
1436 }
1437 v = r_object(p);
1438 if (v == NULL && !PyErr_Occurred())
1439 PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
1440 return v;
Armin Rigo01ab2792004-03-26 15:09:27 +00001441}
1442
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001443int
1444PyMarshal_ReadShortFromFile(FILE *fp)
1445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001447 int res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 assert(fp);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001449 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 rf.fp = fp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 rf.end = rf.ptr = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001452 rf.buf = NULL;
1453 res = r_short(&rf);
1454 if (rf.buf != NULL)
1455 PyMem_FREE(rf.buf);
1456 return res;
Guido van Rossumb8cf3e62001-10-19 01:46:21 +00001457}
1458
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001459long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001460PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 RFILE rf;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001463 long res;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001465 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001467 rf.buf = NULL;
1468 res = r_long(&rf);
1469 if (rf.buf != NULL)
1470 PyMem_FREE(rf.buf);
1471 return res;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001472}
1473
Steve Dowerf2f373f2015-02-21 08:44:05 -08001474/* Return size of file in bytes; < 0 if unknown or INT_MAX if too big */
Tim Peters691e0e92001-01-18 04:39:16 +00001475static off_t
1476getfilesize(FILE *fp)
1477{
Steve Dowerf2f373f2015-02-21 08:44:05 -08001478 struct _Py_stat_struct st;
Victor Stinnere134a7f2015-03-30 10:09:31 +02001479 if (_Py_fstat_noraise(fileno(fp), &st) != 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 return -1;
Steve Dowerf2f373f2015-02-21 08:44:05 -08001481#if SIZEOF_OFF_T == 4
1482 else if (st.st_size >= INT_MAX)
1483 return (off_t)INT_MAX;
1484#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 else
Steve Dowerf2f373f2015-02-21 08:44:05 -08001486 return (off_t)st.st_size;
Tim Peters691e0e92001-01-18 04:39:16 +00001487}
Tim Petersd9b9ac82001-01-28 00:27:39 +00001488
Tim Peters691e0e92001-01-18 04:39:16 +00001489/* If we can get the size of the file up-front, and it's reasonably small,
1490 * read it in one gulp and delegate to ...FromString() instead. Much quicker
1491 * than reading a byte at a time from file; speeds .pyc imports.
Tim Petersd9b9ac82001-01-28 00:27:39 +00001492 * CAUTION: since this may read the entire remainder of the file, don't
1493 * call it unless you know you're done with the file.
Tim Peters691e0e92001-01-18 04:39:16 +00001494 */
Guido van Rossum79f25d91997-04-29 20:08:16 +00001495PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001496PyMarshal_ReadLastObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001497{
Antoine Pitrou5bc7ec92010-04-21 22:56:22 +00001498/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
Tim Peters691e0e92001-01-18 04:39:16 +00001499#define REASONABLE_FILE_LIMIT (1L << 18)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001500 off_t filesize;
1501 filesize = getfilesize(fp);
1502 if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
1503 char* pBuf = (char *)PyMem_MALLOC(filesize);
1504 if (pBuf != NULL) {
Serhiy Storchaka7e019112013-02-13 12:08:15 +02001505 size_t n = fread(pBuf, 1, (size_t)filesize, fp);
1506 PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 PyMem_FREE(pBuf);
1508 return v;
1509 }
Tim Petersd9b9ac82001-01-28 00:27:39 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 /* We don't have fstat, or we do but the file is larger than
1513 * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
1514 */
1515 return PyMarshal_ReadObjectFromFile(fp);
Tim Petersd9b9ac82001-01-28 00:27:39 +00001516
Tim Peters691e0e92001-01-18 04:39:16 +00001517#undef REASONABLE_FILE_LIMIT
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001518}
1519
Guido van Rossum79f25d91997-04-29 20:08:16 +00001520PyObject *
Tim Petersd9b9ac82001-01-28 00:27:39 +00001521PyMarshal_ReadObjectFromFile(FILE *fp)
1522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 RFILE rf;
1524 PyObject *result;
1525 rf.fp = fp;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001526 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 rf.depth = 0;
1528 rf.ptr = rf.end = NULL;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001529 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001530 rf.refs = PyList_New(0);
1531 if (rf.refs == NULL)
1532 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001533 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001534 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001535 if (rf.buf != NULL)
1536 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 return result;
Tim Petersd9b9ac82001-01-28 00:27:39 +00001538}
1539
1540PyObject *
Serhiy Storchakac6792272013-10-19 21:03:34 +03001541PyMarshal_ReadObjectFromString(const char *str, Py_ssize_t len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 RFILE rf;
1544 PyObject *result;
1545 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001546 rf.readable = NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001547 rf.ptr = str;
1548 rf.end = str + len;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001549 rf.buf = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001550 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001551 rf.refs = PyList_New(0);
1552 if (rf.refs == NULL)
1553 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 result = r_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001555 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001556 if (rf.buf != NULL)
1557 PyMem_FREE(rf.buf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 return result;
Guido van Rossumf56e3db1993-04-01 20:59:32 +00001559}
1560
Guido van Rossum79f25d91997-04-29 20:08:16 +00001561PyObject *
Martin v. Löwisef82d2f2004-06-27 16:51:46 +00001562PyMarshal_WriteObjectToString(PyObject *x, int version)
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001563{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001564 WFILE wf;
Guido van Rossume6d39042007-05-09 00:01:30 +00001565
Serhiy Storchakace921c622015-02-11 15:53:31 +02001566 memset(&wf, 0, sizeof(wf));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
1568 if (wf.str == NULL)
1569 return NULL;
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001570 wf.ptr = wf.buf = PyBytes_AS_STRING(wf.str);
1571 wf.end = wf.ptr + PyBytes_GET_SIZE(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 wf.error = WFERR_OK;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 wf.version = version;
Serhiy Storchakace921c622015-02-11 15:53:31 +02001574 if (w_init_refs(&wf, version)) {
1575 Py_DECREF(wf.str);
1576 return NULL;
1577 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 w_object(x, &wf);
Serhiy Storchakace921c622015-02-11 15:53:31 +02001579 w_clear_refs(&wf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 if (wf.str != NULL) {
Serhiy Storchaka2c003ef2020-03-31 23:23:21 +03001581 const char *base = PyBytes_AS_STRING(wf.str);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001582 if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
1583 return NULL;
1584 }
1585 if (wf.error != WFERR_OK) {
1586 Py_XDECREF(wf.str);
1587 if (wf.error == WFERR_NOMEMORY)
1588 PyErr_NoMemory();
1589 else
1590 PyErr_SetString(PyExc_ValueError,
1591 (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
1592 :"object too deeply nested to marshal");
1593 return NULL;
1594 }
Antoine Pitrou1c13f842012-03-02 18:22:23 +01001595 return wf.str;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +00001596}
1597
Guido van Rossum64b45521991-06-07 13:58:22 +00001598/* And an interface for Python programs... */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001599/*[clinic input]
1600marshal.dump
1601
1602 value: object
1603 Must be a supported type.
1604 file: object
1605 Must be a writeable binary file.
1606 version: int(c_default="Py_MARSHAL_VERSION") = version
1607 Indicates the data format that dump should use.
1608 /
1609
1610Write the value on the open file.
1611
1612If the value has (or contains an object that has) an unsupported type, a
1613ValueError exception is raised - but garbage data will also be written
1614to the file. The object will not be properly read back by load().
1615[clinic start generated code]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001616
Guido van Rossum79f25d91997-04-29 20:08:16 +00001617static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001618marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
1619 int version)
1620/*[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001622 /* XXX Quick hack -- need to do this differently */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001623 PyObject *s;
1624 PyObject *res;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001625 _Py_IDENTIFIER(write);
Martin v. Löwisafe55bb2011-10-09 10:38:36 +02001626
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001627 s = PyMarshal_WriteObjectToString(value, version);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 if (s == NULL)
1629 return NULL;
Jeroen Demeyer59ad1102019-07-11 10:59:05 +02001630 res = _PyObject_CallMethodIdOneArg(file, &PyId_write, s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001631 Py_DECREF(s);
1632 return res;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001633}
1634
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001635/*[clinic input]
1636marshal.load
1637
1638 file: object
1639 Must be readable binary file.
1640 /
1641
1642Read one value from the open file and return it.
1643
1644If no valid value is read (e.g. because the data has a different Python
1645version's incompatible marshal format), raise EOFError, ValueError or
1646TypeError.
1647
1648Note: If an object containing an unsupported type was marshalled with
1649dump(), load() will substitute None for the unmarshallable type.
1650[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001651
Guido van Rossum79f25d91997-04-29 20:08:16 +00001652static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001653marshal_load(PyObject *module, PyObject *file)
1654/*[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]*/
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001655{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 PyObject *data, *result;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001657 _Py_IDENTIFIER(read);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001658 RFILE rf;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001659
1660 /*
1661 * Make a call to the read method, but read zero bytes.
1662 * This is to ensure that the object passed in at least
1663 * has a read method which returns bytes.
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001664 * This can be removed if we guarantee good error handling
1665 * for r_string()
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001666 */
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001667 data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001668 if (data == NULL)
1669 return NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001670 if (!PyBytes_Check(data)) {
1671 PyErr_Format(PyExc_TypeError,
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001672 "file.read() returned not bytes but %.100s",
Victor Stinnera102ed72020-02-07 02:24:48 +01001673 Py_TYPE(data)->tp_name);
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001674 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001675 }
1676 else {
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001677 rf.depth = 0;
1678 rf.fp = NULL;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001679 rf.readable = file;
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001680 rf.ptr = rf.end = NULL;
1681 rf.buf = NULL;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001682 if ((rf.refs = PyList_New(0)) != NULL) {
1683 result = read_object(&rf);
1684 Py_DECREF(rf.refs);
Antoine Pitrou1164dfc2013-10-12 22:25:39 +02001685 if (rf.buf != NULL)
1686 PyMem_FREE(rf.buf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001687 } else
1688 result = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001689 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001690 Py_DECREF(data);
1691 return result;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001692}
1693
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001694/*[clinic input]
1695marshal.dumps
R. David Murraydd226ea2009-05-13 12:27:21 +00001696
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001697 value: object
1698 Must be a supported type.
1699 version: int(c_default="Py_MARSHAL_VERSION") = version
1700 Indicates the data format that dumps should use.
1701 /
1702
1703Return the bytes object that would be written to a file by dump(value, file).
1704
1705Raise a ValueError exception if value has (or contains an object that has) an
1706unsupported type.
1707[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001708
Guido van Rossum79f25d91997-04-29 20:08:16 +00001709static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001710marshal_dumps_impl(PyObject *module, PyObject *value, int version)
1711/*[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001712{
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001713 return PyMarshal_WriteObjectToString(value, version);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001714}
1715
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001716/*[clinic input]
1717marshal.loads
R. David Murraydd226ea2009-05-13 12:27:21 +00001718
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001719 bytes: Py_buffer
1720 /
1721
1722Convert the bytes-like object to a value.
1723
1724If no valid value is found, raise EOFError, ValueError or TypeError. Extra
1725bytes in the input are ignored.
1726[clinic start generated code]*/
R. David Murraydd226ea2009-05-13 12:27:21 +00001727
Guido van Rossum79f25d91997-04-29 20:08:16 +00001728static PyObject *
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001729marshal_loads_impl(PyObject *module, Py_buffer *bytes)
1730/*[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]*/
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00001731{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001732 RFILE rf;
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001733 char *s = bytes->buf;
1734 Py_ssize_t n = bytes->len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001735 PyObject* result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001736 rf.fp = NULL;
Vinay Sajip5bdae3b2011-07-02 16:42:47 +01001737 rf.readable = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 rf.ptr = s;
1739 rf.end = s + n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001740 rf.depth = 0;
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001741 if ((rf.refs = PyList_New(0)) == NULL)
1742 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 result = read_object(&rf);
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001744 Py_DECREF(rf.refs);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 return result;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001746}
1747
Guido van Rossum79f25d91997-04-29 20:08:16 +00001748static PyMethodDef marshal_methods[] = {
Serhiy Storchaka0767ad42017-03-12 09:20:15 +02001749 MARSHAL_DUMP_METHODDEF
1750 MARSHAL_LOAD_METHODDEF
1751 MARSHAL_DUMPS_METHODDEF
1752 MARSHAL_LOADS_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001753 {NULL, NULL} /* sentinel */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001754};
1755
R. David Murraydd226ea2009-05-13 12:27:21 +00001756
1757PyDoc_STRVAR(module_doc,
1758"This module contains functions that can read and write Python values in\n\
1759a binary format. The format is specific to Python, but independent of\n\
1760machine architecture issues.\n\
1761\n\
1762Not all Python object types are supported; in general, only objects\n\
1763whose value is independent from a particular invocation of Python can be\n\
1764written and read by this module. The following types are supported:\n\
1765None, integers, floating point numbers, strings, bytes, bytearrays,\n\
1766tuples, lists, sets, dictionaries, and code objects, where it\n\
1767should be understood that tuples, lists and dictionaries are only\n\
1768supported as long as the values contained therein are themselves\n\
1769supported; and recursive lists and dictionaries should not be written\n\
1770(they will cause infinite loops).\n\
1771\n\
1772Variables:\n\
1773\n\
1774version -- indicates the format that the module uses. Version 0 is the\n\
1775 historical format, version 1 shares interned strings and version 2\n\
1776 uses a binary format for floating point numbers.\n\
Kristján Valur Jónssond7009c62013-03-19 18:02:10 -07001777 Version 3 shares common object references (New in version 3.4).\n\
R. David Murraydd226ea2009-05-13 12:27:21 +00001778\n\
1779Functions:\n\
1780\n\
1781dump() -- write value to a file\n\
1782load() -- read value from a file\n\
Serhiy Storchakac611a5b2017-03-12 08:53:22 +02001783dumps() -- marshal value as a bytes object\n\
1784loads() -- read value from a bytes-like object");
R. David Murraydd226ea2009-05-13 12:27:21 +00001785
1786
1787
Brett Cannon429ef652008-06-27 00:35:35 +00001788static struct PyModuleDef marshalmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 PyModuleDef_HEAD_INIT,
1790 "marshal",
1791 module_doc,
1792 0,
1793 marshal_methods,
1794 NULL,
1795 NULL,
1796 NULL,
1797 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001798};
1799
Jason Tishler6bc06ec2003-09-04 11:59:50 +00001800PyMODINIT_FUNC
Thomas Woutersf70ef4f2000-07-22 18:47:25 +00001801PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001803 PyObject *mod = PyModule_Create(&marshalmodule);
1804 if (mod == NULL)
1805 return NULL;
Brandt Bucher33b671e2019-11-19 16:59:32 -08001806 if (PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION) < 0) {
1807 Py_DECREF(mod);
1808 return NULL;
1809 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 return mod;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001811}