Skip to content

Commit 16dfca4

Browse files
authored
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 9b6c60c.
1 parent cafaf04 commit 16dfca4

File tree

6 files changed

+15
-0
lines changed

6 files changed

+15
-0
lines changed

Lib/test/test_complex.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ def split_zeros(x):
345345
self.assertEqual(type(complex("1"*500)), complex)
346346
# check whitespace processing
347347
self.assertEqual(complex('\N{EM SPACE}(\N{EN SPACE}1+1j ) '), 1+1j)
348+
# Invalid unicode string
349+
# See bpo-34087
350+
self.assertRaises(ValueError, complex, '\u3053\u3093\u306b\u3061\u306f')
348351

349352
class EvilExc(Exception):
350353
pass

Lib/test/test_float.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ def test_float(self):
6060
# extra long strings should not be a problem
6161
float(b'.' + b'1'*1000)
6262
float('.' + '1'*1000)
63+
# Invalid unicode string
64+
# See bpo-34087
65+
self.assertRaises(ValueError, float, '\u3053\u3093\u306b\u3061\u306f')
6366

6467
def test_underscores(self):
6568
for lit in VALID_UNDERSCORE_LITERALS:

Lib/test/test_long.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ def test_long(self):
373373
for base in invalid_bases:
374374
self.assertRaises(ValueError, int, '42', base)
375375

376+
# Invalid unicode string
377+
# See bpo-34087
378+
self.assertRaises(ValueError, int, '\u3053\u3093\u306b\u3061\u306f')
379+
376380

377381
def test_conversion(self):
378382

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix buffer overflow while converting unicode to numeric values.

Objects/unicodeobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9072,13 +9072,15 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
90729072
int decimal = Py_UNICODE_TODECIMAL(ch);
90739073
if (decimal < 0) {
90749074
out[i] = '?';
9075+
out[i+1] = '\0';
90759076
_PyUnicode_LENGTH(result) = i + 1;
90769077
break;
90779078
}
90789079
out[i] = '0' + decimal;
90799080
}
90809081
}
90819082

9083+
assert(_PyUnicode_CheckConsistency(result, 1));
90829084
return result;
90839085
}
90849086

Python/pystrtod.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ _Py_string_to_number_with_underscores(
391391
char *dup, *end;
392392
PyObject *result;
393393

394+
assert(s[orig_len] == '\0');
395+
394396
if (strchr(s, '_') == NULL) {
395397
return innerfunc(s, orig_len, arg);
396398
}

0 commit comments

Comments
 (0)