From 8489a551d30c5a555f8b26111bf529665a403b8a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 09:47:52 +0200 Subject: [PATCH 1/3] bpo-29768: Fixed compile-time check for expat version. (#574) (cherry picked from commit 22e707fa04476710ba5cc7e2206e4ac66743931b) --- Modules/pyexpat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 00c96a16c7895a..3a6e590ef21ba6 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1190,7 +1190,7 @@ newxmlparseobject(const char *encoding, const char *namespace_separator, PyObjec Py_DECREF(self); return NULL; } -#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT) +#if XML_COMBINED_VERSION >= 20100 || defined(XML_HAS_SET_HASH_SALT) /* This feature was added upstream in libexpat 2.1.0. Our expat copy * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT * to indicate that we can still use it. */ From d5d39cbdec74f7ddc0dbb5561f0ea8c13e34d0b4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 20:07:58 +0200 Subject: [PATCH 2/3] bpo-29773: Add more cases for testing string to float conversion errors. (#580) (cherry picked from commit 9e6ac83acae31de2b072e665e177db9fcdf7c049) --- Lib/test/test_float.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index cb1f6db8fc7627..28b6954c4d5923 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -98,15 +98,27 @@ def test_float_memoryview(self): self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) def test_error_message(self): - testlist = ('\xbd', '123\xbd', ' 123 456 ') - for s in testlist: - try: + def check(s): + with self.assertRaises(ValueError, msg='float(%r)' % (s,)) as cm: float(s) - except ValueError as e: - self.assertIn(s.strip(), e.args[0]) - else: - self.fail("Expected int(%r) to raise a ValueError", s) - + self.assertEqual(str(cm.exception), + 'could not convert string to float: %r' % (s,)) + + check('\xbd') + check('123\xbd') + check(' 123 456 ') + check(b' 123 456 ') + + # non-ascii digits (error came from non-digit '!') + check('\u0663\u0661\u0664!') + # embedded NUL + check('123\x00') + check('123\x00 245') + check('123\x00245') + # byte string with embedded NUL + check(b'123\x00') + # non-UTF-8 byte string + check(b'123\xa0') @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') def test_float_with_comma(self): From 0b2fe9514fbfcee1bce9357a12066e47f260134e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 12 Mar 2017 13:50:36 +0200 Subject: [PATCH 3/3] bpo-8256: Fixed possible failing or crashing input() (#517) if attributes "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not strings. (cherry picked from commit c2cf12857187aa147c268651f10acd6da2c9cb74) --- Misc/NEWS | 3 +++ Python/bltinmodule.c | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index df0975a4d5ea22..98b47bdab4a8f1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -41,6 +41,9 @@ Extension Modules Library ------- +- bpo-8256: Fixed possible failing or crashing input() if attributes "encoding" + or "errors" of sys.stdin or sys.stdout are not set or are not strings. + - bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big intables (objects that have __int__) as elements. Patch by Oren Milman. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 33d2cc2dc8e2cf..17c074a1b3b26b 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1892,12 +1892,15 @@ builtin_input_impl(PyObject *module, PyObject *prompt) PyObject *result; size_t len; + /* stdin is a text stream, so it must have an encoding. */ stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); - if (!stdin_encoding || !stdin_errors) - /* stdin is a text stream, so it must have an - encoding. */ + if (!stdin_encoding || !stdin_errors || + !PyUnicode_Check(stdin_encoding) || + !PyUnicode_Check(stdin_errors)) { + tty = 0; goto _readline_errors; + } stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); stdin_errors_str = _PyUnicode_AsString(stdin_errors); if (!stdin_encoding_str || !stdin_errors_str) @@ -1913,8 +1916,12 @@ builtin_input_impl(PyObject *module, PyObject *prompt) PyObject *stringpo; stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); - if (!stdout_encoding || !stdout_errors) + if (!stdout_encoding || !stdout_errors || + !PyUnicode_Check(stdout_encoding) || + !PyUnicode_Check(stdout_errors)) { + tty = 0; goto _readline_errors; + } stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); stdout_errors_str = _PyUnicode_AsString(stdout_errors); if (!stdout_encoding_str || !stdout_errors_str) @@ -1969,13 +1976,17 @@ builtin_input_impl(PyObject *module, PyObject *prompt) Py_XDECREF(po); PyMem_FREE(s); return result; + _readline_errors: Py_XDECREF(stdin_encoding); Py_XDECREF(stdout_encoding); Py_XDECREF(stdin_errors); Py_XDECREF(stdout_errors); Py_XDECREF(po); - return NULL; + if (tty) + return NULL; + + PyErr_Clear(); } /* Fallback if we're not interactive */