https://github.com/python/cpython/commit/bfdbeac355235f6831ace5b514264bd1908000e5
commit: bfdbeac355235f6831ace5b514264bd1908000e5
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2024-07-17T10:26:05+02:00
summary:

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

Do nothing if start=end.

files:
M Lib/test/test_capi/test_unicode.py
M Objects/unicodeobject.c

diff --git a/Lib/test/test_capi/test_unicode.py 
b/Lib/test/test_capi/test_unicode.py
index 9ef476a02de47d..e6f85427214958 100644
--- a/Lib/test/test_capi/test_unicode.py
+++ b/Lib/test/test_capi/test_unicode.py
@@ -1736,7 +1736,7 @@ def test_basic(self):
         writer.write_char('=')
 
         # test PyUnicodeWriter_WriteSubstring()
-        writer.write_substring("[long]", 1, 5);
+        writer.write_substring("[long]", 1, 5)
 
         # test PyUnicodeWriter_WriteStr()
         writer.write_str(" value ")
@@ -1862,6 +1862,10 @@ def test_ucs4(self):
         with self.assertRaises(ValueError):
             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')
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 408d74fb3afef9..6196a8e766a15b 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -13637,27 +13637,28 @@ int
 _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
                                 Py_ssize_t start, Py_ssize_t end)
 {
-    Py_UCS4 maxchar;
-    Py_ssize_t len;
-
     assert(0 <= start);
     assert(end <= PyUnicode_GET_LENGTH(str));
     assert(start <= end);
 
-    if (end == 0)
-        return 0;
-
     if (start == 0 && end == PyUnicode_GET_LENGTH(str))
         return _PyUnicodeWriter_WriteStr(writer, str);
 
-    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
+    Py_ssize_t len = end - start;
+    if (len == 0) {
+        return 0;
+    }
+
+    Py_UCS4 maxchar;
+    if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar) {
         maxchar = _PyUnicode_FindMaxChar(str, start, end);
-    else
+    }
+    else {
         maxchar = writer->maxchar;
-    len = end - start;
-
-    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0)
+    }
+    if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0) {
         return -1;
+    }
 
     _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
                                   str, start, len);

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to