Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (révision 88500) +++ Objects/unicodeobject.c (copie de travail) @@ -1460,9 +1460,12 @@ PyObject *buffer = NULL, *unicode; Py_buffer info; char lower[11]; /* Enough for any encoding shortcut */ + static const char *empty = ""; if (encoding == NULL) encoding = PyUnicode_GetDefaultEncoding(); + if (s == NULL) + s = empty; /* Shortcuts for common default encodings */ if (normalize_encoding(encoding, lower, sizeof(lower))) { Index: Objects/memoryobject.c =================================================================== --- Objects/memoryobject.c (révision 88500) +++ Objects/memoryobject.c (copie de travail) @@ -75,6 +75,11 @@ { PyMemoryViewObject *mview; + if (info->buf == NULL) { + PyErr_SetString(PyExc_ValueError, + "cannot make memory view from a buffer with a NULL data pointer"); + return NULL; + } mview = (PyMemoryViewObject *) PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type); if (mview == NULL) Index: Lib/test/test_capi.py =================================================================== --- Lib/test/test_capi.py (révision 88500) +++ Lib/test/test_capi.py (copie de travail) @@ -50,7 +50,18 @@ b'Fatal Python error:' b' PyThreadState_Get: no current thread') + def test_memoryview_from_NULL_pointer(self): + self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) + def test_pyunicode_decode_NULL_length_0(self): + f = _testcapi.pyunicode_decode_NULL_length_0 + self.assertEqual(f('ascii'), '') + self.assertEqual(f('utf8'), '') + self.assertEqual(f('utf-8'), '') + self.assertEqual(f('latin1'), '') + self.assertEqual(f('latin1', 'replace'), '') + self.assertEqual(f('latin-1'), '') + @unittest.skipUnless(threading, 'Threading required for this test.') class TestPendingCalls(unittest.TestCase): Index: Modules/_testcapimodule.c =================================================================== --- Modules/_testcapimodule.c (révision 88500) +++ Modules/_testcapimodule.c (copie de travail) @@ -2231,6 +2231,15 @@ return PyErr_NewExceptionWithDoc(name, doc, base, dict); } +static PyObject * +make_memoryview_from_NULL_pointer(PyObject *self) +{ + Py_buffer info; + if (PyBuffer_FillInfo(&info, NULL, NULL, 1, 1, PyBUF_FULL_RO) < 0) + return NULL; + return PyMemoryView_FromBuffer(&info); +} + /* Test that the fatal error from not having a current thread doesn't cause an infinite loop. Run via Lib/test/test_capi.py */ static PyObject * @@ -2246,6 +2255,22 @@ return NULL; } +static PyObject * +pyunicode_decode_NULL_length_0(PyObject *self, PyObject *args, PyObject *kwargs) +{ + const char *encoding; + const char *errors = "strict"; + + static char *kwlist[] = {"encoding", "errors", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|ss:pyunicode_decode_NULL_length_0", kwlist, + &encoding, &errors)) + return NULL; + return PyUnicode_Decode(NULL, 0, encoding, errors); +} + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, @@ -2326,7 +2351,11 @@ {"code_newempty", code_newempty, METH_VARARGS}, {"make_exception_with_doc", (PyCFunction)make_exception_with_doc, METH_VARARGS | METH_KEYWORDS}, + {"make_memoryview_from_NULL_pointer", (PyCFunction)make_memoryview_from_NULL_pointer, + METH_NOARGS}, {"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS}, + {"pyunicode_decode_NULL_length_0", (PyCFunction)pyunicode_decode_NULL_length_0, + METH_VARARGS | METH_KEYWORDS}, {NULL, NULL} /* sentinel */ };