From: Serhiy Storchaka Date: Mon, 2 Mar 2020 07:54:43 +0000 (+0200) Subject: [3.8] bpo-38913: Fix segfault in Py_BuildValue("(sGH-O)", ...) if entered with except... X-Git-Tag: v3.8.3rc1~148 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a7b8a969eb3daacb1fcb029a8c5fecb5d09c964b;p=thirdparty%2FPython%2Fcpython.git [3.8] bpo-38913: Fix segfault in Py_BuildValue("(sGH-O)", ...) if entered with exception raised. (GH-18656). (GH-18732) (cherry picked from commit 28d0bcac8b7e6dbd28311f1283dabb6a4d649fcb) --- diff --git a/Misc/NEWS.d/next/C API/2020-02-25-20-10-34.bpo-38913.siF1lS.rst b/Misc/NEWS.d/next/C API/2020-02-25-20-10-34.bpo-38913.siF1lS.rst new file mode 100644 index 000000000000..0e4d1210315d --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-02-25-20-10-34.bpo-38913.siF1lS.rst @@ -0,0 +1,2 @@ +Fixed segfault in ``Py_BuildValue()`` called with a format containing "#" +and undefined PY_SSIZE_T_CLEAN whwn an exception is set. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b54071669cf9..a8f8e683b201 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5063,6 +5063,8 @@ test_write_unraisable_exc(PyObject *self, PyObject *args) } +static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, @@ -5122,6 +5124,7 @@ static PyMethodDef TestMethods[] = { #endif {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, + {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, {"get_args", get_args, METH_VARARGS}, {"get_kwargs", (PyCFunction)(void(*)(void))get_kwargs, METH_VARARGS|METH_KEYWORDS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, @@ -6332,3 +6335,42 @@ PyInit__testcapi(void) PyState_AddModule(m, &_testcapimodule); return m; } + + +/* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ + +#undef Py_BuildValue +PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); + +static PyObject * +test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *res; + const char str[] = "string"; + const Py_UNICODE unicode[] = L"unicode"; + PyErr_SetNone(PyExc_ZeroDivisionError); + + res = Py_BuildValue("(s#O)", str, 1, Py_None); + assert(res == NULL); + if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { + return NULL; + } + res = Py_BuildValue("(z#O)", str, 1, Py_None); + assert(res == NULL); + if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { + return NULL; + } + res = Py_BuildValue("(y#O)", str, 1, Py_None); + assert(res == NULL); + if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { + return NULL; + } + res = Py_BuildValue("(u#O)", unicode, 1, Py_None); + assert(res == NULL); + if (!PyErr_ExceptionMatches(PyExc_ZeroDivisionError)) { + return NULL; + } + + PyErr_Clear(); + Py_RETURN_NONE; +} diff --git a/Python/modsupport.c b/Python/modsupport.c index 625582210774..7271af3ac533 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -343,11 +343,11 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) if (flags & FLAG_SIZE_T) n = va_arg(*p_va, Py_ssize_t); else { + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } - n = va_arg(*p_va, int); } } else @@ -396,11 +396,11 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) if (flags & FLAG_SIZE_T) n = va_arg(*p_va, Py_ssize_t); else { + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } - n = va_arg(*p_va, int); } } else @@ -434,11 +434,11 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) if (flags & FLAG_SIZE_T) n = va_arg(*p_va, Py_ssize_t); else { + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } - n = va_arg(*p_va, int); } } else