diff Python/marshal.c @ 84556:fc7bab8a8618 3.3

Issue #17872: Fix a segfault in marshal.load() when input stream returns more bytes than requested.
author Serhiy Storchaka <storchaka@gmail.com>
date Thu, 11 Jul 2013 22:20:47 +0300
parents 8b99f2224c3a
children 4d62a62ba44d 5fa793ae36cc
line wrap: on
line diff
--- a/Python/marshal.c	Thu Jul 11 21:57:34 2013 +0300
+++ b/Python/marshal.c	Thu Jul 11 22:20:47 2013 +0300
@@ -490,8 +490,17 @@
             else {
                 read = PyBytes_GET_SIZE(data);
                 if (read > 0) {
-                    ptr = PyBytes_AS_STRING(data);
-                    memcpy(s, ptr, read);
+                    if (read > n) {
+                        PyErr_Format(PyExc_ValueError,
+                                    "read() returned too much data: "
+                                    "%zd bytes requested, %zd returned",
+                                    n, read);
+                        read = -1;
+                    }
+                    else {
+                        ptr = PyBytes_AS_STRING(data);
+                        memcpy(s, ptr, read);
+                    }
                 }
             }
             Py_DECREF(data);
@@ -733,11 +742,13 @@
             double dx;
             retval = NULL;
             n = r_byte(p);
-            if (n == EOF || r_string(buf, n, p) != n) {
+            if (n == EOF) {
                 PyErr_SetString(PyExc_EOFError,
                     "EOF read where object expected");
                 break;
             }
+            if (r_string(buf, n, p) != n)
+                break;
             buf[n] = '\0';
             dx = PyOS_string_to_double(buf, NULL, NULL);
             if (dx == -1.0 && PyErr_Occurred())
@@ -751,8 +762,6 @@
             unsigned char buf[8];
             double x;
             if (r_string((char*)buf, 8, p) != 8) {
-                PyErr_SetString(PyExc_EOFError,
-                    "EOF read where object expected");
                 retval = NULL;
                 break;
             }
@@ -771,21 +780,25 @@
             Py_complex c;
             retval = NULL;
             n = r_byte(p);
-            if (n == EOF || r_string(buf, n, p) != n) {
+            if (n == EOF) {
                 PyErr_SetString(PyExc_EOFError,
                     "EOF read where object expected");
                 break;
             }
+            if (r_string(buf, n, p) != n)
+                break;
             buf[n] = '\0';
             c.real = PyOS_string_to_double(buf, NULL, NULL);
             if (c.real == -1.0 && PyErr_Occurred())
                 break;
             n = r_byte(p);
-            if (n == EOF || r_string(buf, n, p) != n) {
+            if (n == EOF) {
                 PyErr_SetString(PyExc_EOFError,
                     "EOF read where object expected");
                 break;
             }
+            if (r_string(buf, n, p) != n)
+                break;
             buf[n] = '\0';
             c.imag = PyOS_string_to_double(buf, NULL, NULL);
             if (c.imag == -1.0 && PyErr_Occurred())
@@ -799,8 +812,6 @@
             unsigned char buf[8];
             Py_complex c;
             if (r_string((char*)buf, 8, p) != 8) {
-                PyErr_SetString(PyExc_EOFError,
-                    "EOF read where object expected");
                 retval = NULL;
                 break;
             }
@@ -810,8 +821,6 @@
                 break;
             }
             if (r_string((char*)buf, 8, p) != 8) {
-                PyErr_SetString(PyExc_EOFError,
-                    "EOF read where object expected");
                 retval = NULL;
                 break;
             }
@@ -842,8 +851,6 @@
         }
         if (r_string(PyBytes_AS_STRING(v), n, p) != n) {
             Py_DECREF(v);
-            PyErr_SetString(PyExc_EOFError,
-                            "EOF read where object expected");
             retval = NULL;
             break;
         }
@@ -871,8 +878,6 @@
         }
         if (r_string(buffer, n, p) != n) {
             PyMem_DEL(buffer);
-            PyErr_SetString(PyExc_EOFError,
-                "EOF read where object expected");
             retval = NULL;
             break;
         }