diff -r e392f1b88fff Lib/test/test_marshal.py --- a/Lib/test/test_marshal.py Mon May 20 10:28:48 2013 -0700 +++ b/Lib/test/test_marshal.py Mon May 20 23:27:33 2013 +0300 @@ -2,6 +2,7 @@ from test import support import array +import io import marshal import sys import unittest @@ -264,6 +265,17 @@ for i in range(len(data)): self.assertRaises(EOFError, marshal.loads, data[0: i]) + def test_bad_reader(self): + class BadReader(io.BytesIO): + def read(self, n=-1): + b = super().read(n) + if n is not None and n > 4: + b += b' ' * 10**6 + return b + for value in (1.0, 1j, b'0123456789', '0123456789'): + self.assertRaises(ValueError, marshal.load, + BadReader(marshal.dumps(value))) + LARGE_SIZE = 2**31 pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4 diff -r e392f1b88fff Python/marshal.c --- a/Python/marshal.c Mon May 20 10:28:48 2013 -0700 +++ b/Python/marshal.c Mon May 20 23:27:33 2013 +0300 @@ -569,10 +569,19 @@ data->ob_type->tp_name); } else { - read = (int)PyBytes_GET_SIZE(data); + 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); @@ -842,11 +851,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()) @@ -861,8 +872,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; } @@ -882,21 +891,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()) @@ -911,8 +924,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; } @@ -922,8 +933,6 @@ break; } if (r_string((char*)buf, 8, p) != 8) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); retval = NULL; break; } @@ -955,8 +964,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; } @@ -986,8 +993,6 @@ } if (r_string(buffer, n, p) != n) { PyMem_DEL(buffer); - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); retval = NULL; break; }