gh-121849: Fix PyUnicodeWriter_WriteSubstring() crash if len=0 (#121896)

Do nothing if start=end.
This commit is contained in:
Victor Stinner 2024-07-17 10:26:05 +02:00 committed by GitHub
parent 5d98a4d266
commit bfdbeac355
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 13 deletions

View File

@ -1736,7 +1736,7 @@ class PyUnicodeWriterTest(unittest.TestCase):
writer.write_char('=') writer.write_char('=')
# test PyUnicodeWriter_WriteSubstring() # test PyUnicodeWriter_WriteSubstring()
writer.write_substring("[long]", 1, 5); writer.write_substring("[long]", 1, 5)
# test PyUnicodeWriter_WriteStr() # test PyUnicodeWriter_WriteStr()
writer.write_str(" value ") writer.write_str(" value ")
@ -1862,6 +1862,10 @@ class PyUnicodeWriterTest(unittest.TestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
writer.write_ucs4("text", -1) writer.write_ucs4("text", -1)
def test_substring_empty(self):
writer = self.create_writer(0)
writer.write_substring("abc", 1, 1)
self.assertEqual(writer.finish(), '')
@unittest.skipIf(ctypes is None, 'need ctypes') @unittest.skipIf(ctypes is None, 'need ctypes')

View File

@ -13637,27 +13637,28 @@ int
_PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str, _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
Py_ssize_t start, Py_ssize_t end) Py_ssize_t start, Py_ssize_t end)
{ {
Py_UCS4 maxchar;
Py_ssize_t len;
assert(0 <= start); assert(0 <= start);
assert(end <= PyUnicode_GET_LENGTH(str)); assert(end <= PyUnicode_GET_LENGTH(str));
assert(start <= end); assert(start <= end);
if (end == 0)
return 0;
if (start == 0 && end == PyUnicode_GET_LENGTH(str)) if (start == 0 && end == PyUnicode_GET_LENGTH(str))
return _PyUnicodeWriter_WriteStr(writer, str); return _PyUnicodeWriter_WriteStr(writer, str);
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) Py_ssize_t len = end - start;
maxchar = _PyUnicode_FindMaxChar(str, start, end); if (len == 0) {
else return 0;
maxchar = writer->maxchar; }
len = end - start;
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) Py_UCS4 maxchar;
if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
maxchar = _PyUnicode_FindMaxChar(str, start, end);
}
else {
maxchar = writer->maxchar;
}
if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
return -1; return -1;
}
_PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
str, start, len); str, start, len);