Browse Source

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.
pull/8281/head
INADA Naoki 8 years ago
committed by GitHub
parent
commit
16dfca4d82
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      Lib/test/test_complex.py
  2. 3
      Lib/test/test_float.py
  3. 4
      Lib/test/test_long.py
  4. 1
      Misc/NEWS.d/next/Core and Builtins/2018-07-13-22-09-55.bpo-34087.I1Bxfc.rst
  5. 2
      Objects/unicodeobject.c
  6. 2
      Python/pystrtod.c

3
Lib/test/test_complex.py

@ -345,6 +345,9 @@ class ComplexTest(unittest.TestCase):
self.assertEqual(type(complex("1"*500)), complex)
# check whitespace processing
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):
pass

3
Lib/test/test_float.py

@ -60,6 +60,9 @@ class GeneralFloatCases(unittest.TestCase):
# extra long strings should not be a problem
float(b'.' + b'1'*1000)
float('.' + '1'*1000)
# Invalid unicode string
# See bpo-34087
self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
def test_underscores(self):
for lit in VALID_UNDERSCORE_LITERALS:

4
Lib/test/test_long.py

@ -373,6 +373,10 @@ class LongTest(unittest.TestCase):
for base in invalid_bases:
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):

1
Misc/NEWS.d/next/Core and Builtins/2018-07-13-22-09-55.bpo-34087.I1Bxfc.rst

@ -0,0 +1 @@
Fix buffer overflow while converting unicode to numeric values.

2
Objects/unicodeobject.c

@ -9072,6 +9072,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
int decimal = Py_UNICODE_TODECIMAL(ch);
if (decimal < 0) {
out[i] = '?';
out[i+1] = '\0';
_PyUnicode_LENGTH(result) = i + 1;
break;
}
@ -9079,6 +9080,7 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
}
}
assert(_PyUnicode_CheckConsistency(result, 1));
return result;
}

2
Python/pystrtod.c

@ -391,6 +391,8 @@ _Py_string_to_number_with_underscores(
char *dup, *end;
PyObject *result;
assert(s[orig_len] == '\0');
if (strchr(s, '_') == NULL) {
return innerfunc(s, orig_len, arg);
}

Loading…
Cancel
Save