cpython: 5fa793ae36cc (original) (raw)
--- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -2,6 +2,7 @@ from test import support import array +import io import marshal import sys import unittest @@ -259,6 +260,17 @@ class BugsTestCase(unittest.TestCase): unicode_string = 'T' self.assertRaises(TypeError, marshal.loads, unicode_string)
- def test_bad_reader(self):
class BadReader(io.BytesIO):[](#l1.16)
def read(self, n=-1):[](#l1.17)
b = super().read(n)[](#l1.18)
if n is not None and n > 4:[](#l1.19)
b += b' ' * 10**6[](#l1.20)
return b[](#l1.21)
for value in (1.0, 1j, b'0123456789', '0123456789'):[](#l1.22)
self.assertRaises(ValueError, marshal.load,[](#l1.23)
BadReader(marshal.dumps(value)))[](#l1.24)
+ def _test_eof(self): data = marshal.dumps(("hello", "dolly", None)) for i in range(len(data)):
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.4.0 Alpha 1? Core and Builtins ----------------- +- Issue #17872: Fix a segfault in marshal.load() when input stream returns
- Issue #18338:
python --version
now prints version string to stdout, and not to stderr. Patch by Berker Peksag and Michael Dickens.
--- a/Python/marshal.c +++ b/Python/marshal.c @@ -570,8 +570,17 @@ r_string(char *s, Py_ssize_t n, RFILE *p else { read = (int)PyBytes_GET_SIZE(data); if (read > 0) {
ptr = PyBytes_AS_STRING(data);[](#l3.7)
memcpy(s, ptr, read);[](#l3.8)
if (read > n) {[](#l3.9)
PyErr_Format(PyExc_ValueError,[](#l3.10)
"read() returned too much data: "[](#l3.11)
"%zd bytes requested, %zd returned",[](#l3.12)
n, read);[](#l3.13)
read = -1;[](#l3.14)
}[](#l3.15)
else {[](#l3.16)
ptr = PyBytes_AS_STRING(data);[](#l3.17)
memcpy(s, ptr, read);[](#l3.18)
}[](#l3.19) }[](#l3.20) }[](#l3.21) Py_DECREF(data);[](#l3.22)
@@ -841,11 +850,13 @@ r_object(RFILE *p) double dx; retval = NULL; n = r_byte(p);
if (n == EOF || r_string(buf, n, p) != n) {[](#l3.27)
if (n == EOF) {[](#l3.28) PyErr_SetString(PyExc_EOFError,[](#l3.29) "EOF read where object expected");[](#l3.30) break;[](#l3.31) }[](#l3.32)
if (r_string(buf, n, p) != n)[](#l3.33)
break;[](#l3.34) buf[n] = '\0';[](#l3.35) dx = PyOS_string_to_double(buf, NULL, NULL);[](#l3.36) if (dx == -1.0 && PyErr_Occurred())[](#l3.37)
@@ -860,8 +871,6 @@ r_object(RFILE p) unsigned char buf[8]; double x; if (r_string((char)buf, 8, p) != 8) {
PyErr_SetString(PyExc_EOFError,[](#l3.42)
"EOF read where object expected");[](#l3.43) retval = NULL;[](#l3.44) break;[](#l3.45) }[](#l3.46)
@@ -881,21 +890,25 @@ r_object(RFILE *p) Py_complex c; retval = NULL; n = r_byte(p);
if (n == EOF || r_string(buf, n, p) != n) {[](#l3.51)
if (n == EOF) {[](#l3.52) PyErr_SetString(PyExc_EOFError,[](#l3.53) "EOF read where object expected");[](#l3.54) break;[](#l3.55) }[](#l3.56)
if (r_string(buf, n, p) != n)[](#l3.57)
break;[](#l3.58) buf[n] = '\0';[](#l3.59) c.real = PyOS_string_to_double(buf, NULL, NULL);[](#l3.60) if (c.real == -1.0 && PyErr_Occurred())[](#l3.61) break;[](#l3.62) n = r_byte(p);[](#l3.63)
if (n == EOF || r_string(buf, n, p) != n) {[](#l3.64)
if (n == EOF) {[](#l3.65) PyErr_SetString(PyExc_EOFError,[](#l3.66) "EOF read where object expected");[](#l3.67) break;[](#l3.68) }[](#l3.69)
if (r_string(buf, n, p) != n)[](#l3.70)
break;[](#l3.71) buf[n] = '\0';[](#l3.72) c.imag = PyOS_string_to_double(buf, NULL, NULL);[](#l3.73) if (c.imag == -1.0 && PyErr_Occurred())[](#l3.74)
@@ -910,8 +923,6 @@ r_object(RFILE p) unsigned char buf[8]; Py_complex c; if (r_string((char)buf, 8, p) != 8) {
PyErr_SetString(PyExc_EOFError,[](#l3.79)
"EOF read where object expected");[](#l3.80) retval = NULL;[](#l3.81) break;[](#l3.82) }[](#l3.83)
@@ -921,8 +932,6 @@ r_object(RFILE p) break; } if (r_string((char)buf, 8, p) != 8) {
PyErr_SetString(PyExc_EOFError,[](#l3.88)
"EOF read where object expected");[](#l3.89) retval = NULL;[](#l3.90) break;[](#l3.91) }[](#l3.92)
@@ -954,8 +963,6 @@ r_object(RFILE *p) } if (r_string(PyBytes_AS_STRING(v), n, p) != n) { Py_DECREF(v);
PyErr_SetString(PyExc_EOFError,[](#l3.97)
"EOF read where object expected");[](#l3.98) retval = NULL;[](#l3.99) break;[](#l3.100) }[](#l3.101)
@@ -986,8 +993,6 @@ r_object(RFILE *p) } if (r_string(buffer, n, p) != n) { PyMem_DEL(buffer);
PyErr_SetString(PyExc_EOFError,[](#l3.106)
"EOF read where object expected");[](#l3.107) retval = NULL;[](#l3.108) break;[](#l3.109) }[](#l3.110)