mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	Michael Hudson <mwh21@cam.ac.uk>:
As I really do not have anything better to do at the moment, I have written a patch to Python/marshal.c that prevents Python dumping core when trying to marshal stack bustingly deep (or recursive) data structure. It just throws an exception; even slightly clever handling of recursive data is what pickle is for... [Fred Drake:] Moved magic constant 5000 to a #define. This closes SourceForge patch #100645.
This commit is contained in:
		
							parent
							
								
									7833447f8f
								
							
						
					
					
						commit
						6da0b9148c
					
				
					 1 changed files with 22 additions and 3 deletions
				
			
		| 
						 | 
					@ -39,6 +39,12 @@ PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
#include "compile.h"
 | 
					#include "compile.h"
 | 
				
			||||||
#include "marshal.h"
 | 
					#include "marshal.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* High water mark to determine when the marshalled object is dangerously deep
 | 
				
			||||||
 | 
					 * and risks coring the interpreter.  When the object stack gets this deep,
 | 
				
			||||||
 | 
					 * raise an exception instead of continuing.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define MAX_MARSHAL_STACK_DEPTH 5000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TYPE_NULL	'0'
 | 
					#define TYPE_NULL	'0'
 | 
				
			||||||
#define TYPE_NONE	'N'
 | 
					#define TYPE_NONE	'N'
 | 
				
			||||||
#define TYPE_ELLIPSIS   '.'
 | 
					#define TYPE_ELLIPSIS   '.'
 | 
				
			||||||
| 
						 | 
					@ -58,6 +64,7 @@ PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
	FILE *fp;
 | 
						FILE *fp;
 | 
				
			||||||
	int error;
 | 
						int error;
 | 
				
			||||||
 | 
						int depth;
 | 
				
			||||||
	/* If fp == NULL, the following are valid: */
 | 
						/* If fp == NULL, the following are valid: */
 | 
				
			||||||
	PyObject *str;
 | 
						PyObject *str;
 | 
				
			||||||
	char *ptr;
 | 
						char *ptr;
 | 
				
			||||||
| 
						 | 
					@ -144,8 +151,13 @@ w_object(v, p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, n;
 | 
						int i, n;
 | 
				
			||||||
	PyBufferProcs *pb;
 | 
						PyBufferProcs *pb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p->depth++;
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	if (v == NULL) {
 | 
						if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
 | 
				
			||||||
 | 
							p->error = 2;
 | 
				
			||||||
 | 
						} 
 | 
				
			||||||
 | 
						else if (v == NULL) {
 | 
				
			||||||
		w_byte(TYPE_NULL, p);
 | 
							w_byte(TYPE_NULL, p);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if (v == Py_None) {
 | 
						else if (v == Py_None) {
 | 
				
			||||||
| 
						 | 
					@ -301,6 +313,7 @@ PyMarshal_WriteLongToFile(x, fp)
 | 
				
			||||||
	WFILE wf;
 | 
						WFILE wf;
 | 
				
			||||||
	wf.fp = fp;
 | 
						wf.fp = fp;
 | 
				
			||||||
	wf.error = 0;
 | 
						wf.error = 0;
 | 
				
			||||||
 | 
						wf.depth = 0;
 | 
				
			||||||
	w_long(x, &wf);
 | 
						w_long(x, &wf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -690,6 +703,7 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */
 | 
				
			||||||
	wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
 | 
						wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
 | 
				
			||||||
	wf.end = wf.ptr + PyString_Size(wf.str);
 | 
						wf.end = wf.ptr + PyString_Size(wf.str);
 | 
				
			||||||
	wf.error = 0;
 | 
						wf.error = 0;
 | 
				
			||||||
 | 
						wf.depth = 0;
 | 
				
			||||||
	w_object(x, &wf);
 | 
						w_object(x, &wf);
 | 
				
			||||||
	if (wf.str != NULL)
 | 
						if (wf.str != NULL)
 | 
				
			||||||
		_PyString_Resize(&wf.str,
 | 
							_PyString_Resize(&wf.str,
 | 
				
			||||||
| 
						 | 
					@ -697,7 +711,9 @@ PyMarshal_WriteObjectToString(x) /* wrs_object() */
 | 
				
			||||||
			   PyString_AS_STRING((PyStringObject *)wf.str)));
 | 
								   PyString_AS_STRING((PyStringObject *)wf.str)));
 | 
				
			||||||
	if (wf.error) {
 | 
						if (wf.error) {
 | 
				
			||||||
		Py_XDECREF(wf.str);
 | 
							Py_XDECREF(wf.str);
 | 
				
			||||||
		PyErr_SetString(PyExc_ValueError, "unmarshallable object");
 | 
							PyErr_SetString(PyExc_ValueError, 
 | 
				
			||||||
 | 
									(wf.error==1)?"unmarshallable object"
 | 
				
			||||||
 | 
									:"object too deeply nested to marshal");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return wf.str;
 | 
						return wf.str;
 | 
				
			||||||
| 
						 | 
					@ -724,9 +740,12 @@ marshal_dump(self, args)
 | 
				
			||||||
	wf.str = NULL;
 | 
						wf.str = NULL;
 | 
				
			||||||
	wf.ptr = wf.end = NULL;
 | 
						wf.ptr = wf.end = NULL;
 | 
				
			||||||
	wf.error = 0;
 | 
						wf.error = 0;
 | 
				
			||||||
 | 
						wf.depth = 0;
 | 
				
			||||||
	w_object(x, &wf);
 | 
						w_object(x, &wf);
 | 
				
			||||||
	if (wf.error) {
 | 
						if (wf.error) {
 | 
				
			||||||
		PyErr_SetString(PyExc_ValueError, "unmarshallable object");
 | 
							PyErr_SetString(PyExc_ValueError, 
 | 
				
			||||||
 | 
									(wf.error==1)?"unmarshallable object"
 | 
				
			||||||
 | 
									:"object too deeply nested to marshal");
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	Py_INCREF(Py_None);
 | 
						Py_INCREF(Py_None);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue