summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@haypocalc.com>2011-12-12 12:08:33 (GMT)
committerVictor Stinner <victor.stinner@haypocalc.com>2011-12-12 12:08:33 (GMT)
commitb0a82a6a7f0686f99e19cc04b498abcd2896b906 (patch)
treed3fe59d2ff36222b109a886eff57fc85d79a7637
parent521dfb02dd754972f04cd77d80dd34fcf5ac9399 (diff)
downloadcpython-b0a82a6a7f0686f99e19cc04b498abcd2896b906.zip
cpython-b0a82a6a7f0686f99e19cc04b498abcd2896b906.tar.gz
cpython-b0a82a6a7f0686f99e19cc04b498abcd2896b906.tar.bz2
Fix PyUnicode_Resize() for compact string: leave the string unchanged on error
Fix also PyUnicode_Resize() doc
-rw-r--r--Include/unicodeobject.h13
-rw-r--r--Objects/unicodeobject.c29
2 files changed, 14 insertions, 28 deletions
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index 235c677..32d7df7 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -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. */
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 5c2d2a7..6edba5d 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -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;
}