cpython: a75336ac40e0 (original) (raw)

Mercurial > cpython

changeset 98992:a75336ac40e0 3.4

Issue #24802: Copy bytes-like objects to null-terminated buffers if necessary This avoids possible buffer overreads when int(), float(), compile(), exec() and eval() are passed bytes-like objects. Similar code is removed from the complex() constructor, where it was not reachable. Patch by John Leitch, Serhiy Storchaka and Martin Panter. [#24802]

Martin Panter vadmium+py@gmail.com
date Sat, 07 Nov 2015 02:32:21 +0000
parents 9098731de840
children 95b9c07b27f7 2071d16ed5e6
files Lib/test/test_compile.py Lib/test/test_float.py Lib/test/test_int.py Misc/NEWS Objects/abstract.c Objects/complexobject.c Objects/floatobject.c Python/bltinmodule.c
diffstat 8 files changed, 161 insertions(+), 36 deletions(-)[+] [-] Lib/test/test_compile.py 21 Lib/test/test_float.py 38 Lib/test/test_int.py 42 Misc/NEWS 4 Objects/abstract.c 22 Objects/complexobject.c 7 Objects/floatobject.c 15 Python/bltinmodule.c 48

line wrap: on

line diff

--- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -530,6 +530,27 @@ if 1: check_limit("a", "[0]") check_limit("a", "*a")

+

+ class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object

--- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -31,7 +31,6 @@ class GeneralFloatCases(unittest.TestCas self.assertEqual(float(3.14), 3.14) self.assertEqual(float(314), 314.0) self.assertEqual(float(" 3.14 "), 3.14)

@@ -43,7 +42,6 @@ class GeneralFloatCases(unittest.TestCas self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.")

@@ -57,6 +55,42 @@ class GeneralFloatCases(unittest.TestCas float(b'.' + b'1'*1000) float('.' + '1'*1000)

+

+

+

+ def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist:

--- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -276,16 +276,40 @@ class IntTestCases(unittest.TestCase): class CustomBytes(bytes): pass class CustomByteArray(bytearray): pass

+

def test_string_float(self): self.assertRaises(ValueError, int, '1.2')

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Release date: tba Core and Builtins ----------------- +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec()

--- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1264,12 +1264,30 @@ PyNumber_Long(PyObject o) / The below check is done in PyLong_FromUnicode(). */ return PyLong_FromUnicodeObject(o, 10);

+

+

+

--- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -767,7 +767,6 @@ complex_subtype_from_string(PyTypeObject int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len;

if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -777,10 +776,6 @@ complex_subtype_from_string(PyTypeObject if (s == NULL) goto error; }

@@ -895,7 +890,6 @@ complex_subtype_from_string(PyTypeObject if (s-start != len) goto parse_error;

error:

--- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -144,9 +144,24 @@ PyFloat_FromString(PyObject *v) return NULL; } }

--- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -560,20 +560,37 @@ Return a Unicode string of one character static const char * -source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) { const char *str; Py_ssize_t size;

@@ -585,7 +602,7 @@ source_as_string(PyObject *cmd, const ch if (strlen(str) != size) { PyErr_SetString(PyExc_TypeError, "source code string cannot contain null bytes");

result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize);

@@ -815,8 +831,7 @@ builtin_eval(PyObject *self, PyObject *a (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf);

@@ -882,12 +897,13 @@ builtin_exec(PyObject *self, PyObject *a v = PyEval_EvalCode(prog, globals, locals); } else {

@@ -895,7 +911,7 @@ builtin_exec(PyObject *self, PyObject *a locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals);