diff Python/marshal.c @ 13070:7392e71f6cce legacy-trunk

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.
author Fred Drake <fdrake@acm.org>
date Wed, 28 Jun 2000 18:47:56 +0000
parents 1c7c2dd1beb1
children a6725acdf33b
line wrap: on
line diff
--- a/Python/marshal.c	Wed Jun 28 17:50:51 2000 +0000
+++ b/Python/marshal.c	Wed Jun 28 18:47:56 2000 +0000
@@ -39,6 +39,12 @@
 #include "compile.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_NONE	'N'
 #define TYPE_ELLIPSIS   '.'
@@ -58,6 +64,7 @@
 typedef struct {
 	FILE *fp;
 	int error;
+	int depth;
 	/* If fp == NULL, the following are valid: */
 	PyObject *str;
 	char *ptr;
@@ -144,8 +151,13 @@
 {
 	int i, n;
 	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);
 	}
 	else if (v == Py_None) {
@@ -301,6 +313,7 @@
 	WFILE wf;
 	wf.fp = fp;
 	wf.error = 0;
+	wf.depth = 0;
 	w_long(x, &wf);
 }
 
@@ -690,6 +703,7 @@
 	wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
 	wf.end = wf.ptr + PyString_Size(wf.str);
 	wf.error = 0;
+	wf.depth = 0;
 	w_object(x, &wf);
 	if (wf.str != NULL)
 		_PyString_Resize(&wf.str,
@@ -697,7 +711,9 @@
 			   PyString_AS_STRING((PyStringObject *)wf.str)));
 	if (wf.error) {
 		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 wf.str;
@@ -724,9 +740,12 @@
 	wf.str = NULL;
 	wf.ptr = wf.end = NULL;
 	wf.error = 0;
+	wf.depth = 0;
 	w_object(x, &wf);
 	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;
 	}
 	Py_INCREF(Py_None);