diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 53c50734281db9..b3287546dd92f0 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,14 @@ 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)) { + PyObject *copy = resize_copy(unicode, length); + if (copy == NULL) { + return NULL; + } + Py_DECREF(unicode); + return copy; + } assert(PyUnicode_IS_COMPACT(unicode)); char_size = PyUnicode_KIND(unicode); @@ -1250,21 +1272,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) { @@ -1816,7 +1823,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 +14745,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;