Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3bfe19

Browse files
committed
fix possible overflow in encode_basestring_ascii (closes #23369)
1 parent 4dbc305 commit e3bfe19

3 files changed

Lines changed: 25 additions & 5 deletions

File tree

Lib/test/test_json/test_encode_basestring_ascii.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from collections import OrderedDict
22
from test.test_json import PyTest, CTest
3+
from test.support import bigaddrspacetest
34

45

56
CASES = [
@@ -41,4 +42,10 @@ def test_sorted_dict(self):
4142

4243

4344
class TestPyEncodeBasestringAscii(TestEncodeBasestringAscii, PyTest): pass
44-
class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest): pass
45+
class TestCEncodeBasestringAscii(TestEncodeBasestringAscii, CTest):
46+
@bigaddrspacetest
47+
def test_overflow(self):
48+
s = "\uffff"*((2**32)//6 + 1)
49+
with self.assertRaises(OverflowError):
50+
self.json.encoder.encode_basestring_ascii(s)
51+

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ Core and Builtins
1313
- Issue #23055: Fixed a buffer overflow in PyUnicode_FromFormatV. Analysis
1414
and fix by Guido Vranken.
1515

16+
Library
17+
-------
18+
19+
- Issue #23369: Fixed possible integer overflow in
20+
_json.encode_basestring_ascii.
21+
1622

1723
What's New in Python 3.3.6?
1824
===========================

Modules/_json.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,24 @@ ascii_escape_unicode(PyObject *pystr)
216216
/* Compute the output size */
217217
for (i = 0, output_size = 2; i < input_chars; i++) {
218218
Py_UCS4 c = PyUnicode_READ(kind, input, i);
219-
if (S_CHAR(c))
220-
output_size++;
219+
Py_ssize_t d;
220+
if (S_CHAR(c)) {
221+
d = 1;
222+
}
221223
else {
222224
switch(c) {
223225
case '\\': case '"': case '\b': case '\f':
224226
case '\n': case '\r': case '\t':
225-
output_size += 2; break;
227+
d = 2; break;
226228
default:
227-
output_size += c >= 0x10000 ? 12 : 6;
229+
d = c >= 0x10000 ? 12 : 6;
228230
}
229231
}
232+
if (output_size > PY_SSIZE_T_MAX - d) {
233+
PyErr_SetString(PyExc_OverflowError, "string is too long to escape");
234+
return NULL;
235+
}
236+
output_size += d;
230237
}
231238

232239
rval = PyUnicode_New(output_size, 127);

0 commit comments

Comments
 (0)