From 419967b8320be40d7948bde042e92b6e7d1f48a7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 6 Dec 2016 00:13:34 +0200 Subject: [PATCH] Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. --- Doc/c-api/unicode.rst | 3 +-- Include/unicodeobject.h | 2 +- Misc/NEWS | 2 ++ Objects/unicodeobject.c | 18 ++++++++++++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index acdef7d7ce..3c7b9cc463 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1652,8 +1652,7 @@ They all return *NULL* or ``-1`` if an exception occurs. ASCII-encoded strings, but the function interprets the input string as ISO-8859-1 if it contains non-ASCII characters. - This function returns ``-1`` upon failure, so one should call - :c:func:`PyErr_Occurred` to check for errors. + This function does not raise exceptions. .. c:function:: PyObject* PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 6b6acd7353..90f2b72c20 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -2023,7 +2023,7 @@ PyAPI_FUNC(int) _PyUnicode_EqualToASCIIId( equal, and greater than, respectively. It is best to pass only ASCII-encoded strings, but the function interprets the input string as ISO-8859-1 if it contains non-ASCII characters. - Raise an exception and return -1 on error. */ + This function does not raise exceptions. */ PyAPI_FUNC(int) PyUnicode_CompareWithASCIIString( PyObject *left, diff --git a/Misc/NEWS b/Misc/NEWS index 3b8ca5e68b..1575c9ab53 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -506,6 +506,8 @@ IDLE C API ----- +- Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. + - Issue #26754: PyUnicode_FSDecoder() accepted a filename argument encoded as an iterable of integers. Now only strings and bytes-like objects are accepted. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6212cc4c82..ab261cc953 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10793,10 +10793,24 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) Py_ssize_t i; int kind; Py_UCS4 chr; + const unsigned char *ustr = (const unsigned char *)str; assert(_PyUnicode_CHECK(uni)); - if (PyUnicode_READY(uni) == -1) - return -1; + if (!PyUnicode_IS_READY(uni)) { + const wchar_t *ws = _PyUnicode_WSTR(uni); + /* Compare Unicode string and source character set string */ + for (i = 0; (chr = ws[i]) && ustr[i]; i++) { + if (chr != ustr[i]) + return (chr < ustr[i]) ? -1 : 1; + } + /* This check keeps Python strings that end in '\0' from comparing equal + to C strings identical up to that point. */ + if (_PyUnicode_WSTR_LENGTH(uni) != i || chr) + return 1; /* uni is longer */ + if (ustr[i]) + return -1; /* str is longer */ + return 0; + } kind = PyUnicode_KIND(uni); if (kind == PyUnicode_1BYTE_KIND) { const void *data = PyUnicode_1BYTE_DATA(uni); -- 2.40.0