Author: Ronan Lamy <[email protected]>
Branch: py3.5
Changeset: r93108:ecfbd8f62994
Date: 2017-11-21 05:32 +0000
http://bitbucket.org/pypy/pypy/changeset/ecfbd8f62994/

Log:    Do not use PyUnicode_Check in PyUnicode_AS_UNICODE, ever

        This macro may be used to fill in an uninitialised, unrealised
        unicode object, but PyUnicode_Check realises it, and modifying a
        PyPy-linked PyUnicodeObject is a no-no...

diff --git a/pypy/module/cpyext/include/unicodeobject.h 
b/pypy/module/cpyext/include/unicodeobject.h
--- a/pypy/module/cpyext/include/unicodeobject.h
+++ b/pypy/module/cpyext/include/unicodeobject.h
@@ -61,8 +61,7 @@
    use PyUnicode_WRITE() and PyUnicode_READ(). */
 
 #define PyUnicode_AS_UNICODE(op) \
-    (assert(PyUnicode_Check(op)), \
-     (((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \
+     ((((PyASCIIObject *)(op))->wstr) ? (((PyASCIIObject *)(op))->wstr) : \
       PyUnicode_AsUnicode((PyObject *)(op)))
 
 #define PyUnicode_AS_DATA(op) \
diff --git a/pypy/module/cpyext/test/_widechar.c 
b/pypy/module/cpyext/test/_widechar.c
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/_widechar.c
@@ -0,0 +1,47 @@
+// Enable asserts. This used to fail in that case only.
+#undef NDEBUG
+
+#include "Python.h"
+
+static PyObject *
+test_widechar(PyObject *self)
+{
+    const wchar_t invalid[1] = {(wchar_t)0x110000u};
+    PyObject *wide;
+
+    wide = PyUnicode_FromUnicode(NULL, 1);
+    if (wide == NULL)
+        return NULL;
+    PyUnicode_AS_UNICODE(wide)[0] = invalid[0];
+    if (_PyUnicode_Ready(wide) < 0) {
+        return NULL;
+    }
+    return wide;
+}
+
+static PyMethodDef TestMethods[] = {
+    {"test_widechar",           (PyCFunction)test_widechar,      METH_NOARGS},
+    {NULL, NULL} /* sentinel */
+};
+
+static struct PyModuleDef _testcapimodule = {
+    PyModuleDef_HEAD_INIT,
+    "_widechar",
+    NULL,
+    -1,
+    TestMethods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+PyMODINIT_FUNC
+PyInit__widechar(void)
+{
+    PyObject *m;
+    m = PyModule_Create(&_testcapimodule);
+    if (m == NULL)
+        return NULL;
+    return m;
+}
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py 
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -356,6 +356,10 @@
         print(repr(wide), repr(utf8))
         assert wide == utf8
 
+    def test_invalid(self):
+        m = self.import_module('_widechar')
+        raises(ValueError, m.test_widechar)
+
 
 class TestUnicode(BaseApiTest):
     def test_unicodeobject(self, space):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to