bpo-38913: Fix segfault in Py_BuildValue("(s#O)", ...) if entered with exception raised. (GH-18656)
This commit is contained in:
parent
2565edec2c
commit
28d0bcac8b
|
@ -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.
|
|
@ -5258,6 +5258,9 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args,
|
|||
return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
|
||||
|
||||
static PyMethodDef TestMethods[] = {
|
||||
{"raise_exception", raise_exception, METH_VARARGS},
|
||||
{"raise_memoryerror", raise_memoryerror, METH_NOARGS},
|
||||
|
@ -5322,6 +5325,7 @@ static PyMethodDef TestMethods[] = {
|
|||
{"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
|
||||
{"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS},
|
||||
{"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},
|
||||
|
@ -6791,3 +6795,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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue