Skip to content

Commit 1cff94d

Browse files
committed
gh-121849: Fix PyUnicodeWriter_WriteSubstring() crash if len=0
Do nothing if start=end.
1 parent a2bec77 commit 1cff94d

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

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
@@ -13635,27 +13635,28 @@ int
1363513635
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
1363613636
Py_ssize_t start, Py_ssize_t end)
1363713637
{
13638-
Py_UCS4 maxchar;
13639-
Py_ssize_t len;
13640-
1364113638
assert(0 <= start);
1364213639
assert(end <= PyUnicode_GET_LENGTH(str));
1364313640
assert(start <= end);
1364413641

13645-
if (end == 0)
13646-
return 0;
13647-
1364813642
if (start == 0 && end == PyUnicode_GET_LENGTH(str))
1364913643
return _PyUnicodeWriter_WriteStr(writer, str);
1365013644

13651-
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
13645+
Py_ssize_t len = end - start;
13646+
if (len == 0) {
13647+
return 0;
13648+
}
13649+
13650+
Py_UCS4 maxchar;
13651+
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
1365213652
maxchar = _PyUnicode_FindMaxChar(str, start, end);
13653-
else
13653+
}
13654+
else {
1365413655
maxchar = writer->maxchar;
13655-
len = end - start;
13656-
13657-
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0)
13656+
}
13657+
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
1365813658
return -1;
13659+
}
1365913660

1366013661
_PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
1366113662
str, start, len);

0 commit comments

Comments
 (0)