From f7acd60b07a032fdf3d5c1d5d854ed7ed9da4f02 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Fri, 4 Apr 2025 21:03:21 +0530 Subject: [PATCH 1/4] use unique ref --- Objects/unicodeobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 53c50734281db9..948ef6de2c1ee0 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1816,7 +1816,7 @@ static int unicode_modifiable(PyObject *unicode) { assert(_PyUnicode_CHECK(unicode)); - if (Py_REFCNT(unicode) != 1) + if (!_PyObject_IsUniquelyReferenced(unicode)) return 0; if (PyUnicode_HASH(unicode) != -1) return 0; @@ -14738,7 +14738,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) assert(PyUnicode_IS_ASCII(result)); /* To modify the string in-place, there can only be one reference. */ - if (Py_REFCNT(result) != 1) { + if (!_PyObject_IsUniquelyReferenced(result)) { Py_DECREF(result); PyErr_BadInternalCall(); return NULL; From 6ca1abb2cbc4c7e003770c912c0efb28eb7b1979 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sun, 27 Apr 2025 18:47:07 +0900 Subject: [PATCH 2/4] tmp --- Objects/unicodeobject.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 948ef6de2c1ee0..f31158e83369b8 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1139,6 +1139,21 @@ unicode_fill_invalid(PyObject *unicode, Py_ssize_t old_length) } #endif +static PyObject* +resize_copy(PyObject *unicode, Py_ssize_t length) +{ + Py_ssize_t copy_length; + PyObject *copy; + + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (copy == NULL) + return NULL; + + copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); + return copy; +} + static PyObject* resize_compact(PyObject *unicode, Py_ssize_t length) { @@ -1150,7 +1165,9 @@ resize_compact(PyObject *unicode, Py_ssize_t length) Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif - assert(unicode_modifiable(unicode)); + if (!unicode_modifiable(unicode)) { + return resize_copy(unicode, length); + } assert(PyUnicode_IS_COMPACT(unicode)); char_size = PyUnicode_KIND(unicode); @@ -1250,21 +1267,6 @@ resize_inplace(PyObject *unicode, Py_ssize_t length) return 0; } -static PyObject* -resize_copy(PyObject *unicode, Py_ssize_t length) -{ - Py_ssize_t copy_length; - PyObject *copy; - - copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); - if (copy == NULL) - return NULL; - - copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); - _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); - return copy; -} - static const char* unicode_kind_name(PyObject *unicode) { From 7618a2bcecd761138e7610a1cfc26f665649546d Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sun, 27 Apr 2025 18:51:54 +0900 Subject: [PATCH 3/4] Use resize_copy as fallback logic --- Objects/unicodeobject.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index f31158e83369b8..e7797cb74b3684 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1166,7 +1166,13 @@ resize_compact(PyObject *unicode, Py_ssize_t length) #endif if (!unicode_modifiable(unicode)) { - return resize_copy(unicode, length); + PyObject *copy = resize_copy(unicode, length); + if (copy == NULL) { + PyErr_NoMemory(); + return NULL; + } + Py_DECREF(unicode); + return copy; } assert(PyUnicode_IS_COMPACT(unicode)); From 2750016944e5238d8693979712e4d7e05db9cee2 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Mon, 28 Apr 2025 18:02:38 +0900 Subject: [PATCH 4/4] Update Objects/unicodeobject.c Co-authored-by: Serhiy Storchaka --- Objects/unicodeobject.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e7797cb74b3684..b3287546dd92f0 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1168,7 +1168,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length) if (!unicode_modifiable(unicode)) { PyObject *copy = resize_copy(unicode, length); if (copy == NULL) { - PyErr_NoMemory(); return NULL; } Py_DECREF(unicode);