Commit 16dfca4d authored by INADA Naoki's avatar INADA Naoki Committed by GitHub

bpo-34087: Fix buffer overflow in int(s) and similar functions (GH-8274)

`_PyUnicode_TransformDecimalAndSpaceToASCII()` missed trailing NUL char.
It caused buffer overflow in `_Py_string_to_number_with_underscores()`.

This bug is introduced in 9b6c60cb.
parent cafaf044
...@@ -345,6 +345,9 @@ class ComplexTest(unittest.TestCase): ...@@ -345,6 +345,9 @@ class ComplexTest(unittest.TestCase):
self.assertEqual(type(complex("1"*500)), complex) self.assertEqual(type(complex("1"*500)), complex)
# check whitespace processing # check whitespace processing
self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j) self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j)
# Invalid unicode string
# See bpo-34087
self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f')
class EvilExc(Exception): class EvilExc(Exception):
pass pass
......
...@@ -60,6 +60,9 @@ class GeneralFloatCases(unittest.TestCase): ...@@ -60,6 +60,9 @@ class GeneralFloatCases(unittest.TestCase):
# extra long strings should not be a problem # extra long strings should not be a problem
float(b'.' + b'1'*1000) float(b'.' + b'1'*1000)
float('.' + '1'*1000) float('.' + '1'*1000)
# Invalid unicode string
# See bpo-34087
self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
def test_underscores(self): def test_underscores(self):
for lit in VALID_UNDERSCORE_LITERALS: for lit in VALID_UNDERSCORE_LITERALS:
......
...@@ -373,6 +373,10 @@ class LongTest(unittest.TestCase): ...@@ -373,6 +373,10 @@ class LongTest(unittest.TestCase):
for base in invalid_bases: for base in invalid_bases:
self.assertRaises(ValueError, int, '42', base) self.assertRaises(ValueError, int, '42', base)
# Invalid unicode string
# See bpo-34087
self.assertRaises(ValueError, int, '\u3053\u3093\u306b\u3061\u306f')
def test_conversion(self): def test_conversion(self):
......
Fix buffer overflow while converting unicode to numeric values.
...@@ -9072,6 +9072,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) ...@@ -9072,6 +9072,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
int decimal = Py_UNICODE_TODECIMAL(ch); int decimal = Py_UNICODE_TODECIMAL(ch);
if (decimal < 0) { if (decimal < 0) {
out[i] = '?'; out[i] = '?';
out[i+1] = '\0';
_PyUnicode_LENGTH(result) = i + 1; _PyUnicode_LENGTH(result) = i + 1;
break; break;
} }
...@@ -9079,6 +9080,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) ...@@ -9079,6 +9080,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
} }
} }
assert(_PyUnicode_CheckConsistency(result, 1));
return result; return result;
} }
......
...@@ -391,6 +391,8 @@ _Py_string_to_number_with_underscores( ...@@ -391,6 +391,8 @@ _Py_string_to_number_with_underscores(
char *dup, *end; char *dup, *end;
PyObject *result; PyObject *result;
assert(s[orig_len] == '\0');
if (strchr(s, '_') == NULL) { if (strchr(s, '_') == NULL) {
return innerfunc(s, orig_len, arg); return innerfunc(s, orig_len, arg);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment