diff -r 656543a2ad75 Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c Mon Mar 02 23:32:02 2015 -0800 +++ b/Objects/bytearrayobject.c Tue Mar 03 14:39:56 2015 +0200 @@ -1142,7 +1142,7 @@ bytearray_find_internal(PyByteArrayObjec char byte; Py_buffer subbuf; const char *sub; - Py_ssize_t sub_len; + Py_ssize_t len, sub_len; Py_ssize_t start=0, end=PY_SSIZE_T_MAX; Py_ssize_t res; @@ -1161,15 +1161,30 @@ bytearray_find_internal(PyByteArrayObjec sub = &byte; sub_len = 1; } - - if (dir > 0) - res = stringlib_find_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - sub, sub_len, start, end); - else - res = stringlib_rfind_slice( - PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), - sub, sub_len, start, end); + len = PyByteArray_GET_SIZE(self); + + ADJUST_INDICES(start, end, len); + if (end - start < sub_len) + res = -1; + else if (sub_len == 1) { + unsigned char needle = *sub; + int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; + res = stringlib_fastsearch_memchr_1char( + PyByteArray_AS_STRING(self) + start, end - start, + needle, needle, mode); + if (res >= 0) + res += start; + } + else { + if (dir > 0) + res = stringlib_find_slice( + PyByteArray_AS_STRING(self), len, + sub, sub_len, start, end); + else + res = stringlib_rfind_slice( + PyByteArray_AS_STRING(self), len, + sub, sub_len, start, end); + } if (subobj) PyBuffer_Release(&subbuf); diff -r 656543a2ad75 Objects/bytesobject.c --- a/Objects/bytesobject.c Mon Mar 02 23:32:02 2015 -0800 +++ b/Objects/bytesobject.c Tue Mar 03 14:39:56 2015 +0200 @@ -1903,7 +1903,7 @@ bytes_find_internal(PyBytesObject *self, char byte; Py_buffer subbuf; const char *sub; - Py_ssize_t sub_len; + Py_ssize_t len, sub_len; Py_ssize_t start=0, end=PY_SSIZE_T_MAX; Py_ssize_t res; @@ -1922,15 +1922,30 @@ bytes_find_internal(PyBytesObject *self, sub = &byte; sub_len = 1; } - - if (dir > 0) - res = stringlib_find_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); - else - res = stringlib_rfind_slice( - PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), - sub, sub_len, start, end); + len = PyBytes_GET_SIZE(self); + + ADJUST_INDICES(start, end, len); + if (end - start < sub_len) + res = -1; + else if (sub_len == 1) { + unsigned char needle = *sub; + int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; + res = stringlib_fastsearch_memchr_1char( + PyBytes_AS_STRING(self) + start, end - start, + needle, needle, mode); + if (res >= 0) + res += start; + } + else { + if (dir > 0) + res = stringlib_find_slice( + PyBytes_AS_STRING(self), len, + sub, sub_len, start, end); + else + res = stringlib_rfind_slice( + PyBytes_AS_STRING(self), len, + sub, sub_len, start, end); + } if (subobj) PyBuffer_Release(&subbuf); diff -r 656543a2ad75 Objects/stringlib/fastsearch.h --- a/Objects/stringlib/fastsearch.h Mon Mar 02 23:32:02 2015 -0800 +++ b/Objects/stringlib/fastsearch.h Tue Mar 03 14:39:56 2015 +0200 @@ -36,7 +36,7 @@ Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(fastsearch_memchr_1char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch, unsigned char needle, - Py_ssize_t maxcount, int mode) + int mode) { if (mode == FAST_SEARCH) { const STRINGLIB_CHAR *ptr = s; @@ -115,7 +115,7 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_s if (needle != 0) #endif return STRINGLIB(fastsearch_memchr_1char) - (s, n, p[0], needle, maxcount, mode); + (s, n, p[0], needle, mode); } if (mode == FAST_COUNT) { for (i = 0; i < n; i++) diff -r 656543a2ad75 Objects/stringlib/find.h --- a/Objects/stringlib/find.h Mon Mar 02 23:32:02 2015 -0800 +++ b/Objects/stringlib/find.h Tue Mar 03 14:39:56 2015 +0200 @@ -11,8 +11,7 @@ STRINGLIB(find)(const STRINGLIB_CHAR* st { Py_ssize_t pos; - if (str_len < 0) - return -1; + assert(str_len >= 0); if (sub_len == 0) return offset; @@ -31,8 +30,7 @@ STRINGLIB(rfind)(const STRINGLIB_CHAR* s { Py_ssize_t pos; - if (str_len < 0) - return -1; + assert(str_len >= 0); if (sub_len == 0) return str_len + offset; @@ -44,27 +42,11 @@ STRINGLIB(rfind)(const STRINGLIB_CHAR* s return pos; } -/* helper macro to fixup start/end slice values */ -#define ADJUST_INDICES(start, end, len) \ - if (end > len) \ - end = len; \ - else if (end < 0) { \ - end += len; \ - if (end < 0) \ - end = 0; \ - } \ - if (start < 0) { \ - start += len; \ - if (start < 0) \ - start = 0; \ - } - Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(find_slice)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, Py_ssize_t start, Py_ssize_t end) { - ADJUST_INDICES(start, end, str_len); return STRINGLIB(find)(str + start, end - start, sub, sub_len, start); } @@ -73,7 +55,6 @@ STRINGLIB(rfind_slice)(const STRINGLIB_C const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, Py_ssize_t start, Py_ssize_t end) { - ADJUST_INDICES(start, end, str_len); return STRINGLIB(rfind)(str + start, end - start, sub, sub_len, start); } diff -r 656543a2ad75 Objects/unicodeobject.c --- a/Objects/unicodeobject.c Mon Mar 02 23:32:02 2015 -0800 +++ b/Objects/unicodeobject.c Tue Mar 03 14:39:56 2015 +0200 @@ -641,7 +641,7 @@ make_bloom_mask(int kind, void* ptr, Py_ static PyObject * fixup(PyObject *self, Py_UCS4 (*fixfct)(PyObject *s)); -Py_LOCAL_INLINE(Py_ssize_t) findchar(void *s, int kind, +Py_LOCAL_INLINE(Py_ssize_t) findchar(const void *s, int kind, Py_ssize_t size, Py_UCS4 ch, int direction) { @@ -8958,35 +8958,61 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, /* --- Helpers ------------------------------------------------------------ */ +/* helper macro to fixup start/end slice values */ +#define ADJUST_INDICES(start, end, len) \ + if (end > len) \ + end = len; \ + else if (end < 0) { \ + end += len; \ + if (end < 0) \ + end = 0; \ + } \ + if (start < 0) { \ + start += len; \ + if (start < 0) \ + start = 0; \ + } + static Py_ssize_t any_find_slice(int direction, PyObject* s1, PyObject* s2, Py_ssize_t start, Py_ssize_t end) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2, result; kind1 = PyUnicode_KIND(s1); kind2 = PyUnicode_KIND(s2); - kind = kind1 > kind2 ? kind1 : kind2; + if (kind1 < kind2) + return -1; + + len1 = PyUnicode_GET_LENGTH(s1); + len2 = PyUnicode_GET_LENGTH(s2); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) + return -1; + buf1 = PyUnicode_DATA(s1); buf2 = PyUnicode_DATA(s2); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(s1, kind); - if (!buf1) - return -2; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(s2, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return -2; - } - len1 = PyUnicode_GET_LENGTH(s1); - len2 = PyUnicode_GET_LENGTH(s2); + if (len2 == 1) { + Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0); + result = findchar((const char *)buf1 + kind1*start, + kind1, end - start, ch, direction); + if (result == -1) + return -1; + else + return start + result; + } + + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(s2, kind1); + if (!buf2) + return -2; + } if (direction > 0) { - switch (kind) { + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2)) result = asciilib_find_slice(buf1, len1, buf2, len2, start, end); @@ -9004,7 +9030,7 @@ any_find_slice(int direction, PyObject* } } else { - switch (kind) { + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2)) result = asciilib_rfind_slice(buf1, len1, buf2, len2, start, end); @@ -9022,9 +9048,7 @@ any_find_slice(int direction, PyObject* } } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return result; @@ -9114,21 +9138,6 @@ Py_ssize_t } -/* helper macro to fixup start/end slice values */ -#define ADJUST_INDICES(start, end, len) \ - if (end > len) \ - end = len; \ - else if (end < 0) { \ - end += len; \ - if (end < 0) \ - end = 0; \ - } \ - if (start < 0) { \ - start += len; \ - if (start < 0) \ - start = 0; \ - } - Py_ssize_t PyUnicode_Count(PyObject *str, PyObject *substr, @@ -9138,7 +9147,7 @@ PyUnicode_Count(PyObject *str, Py_ssize_t result; PyObject* str_obj; PyObject* sub_obj; - int kind1, kind2, kind; + int kind1, kind2; void *buf1 = NULL, *buf2 = NULL; Py_ssize_t len1, len2; @@ -9158,24 +9167,30 @@ PyUnicode_Count(PyObject *str, kind1 = PyUnicode_KIND(str_obj); kind2 = PyUnicode_KIND(sub_obj); - kind = kind1; + if (kind1 < kind2) { + Py_DECREF(sub_obj); + Py_DECREF(str_obj); + return 0; + } + + len1 = PyUnicode_GET_LENGTH(str_obj); + len2 = PyUnicode_GET_LENGTH(sub_obj); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) { + Py_DECREF(sub_obj); + Py_DECREF(str_obj); + return 0; + } + buf1 = PyUnicode_DATA(str_obj); buf2 = PyUnicode_DATA(sub_obj); - if (kind2 != kind) { - if (kind2 > kind) { - Py_DECREF(sub_obj); - Py_DECREF(str_obj); - return 0; - } - buf2 = _PyUnicode_AsKind(sub_obj, kind); - } - if (!buf2) - goto onError; - len1 = PyUnicode_GET_LENGTH(str_obj); - len2 = PyUnicode_GET_LENGTH(sub_obj); - - ADJUST_INDICES(start, end, len1); - switch (kind) { + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sub_obj, kind1); + if (!buf2) + goto onError; + } + + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sub_obj)) result = asciilib_count( @@ -9207,14 +9222,14 @@ PyUnicode_Count(PyObject *str, Py_DECREF(sub_obj); Py_DECREF(str_obj); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return result; onError: Py_DECREF(sub_obj); Py_DECREF(str_obj); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return -1; } @@ -9267,6 +9282,8 @@ PyUnicode_FindChar(PyObject *str, Py_UCS } if (end > PyUnicode_GET_LENGTH(str)) end = PyUnicode_GET_LENGTH(str); + if (start >= end) + return -1; kind = PyUnicode_KIND(str); result = findchar(PyUnicode_1BYTE_DATA(str) + kind*start, kind, end-start, ch, direction); @@ -10013,7 +10030,7 @@ split(PyObject *self, PyObject *substring, Py_ssize_t maxcount) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; @@ -10057,23 +10074,25 @@ split(PyObject *self, kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - kind = kind1 > kind2 ? kind1 : kind2; + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + if (kind1 < kind2 || len1 < len2) { + out = PyList_New(1); + if (out == NULL) + return NULL; + Py_INCREF(self); + PyList_SET_ITEM(out, 0, self); + return out; + } buf1 = PyUnicode_DATA(self); buf2 = PyUnicode_DATA(substring); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(self, kind); - if (!buf1) - return NULL; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return NULL; - } - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - - switch (kind) { + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) out = asciilib_split( @@ -10093,9 +10112,7 @@ split(PyObject *self, default: out = NULL; } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; } @@ -10105,7 +10122,7 @@ rsplit(PyObject *self, PyObject *substring, Py_ssize_t maxcount) { - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; @@ -10149,23 +10166,25 @@ rsplit(PyObject *self, kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - kind = kind1 > kind2 ? kind1 : kind2; + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + if (kind1 < kind2 || len1 < len2) { + out = PyList_New(1); + if (out == NULL) + return NULL; + Py_INCREF(self); + PyList_SET_ITEM(out, 0, self); + return out; + } buf1 = PyUnicode_DATA(self); buf2 = PyUnicode_DATA(substring); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(self, kind); - if (!buf1) - return NULL; - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - if (kind1 != kind) PyMem_Free(buf1); - return NULL; - } - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - - switch (kind) { + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) + return NULL; + } + + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring)) out = asciilib_rsplit( @@ -10185,9 +10204,7 @@ rsplit(PyObject *self, default: out = NULL; } - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; } @@ -10406,7 +10423,7 @@ replace(PyObject *self, PyObject *str1, } /* new_size = PyUnicode_GET_LENGTH(self) + n * (PyUnicode_GET_LENGTH(str2) - PyUnicode_GET_LENGTH(str1))); */ - if (len2 > len1 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) { + if (len1 < len2 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) { PyErr_SetString(PyExc_OverflowError, "replace string is too long"); goto error; @@ -10815,7 +10832,7 @@ PyUnicode_CompareWithASCIIString(PyObjec } if (len1 > len2) return 1; /* uni is longer */ - if (len2 > len1) + if (len1 < len2) return -1; /* str is longer */ return 0; } @@ -10927,23 +10944,35 @@ PyUnicode_Contains(PyObject *container, kind1 = PyUnicode_KIND(str); kind2 = PyUnicode_KIND(sub); + if (kind1 < kind2) { + Py_DECREF(sub); + Py_DECREF(str); + return 0; + } + len1 = PyUnicode_GET_LENGTH(str); + len2 = PyUnicode_GET_LENGTH(sub); + if (len1 < len2) { + Py_DECREF(sub); + Py_DECREF(str); + return 0; + } buf1 = PyUnicode_DATA(str); buf2 = PyUnicode_DATA(sub); + if (len2 == 1) { + Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0); + result = findchar((const char *)buf1, kind1, len1, ch, 1) != -1; + Py_DECREF(sub); + Py_DECREF(str); + return result; + } if (kind2 != kind1) { - if (kind2 > kind1) { + buf2 = _PyUnicode_AsKind(sub, kind1); + if (!buf2) { Py_DECREF(sub); Py_DECREF(str); - return 0; - } - buf2 = _PyUnicode_AsKind(sub, kind1); - } - if (!buf2) { - Py_DECREF(sub); - Py_DECREF(str); - return -1; - } - len1 = PyUnicode_GET_LENGTH(str); - len2 = PyUnicode_GET_LENGTH(sub); + return -1; + } + } switch (kind1) { case PyUnicode_1BYTE_KIND: @@ -11128,7 +11157,7 @@ unicode_count(PyObject *self, PyObject * Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; PyObject *result; - int kind1, kind2, kind; + int kind1, kind2; void *buf1, *buf2; Py_ssize_t len1, len2, iresult; @@ -11138,24 +11167,27 @@ unicode_count(PyObject *self, PyObject * kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - if (kind2 > kind1) { + if (kind1 < kind2) { Py_DECREF(substring); return PyLong_FromLong(0); } - kind = kind1; + len1 = PyUnicode_GET_LENGTH(self); + len2 = PyUnicode_GET_LENGTH(substring); + ADJUST_INDICES(start, end, len1); + if (end - start < len2) { + Py_DECREF(substring); + return PyLong_FromLong(0); + } buf1 = PyUnicode_DATA(self); buf2 = PyUnicode_DATA(substring); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(substring, kind); - if (!buf2) { - Py_DECREF(substring); - return NULL; - } - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - - ADJUST_INDICES(start, end, len1); - switch (kind) { + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(substring, kind1); + if (!buf2) { + Py_DECREF(substring); + return NULL; + } + } + switch (kind1) { case PyUnicode_1BYTE_KIND: iresult = ucs1lib_count( ((Py_UCS1*)buf1) + start, end - start, @@ -11180,7 +11212,7 @@ unicode_count(PyObject *self, PyObject * result = PyLong_FromSsize_t(iresult); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); Py_DECREF(substring); @@ -12627,8 +12659,8 @@ PyUnicode_Partition(PyObject *str_in, Py PyObject* str_obj; PyObject* sep_obj; PyObject* out; - int kind1, kind2, kind; - void *buf1 = NULL, *buf2 = NULL; + int kind1, kind2; + void *buf1, *buf2; Py_ssize_t len1, len2; str_obj = PyUnicode_FromObject(str_in); @@ -12647,21 +12679,29 @@ PyUnicode_Partition(PyObject *str_in, Py kind1 = PyUnicode_KIND(str_obj); kind2 = PyUnicode_KIND(sep_obj); - kind = Py_MAX(kind1, kind2); - buf1 = PyUnicode_DATA(str_obj); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(str_obj, kind); - if (!buf1) - goto onError; - buf2 = PyUnicode_DATA(sep_obj); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(sep_obj, kind); - if (!buf2) - goto onError; len1 = PyUnicode_GET_LENGTH(str_obj); len2 = PyUnicode_GET_LENGTH(sep_obj); - - switch (PyUnicode_KIND(str_obj)) { + if (kind1 < kind2 || len1 < len2) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + out = NULL; + else { + out = PyTuple_Pack(3, str_obj, unicode_empty, unicode_empty); + Py_DECREF(unicode_empty); + } + Py_DECREF(sep_obj); + Py_DECREF(str_obj); + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + goto onError; + } + + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj)) out = asciilib_partition(str_obj, buf1, len1, sep_obj, buf2, len2); @@ -12681,18 +12721,14 @@ PyUnicode_Partition(PyObject *str_in, Py Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; onError: Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind && buf1) - PyMem_Free(buf1); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return NULL; } @@ -12704,8 +12740,8 @@ PyUnicode_RPartition(PyObject *str_in, P PyObject* str_obj; PyObject* sep_obj; PyObject* out; - int kind1, kind2, kind; - void *buf1 = NULL, *buf2 = NULL; + int kind1, kind2; + void *buf1, *buf2; Py_ssize_t len1, len2; str_obj = PyUnicode_FromObject(str_in); @@ -12717,23 +12753,31 @@ PyUnicode_RPartition(PyObject *str_in, P return NULL; } - kind1 = PyUnicode_KIND(str_in); + kind1 = PyUnicode_KIND(str_obj); kind2 = PyUnicode_KIND(sep_obj); - kind = Py_MAX(kind1, kind2); - buf1 = PyUnicode_DATA(str_in); - if (kind1 != kind) - buf1 = _PyUnicode_AsKind(str_in, kind); - if (!buf1) - goto onError; - buf2 = PyUnicode_DATA(sep_obj); - if (kind2 != kind) - buf2 = _PyUnicode_AsKind(sep_obj, kind); - if (!buf2) - goto onError; len1 = PyUnicode_GET_LENGTH(str_obj); len2 = PyUnicode_GET_LENGTH(sep_obj); - - switch (PyUnicode_KIND(str_in)) { + if (kind1 < kind2 || len1 < len2) { + _Py_INCREF_UNICODE_EMPTY(); + if (!unicode_empty) + out = NULL; + else { + out = PyTuple_Pack(3, unicode_empty, unicode_empty, str_obj); + Py_DECREF(unicode_empty); + } + Py_DECREF(sep_obj); + Py_DECREF(str_obj); + return out; + } + buf1 = PyUnicode_DATA(str_obj); + buf2 = PyUnicode_DATA(sep_obj); + if (kind2 != kind1) { + buf2 = _PyUnicode_AsKind(sep_obj, kind1); + if (!buf2) + goto onError; + } + + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj)) out = asciilib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2); @@ -12753,18 +12797,14 @@ PyUnicode_RPartition(PyObject *str_in, P Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind) - PyMem_Free(buf1); - if (kind2 != kind) + if (kind2 != kind1) PyMem_Free(buf2); return out; onError: Py_DECREF(sep_obj); Py_DECREF(str_obj); - if (kind1 != kind && buf1) - PyMem_Free(buf1); - if (kind2 != kind && buf2) + if (kind2 != kind1 && buf2) PyMem_Free(buf2); return NULL; }