[Python-checkins] r71783 - python/branches/py3k/Python/marshal.c

eric.smith python-checkins at python.org
Tue Apr 21 13:57:38 CEST 2009


Author: eric.smith
Date: Tue Apr 21 13:57:38 2009
New Revision: 71783

Log:
Added handling of PyOS_double_to_string out-of-memory errors. Closes issue 5775.

Modified:
   python/branches/py3k/Python/marshal.c

Modified: python/branches/py3k/Python/marshal.c
==============================================================================
--- python/branches/py3k/Python/marshal.c	(original)
+++ python/branches/py3k/Python/marshal.c	Tue Apr 21 13:57:38 2009
@@ -47,9 +47,14 @@
 #define TYPE_SET		'<'
 #define TYPE_FROZENSET  	'>'
 
+#define WFERR_OK 0
+#define WFERR_UNMARSHALLABLE 1
+#define WFERR_NESTEDTOODEEP 2
+#define WFERR_NOMEMORY 3
+
 typedef struct {
 	FILE *fp;
-	int error;
+	int error;  /* see WFERR_* values */
 	int depth;
 	/* If fp == NULL, the following are valid: */
 	PyObject *str;
@@ -182,7 +187,7 @@
 	p->depth++;
 
 	if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
-		p->error = 2;
+		p->error = WFERR_NESTEDTOODEEP;
 	}
 	else if (v == NULL) {
 		w_byte(TYPE_NULL, p);
@@ -229,7 +234,7 @@
 			unsigned char buf[8];
 			if (_PyFloat_Pack8(PyFloat_AsDouble(v), 
 					   buf, 1) < 0) {
-				p->error = 1;
+				p->error = WFERR_UNMARSHALLABLE;
 				return;
 			}
 			w_byte(TYPE_BINARY_FLOAT, p);
@@ -238,8 +243,10 @@
 		else {
 			char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
                                                           'g', 17, 0, NULL);
-			if (!buf)
-                            return;
+			if (!buf) {
+				p->error = WFERR_NOMEMORY;
+				return;
+			}
 			n = strlen(buf);
 			w_byte(TYPE_FLOAT, p);
 			w_byte((int)n, p);
@@ -253,14 +260,14 @@
 			unsigned char buf[8];
 			if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
 					   buf, 1) < 0) {
-				p->error = 1;
+				p->error = WFERR_UNMARSHALLABLE;
 				return;
 			}
 			w_byte(TYPE_BINARY_COMPLEX, p);
 			w_string((char*)buf, 8, p);
 			if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v), 
 					   buf, 1) < 0) {
-				p->error = 1;
+				p->error = WFERR_UNMARSHALLABLE;
 				return;
 			}
 			w_string((char*)buf, 8, p);
@@ -270,16 +277,20 @@
 			w_byte(TYPE_COMPLEX, p);
 			buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
                                                     'g', 17, 0, NULL);
-			if (!buf)
-                            return;
+			if (!buf) {
+				p->error = WFERR_NOMEMORY;
+				return;
+			}
 			n = strlen(buf);
 			w_byte((int)n, p);
 			w_string(buf, (int)n, p);
 			PyMem_Free(buf);
 			buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
                                                     'g', 17, 0, NULL);
-			if (!buf)
-                            return;
+			if (!buf) {
+				p->error = WFERR_NOMEMORY;
+				return;
+			}
 			n = strlen(buf);
 			w_byte((int)n, p);
 			w_string(buf, (int)n, p);
@@ -293,7 +304,7 @@
 		if (n > INT_MAX) {
 			/* huge strings are not supported */
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		w_long((long)n, p);
@@ -304,14 +315,14 @@
 		utf8 = PyUnicode_AsUTF8String(v);
 		if (utf8 == NULL) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		w_byte(TYPE_UNICODE, p);
 		n = PyBytes_GET_SIZE(utf8);
 		if (n > INT_MAX) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		w_long((long)n, p);
@@ -356,14 +367,14 @@
 		n = PyObject_Size(v);
 		if (n == -1) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		w_long((long)n, p);
 		it = PyObject_GetIter(v);
 		if (it == NULL) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		while ((value = PyIter_Next(it)) != NULL) {
@@ -373,7 +384,7 @@
 		Py_DECREF(it);
 		if (PyErr_Occurred()) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 	}
@@ -403,14 +414,14 @@
                 Py_buffer view;
 		if ((*pb->bf_getbuffer)(v, &view, PyBUF_SIMPLE) != 0) {
                         w_byte(TYPE_UNKNOWN, p);
-                        p->error = 1;
+                        p->error = WFERR_UNMARSHALLABLE;
                 }
 		w_byte(TYPE_STRING, p);
                 n = view.len;
                 s = view.buf;                        
 		if (n > INT_MAX) {
 			p->depth--;
-			p->error = 1;
+			p->error = WFERR_UNMARSHALLABLE;
 			return;
 		}
 		w_long((long)n, p);
@@ -420,7 +431,7 @@
 	}
 	else {
 		w_byte(TYPE_UNKNOWN, p);
-		p->error = 1;
+		p->error = WFERR_UNMARSHALLABLE;
 	}
 	p->depth--;
 }
@@ -431,7 +442,7 @@
 {
 	WFILE wf;
 	wf.fp = fp;
-	wf.error = 0;
+	wf.error = WFERR_OK;
 	wf.depth = 0;
 	wf.strings = NULL;
 	wf.version = version;
@@ -443,7 +454,7 @@
 {
 	WFILE wf;
 	wf.fp = fp;
-	wf.error = 0;
+	wf.error = WFERR_OK;
 	wf.depth = 0;
 	wf.strings = (version > 0) ? PyDict_New() : NULL;
 	wf.version = version;
@@ -1143,7 +1154,7 @@
 		return NULL;
 	wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str);
 	wf.end = wf.ptr + PyBytes_Size(wf.str);
-	wf.error = 0;
+	wf.error = WFERR_OK;
 	wf.depth = 0;
 	wf.version = version;
 	wf.strings = (version > 0) ? PyDict_New() : NULL;
@@ -1160,11 +1171,14 @@
 		if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
 			return NULL;
 	}
-	if (wf.error) {
+	if (wf.error != WFERR_OK) {
 		Py_XDECREF(wf.str);
-		PyErr_SetString(PyExc_ValueError,
-				(wf.error==1)?"unmarshallable object"
-				:"object too deeply nested to marshal");
+                if (wf.error == WFERR_NOMEMORY)
+                    PyErr_NoMemory();
+                else
+                    PyErr_SetString(PyExc_ValueError,
+                      (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
+                       :"object too deeply nested to marshal");
 		return NULL;
 	}
 	if (wf.str != NULL) {


More information about the Python-checkins mailing list