Fix PyUnicode_Resize() for compact string: leave the string unchanged on error
Fix also PyUnicode_Resize() doc
This commit is contained in:
parent
521dfb02dd
commit
b0a82a6a7f
|
@ -768,18 +768,15 @@ PyAPI_FUNC(int) PyUnicode_WriteChar(
|
|||
PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void);
|
||||
#endif
|
||||
|
||||
/* Resize an Unicode object allocated by the legacy API (e.g.
|
||||
PyUnicode_FromUnicode). Unicode objects allocated by the new API (e.g.
|
||||
PyUnicode_New) cannot be resized by this function.
|
||||
|
||||
The length is a number of characters (and not the number of Py_UNICODE characters).
|
||||
/* Resize an Unicode object. The length is the number of characters, except
|
||||
if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length
|
||||
is the number of Py_UNICODE characters.
|
||||
|
||||
*unicode is modified to point to the new (resized) object and 0
|
||||
returned on success.
|
||||
|
||||
If the refcount on the object is 1, the function resizes the string in
|
||||
place, which is usually faster than allocating a new string (and copy
|
||||
characters).
|
||||
Try to resize the string in place (which is usually faster than allocating
|
||||
a new string and copy characters), or create a new string.
|
||||
|
||||
Error handling is implemented as follows: an exception is set, -1
|
||||
is returned and *unicode left untouched. */
|
||||
|
|
|
@ -655,7 +655,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
|
|||
share_wstr = _PyUnicode_SHARE_WSTR(unicode);
|
||||
|
||||
if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) {
|
||||
Py_DECREF(unicode);
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -666,7 +665,7 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
|
|||
|
||||
new_unicode = (PyObject *)PyObject_REALLOC((char *)unicode, new_size);
|
||||
if (new_unicode == NULL) {
|
||||
PyObject_Del(unicode);
|
||||
_Py_NewReference(unicode);
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -834,8 +833,9 @@ _PyUnicode_New(Py_ssize_t length)
|
|||
new_size = sizeof(Py_UNICODE) * ((size_t)length + 1);
|
||||
_PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_MALLOC(new_size);
|
||||
if (!_PyUnicode_WSTR(unicode)) {
|
||||
Py_DECREF(unicode);
|
||||
PyErr_NoMemory();
|
||||
goto onError;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the first element to guard against cases where
|
||||
|
@ -860,13 +860,6 @@ _PyUnicode_New(Py_ssize_t length)
|
|||
_PyUnicode_UTF8_LENGTH(unicode) = 0;
|
||||
assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0));
|
||||
return unicode;
|
||||
|
||||
onError:
|
||||
/* XXX UNREF/NEWREF interface should be more symmetrical */
|
||||
_Py_DEC_REFTOTAL;
|
||||
_Py_ForgetReference((PyObject *)unicode);
|
||||
PyObject_Del(unicode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char*
|
||||
|
@ -1506,15 +1499,10 @@ unicode_dealloc(register PyObject *unicode)
|
|||
PyObject_DEL(_PyUnicode_WSTR(unicode));
|
||||
if (_PyUnicode_HAS_UTF8_MEMORY(unicode))
|
||||
PyObject_DEL(_PyUnicode_UTF8(unicode));
|
||||
if (!PyUnicode_IS_COMPACT(unicode) && _PyUnicode_DATA_ANY(unicode))
|
||||
PyObject_DEL(_PyUnicode_DATA_ANY(unicode));
|
||||
|
||||
if (PyUnicode_IS_COMPACT(unicode)) {
|
||||
Py_TYPE(unicode)->tp_free(unicode);
|
||||
}
|
||||
else {
|
||||
if (_PyUnicode_DATA_ANY(unicode))
|
||||
PyObject_DEL(_PyUnicode_DATA_ANY(unicode));
|
||||
Py_TYPE(unicode)->tp_free(unicode);
|
||||
}
|
||||
Py_TYPE(unicode)->tp_free(unicode);
|
||||
}
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
@ -1590,9 +1578,10 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length)
|
|||
}
|
||||
|
||||
if (PyUnicode_IS_COMPACT(unicode)) {
|
||||
*p_unicode = resize_compact(unicode, length);
|
||||
if (*p_unicode == NULL)
|
||||
PyObject *new_unicode = resize_compact(unicode, length);
|
||||
if (new_unicode == NULL)
|
||||
return -1;
|
||||
*p_unicode = new_unicode;
|
||||
assert(_PyUnicode_CheckConsistency(*p_unicode, 0));
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue