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