]> granicus.if.org Git - python/commitdiff
Issue #28808: PyUnicode_CompareWithASCIIString() now never raises exceptions.
authorSerhiy Storchaka <storchaka@gmail.com>
Mon, 5 Dec 2016 22:13:34 +0000 (00:13 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Mon, 5 Dec 2016 22:13:34 +0000 (00:13 +0200)
Doc/c-api/unicode.rst
Include/unicodeobject.h
Misc/NEWS
Objects/unicodeobject.c

index acdef7d7ce612c3f431aabfff539f04fbaf362ab..3c7b9cc46373eca71e8c699a71f0b840792a97d8 100644 (file)
@@ -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)
index 6b6acd735311c0a2510b308f59814e93f157cd92..90f2b72c2062719429b40b57dfdad65cb3e774dc 100644 (file)
@@ -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,
index 3b8ca5e68b813a56c0ecf7739c9105732790edf5..1575c9ab53d94b67d9787a360dc01833db7b2cee 100644 (file)
--- 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.
 
index 6212cc4c822d3487cd553f5f3aceaeef02d842fb..ab261cc953f30bcc4232c23df1bc84ead300e168 100644 (file)
@@ -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);