Skip to content

Commit bfdbeac

Browse files
authored
pythongh-121849: Fix PyUnicodeWriter_WriteSubstring() crash if len=0 (python#121896)
Do nothing if start=end.
1 parent 5d98a4d commit bfdbeac

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

Lib/test/test_capi/test_unicode.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1736,7 +1736,7 @@ def test_basic(self):
17361736
writer.write_char('=')
17371737

17381738
# test PyUnicodeWriter_WriteSubstring()
1739-
writer.write_substring("[long]", 1, 5);
1739+
writer.write_substring("[long]", 1, 5)
17401740

17411741
# test PyUnicodeWriter_WriteStr()
17421742
writer.write_str(" value ")
@@ -1862,6 +1862,10 @@ def test_ucs4(self):
18621862
with self.assertRaises(ValueError):
18631863
writer.write_ucs4("text", -1)
18641864

1865+
def test_substring_empty(self):
1866+
writer = self.create_writer(0)
1867+
writer.write_substring("abc", 1, 1)
1868+
self.assertEqual(writer.finish(), '')
18651869

18661870

18671871
@unittest.skipIf(ctypes is None, 'need ctypes')

Objects/unicodeobject.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13637,27 +13637,28 @@ int
1363713637
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
1363813638
Py_ssize_t start, Py_ssize_t end)
1363913639
{
13640-
Py_UCS4 maxchar;
13641-
Py_ssize_t len;
13642-
1364313640
assert(0 <= start);
1364413641
assert(end <= PyUnicode_GET_LENGTH(str));
1364513642
assert(start <= end);
1364613643

13647-
if (end == 0)
13648-
return 0;
13649-
1365013644
if (start == 0 && end == PyUnicode_GET_LENGTH(str))
1365113645
return _PyUnicodeWriter_WriteStr(writer, str);
1365213646

13653-
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
13647+
Py_ssize_t len = end - start;
13648+
if (len == 0) {
13649+
return 0;
13650+
}
13651+
13652+
Py_UCS4 maxchar;
13653+
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
1365413654
maxchar = _PyUnicode_FindMaxChar(str, start, end);
13655-
else
13655+
}
13656+
else {
1365613657
maxchar = writer->maxchar;
13657-
len = end - start;
13658-
13659-
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0)
13658+
}
13659+
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
1366013660
return -1;
13661+
}
1366113662

1366213663
_PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
1366313664
str, start, len);

0 commit comments

Comments
 (0)