4747#define TYPE_SET '<'
4848#define TYPE_FROZENSET '>'
4949
50+ #define WFERR_OK 0
51+ #define WFERR_UNMARSHALLABLE 1
52+ #define WFERR_NESTEDTOODEEP 2
53+ #define WFERR_NOMEMORY 3
54+
5055typedef struct {
5156 FILE * fp ;
52- int error ;
57+ int error ; /* see WFERR_* values */
5358 int depth ;
5459 /* If fp == NULL, the following are valid: */
5560 PyObject * str ;
@@ -182,7 +187,7 @@ w_object(PyObject *v, WFILE *p)
182187 p -> depth ++ ;
183188
184189 if (p -> depth > MAX_MARSHAL_STACK_DEPTH ) {
185- p -> error = 2 ;
190+ p -> error = WFERR_NESTEDTOODEEP ;
186191 }
187192 else if (v == NULL ) {
188193 w_byte (TYPE_NULL , p );
@@ -229,7 +234,7 @@ w_object(PyObject *v, WFILE *p)
229234 unsigned char buf [8 ];
230235 if (_PyFloat_Pack8 (PyFloat_AsDouble (v ),
231236 buf , 1 ) < 0 ) {
232- p -> error = 1 ;
237+ p -> error = WFERR_UNMARSHALLABLE ;
233238 return ;
234239 }
235240 w_byte (TYPE_BINARY_FLOAT , p );
@@ -238,8 +243,10 @@ w_object(PyObject *v, WFILE *p)
238243 else {
239244 char * buf = PyOS_double_to_string (PyFloat_AS_DOUBLE (v ),
240245 'g' , 17 , 0 , NULL );
241- if (!buf )
242- return ;
246+ if (!buf ) {
247+ p -> error = WFERR_NOMEMORY ;
248+ return ;
249+ }
243250 n = strlen (buf );
244251 w_byte (TYPE_FLOAT , p );
245252 w_byte ((int )n , p );
@@ -253,14 +260,14 @@ w_object(PyObject *v, WFILE *p)
253260 unsigned char buf [8 ];
254261 if (_PyFloat_Pack8 (PyComplex_RealAsDouble (v ),
255262 buf , 1 ) < 0 ) {
256- p -> error = 1 ;
263+ p -> error = WFERR_UNMARSHALLABLE ;
257264 return ;
258265 }
259266 w_byte (TYPE_BINARY_COMPLEX , p );
260267 w_string ((char * )buf , 8 , p );
261268 if (_PyFloat_Pack8 (PyComplex_ImagAsDouble (v ),
262269 buf , 1 ) < 0 ) {
263- p -> error = 1 ;
270+ p -> error = WFERR_UNMARSHALLABLE ;
264271 return ;
265272 }
266273 w_string ((char * )buf , 8 , p );
@@ -270,16 +277,20 @@ w_object(PyObject *v, WFILE *p)
270277 w_byte (TYPE_COMPLEX , p );
271278 buf = PyOS_double_to_string (PyComplex_RealAsDouble (v ),
272279 'g' , 17 , 0 , NULL );
273- if (!buf )
274- return ;
280+ if (!buf ) {
281+ p -> error = WFERR_NOMEMORY ;
282+ return ;
283+ }
275284 n = strlen (buf );
276285 w_byte ((int )n , p );
277286 w_string (buf , (int )n , p );
278287 PyMem_Free (buf );
279288 buf = PyOS_double_to_string (PyComplex_ImagAsDouble (v ),
280289 'g' , 17 , 0 , NULL );
281- if (!buf )
282- return ;
290+ if (!buf ) {
291+ p -> error = WFERR_NOMEMORY ;
292+ return ;
293+ }
283294 n = strlen (buf );
284295 w_byte ((int )n , p );
285296 w_string (buf , (int )n , p );
@@ -293,7 +304,7 @@ w_object(PyObject *v, WFILE *p)
293304 if (n > INT_MAX ) {
294305 /* huge strings are not supported */
295306 p -> depth -- ;
296- p -> error = 1 ;
307+ p -> error = WFERR_UNMARSHALLABLE ;
297308 return ;
298309 }
299310 w_long ((long )n , p );
@@ -304,14 +315,14 @@ w_object(PyObject *v, WFILE *p)
304315 utf8 = PyUnicode_AsUTF8String (v );
305316 if (utf8 == NULL ) {
306317 p -> depth -- ;
307- p -> error = 1 ;
318+ p -> error = WFERR_UNMARSHALLABLE ;
308319 return ;
309320 }
310321 w_byte (TYPE_UNICODE , p );
311322 n = PyBytes_GET_SIZE (utf8 );
312323 if (n > INT_MAX ) {
313324 p -> depth -- ;
314- p -> error = 1 ;
325+ p -> error = WFERR_UNMARSHALLABLE ;
315326 return ;
316327 }
317328 w_long ((long )n , p );
@@ -356,14 +367,14 @@ w_object(PyObject *v, WFILE *p)
356367 n = PyObject_Size (v );
357368 if (n == -1 ) {
358369 p -> depth -- ;
359- p -> error = 1 ;
370+ p -> error = WFERR_UNMARSHALLABLE ;
360371 return ;
361372 }
362373 w_long ((long )n , p );
363374 it = PyObject_GetIter (v );
364375 if (it == NULL ) {
365376 p -> depth -- ;
366- p -> error = 1 ;
377+ p -> error = WFERR_UNMARSHALLABLE ;
367378 return ;
368379 }
369380 while ((value = PyIter_Next (it )) != NULL ) {
@@ -373,7 +384,7 @@ w_object(PyObject *v, WFILE *p)
373384 Py_DECREF (it );
374385 if (PyErr_Occurred ()) {
375386 p -> depth -- ;
376- p -> error = 1 ;
387+ p -> error = WFERR_UNMARSHALLABLE ;
377388 return ;
378389 }
379390 }
@@ -403,14 +414,14 @@ w_object(PyObject *v, WFILE *p)
403414 Py_buffer view ;
404415 if ((* pb -> bf_getbuffer )(v , & view , PyBUF_SIMPLE ) != 0 ) {
405416 w_byte (TYPE_UNKNOWN , p );
406- p -> error = 1 ;
417+ p -> error = WFERR_UNMARSHALLABLE ;
407418 }
408419 w_byte (TYPE_STRING , p );
409420 n = view .len ;
410421 s = view .buf ;
411422 if (n > INT_MAX ) {
412423 p -> depth -- ;
413- p -> error = 1 ;
424+ p -> error = WFERR_UNMARSHALLABLE ;
414425 return ;
415426 }
416427 w_long ((long )n , p );
@@ -420,7 +431,7 @@ w_object(PyObject *v, WFILE *p)
420431 }
421432 else {
422433 w_byte (TYPE_UNKNOWN , p );
423- p -> error = 1 ;
434+ p -> error = WFERR_UNMARSHALLABLE ;
424435 }
425436 p -> depth -- ;
426437}
@@ -431,7 +442,7 @@ PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
431442{
432443 WFILE wf ;
433444 wf .fp = fp ;
434- wf .error = 0 ;
445+ wf .error = WFERR_OK ;
435446 wf .depth = 0 ;
436447 wf .strings = NULL ;
437448 wf .version = version ;
@@ -443,7 +454,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
443454{
444455 WFILE wf ;
445456 wf .fp = fp ;
446- wf .error = 0 ;
457+ wf .error = WFERR_OK ;
447458 wf .depth = 0 ;
448459 wf .strings = (version > 0 ) ? PyDict_New () : NULL ;
449460 wf .version = version ;
@@ -1143,7 +1154,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
11431154 return NULL ;
11441155 wf .ptr = PyBytes_AS_STRING ((PyBytesObject * )wf .str );
11451156 wf .end = wf .ptr + PyBytes_Size (wf .str );
1146- wf .error = 0 ;
1157+ wf .error = WFERR_OK ;
11471158 wf .depth = 0 ;
11481159 wf .version = version ;
11491160 wf .strings = (version > 0 ) ? PyDict_New () : NULL ;
@@ -1160,11 +1171,14 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
11601171 if (_PyBytes_Resize (& wf .str , (Py_ssize_t )(wf .ptr - base )) < 0 )
11611172 return NULL ;
11621173 }
1163- if (wf .error ) {
1174+ if (wf .error != WFERR_OK ) {
11641175 Py_XDECREF (wf .str );
1165- PyErr_SetString (PyExc_ValueError ,
1166- (wf .error == 1 )?"unmarshallable object"
1167- :"object too deeply nested to marshal" );
1176+ if (wf .error == WFERR_NOMEMORY )
1177+ PyErr_NoMemory ();
1178+ else
1179+ PyErr_SetString (PyExc_ValueError ,
1180+ (wf .error == WFERR_UNMARSHALLABLE )?"unmarshallable object"
1181+ :"object too deeply nested to marshal" );
11681182 return NULL ;
11691183 }
11701184 if (wf .str != NULL ) {
0 commit comments