From 6ec34a2e1e9f7a3749245ac37859a5fbf72952ed Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 4 May 2021 05:29:56 -0700 Subject: [PATCH 1/2] Add C-API tests (GH-25886) (#25887) (cherry picked from commit 2f5baa17504feb9a7613bac32fdceed4894434de) Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> --- .../2021-05-04-18-10-57.bpo-42083.EMS2TK.rst | 2 ++ Modules/_testcapimodule.c | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst diff --git a/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst b/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst new file mode 100644 index 00000000000000..8457508237a888 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst @@ -0,0 +1,2 @@ +Add test to check that ``PyStructSequence_NewType`` accepts a +``PyStructSequence_Desc`` with ``doc`` field set to ``NULL``. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 54c1e62a282414..f4e04e77636cfb 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3731,6 +3731,25 @@ test_structseq_newtype_doesnt_leak(PyObject *Py_UNUSED(self), Py_RETURN_NONE; } +static PyObject * +test_structseq_newtype_null_descr_doc(PyObject *Py_UNUSED(self), + PyObject *Py_UNUSED(args)) +{ + PyStructSequence_Field descr_fields[1] = { + (PyStructSequence_Field){NULL, NULL} + }; + // Test specifically for NULL .doc field. + PyStructSequence_Desc descr = {"_testcapi.test_descr", NULL, &descr_fields[0], 0}; + + PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); + assert(structseq_type != NULL); + assert(PyType_Check(structseq_type)); + assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); + Py_DECREF(structseq_type); + + Py_RETURN_NONE; +} + static PyObject * test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) { @@ -5335,6 +5354,8 @@ static PyMethodDef TestMethods[] = { {"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS}, {"test_structseq_newtype_doesnt_leak", test_structseq_newtype_doesnt_leak, METH_NOARGS}, + {"test_structseq_newtype_null_descr_doc", + test_structseq_newtype_null_descr_doc, METH_NOARGS}, {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, {"test_long_as_double", test_long_as_double, METH_NOARGS}, From bb2d3b3547d73b9cc2e009e707f6388688286a6f Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 4 May 2021 15:21:27 +0200 Subject: [PATCH 2/2] [3.9] bpo-42083: Allow NULL doc in PyStructSequence_NewType --- .../2021-05-04-15-13-31.bpo-42083.ekXnbR.rst | 2 ++ .../2021-05-04-18-10-57.bpo-42083.EMS2TK.rst | 2 -- Objects/structseq.c | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2021-05-04-15-13-31.bpo-42083.ekXnbR.rst delete mode 100644 Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst diff --git a/Misc/NEWS.d/next/C API/2021-05-04-15-13-31.bpo-42083.ekXnbR.rst b/Misc/NEWS.d/next/C API/2021-05-04-15-13-31.bpo-42083.ekXnbR.rst new file mode 100644 index 00000000000000..e83bab9c29599a --- /dev/null +++ b/Misc/NEWS.d/next/C API/2021-05-04-15-13-31.bpo-42083.ekXnbR.rst @@ -0,0 +1,2 @@ +Fix crash in :c:func:`PyStructSequence_NewType` when passed ``NULL`` in the +documentation string slot. diff --git a/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst b/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst deleted file mode 100644 index 8457508237a888..00000000000000 --- a/Misc/NEWS.d/next/Tests/2021-05-04-18-10-57.bpo-42083.EMS2TK.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add test to check that ``PyStructSequence_NewType`` accepts a -``PyStructSequence_Desc`` with ``doc`` field set to ``NULL``. diff --git a/Objects/structseq.c b/Objects/structseq.c index b17b1f99a5bc62..5a493c91e875a8 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -467,12 +467,17 @@ PyStructSequence_NewType(PyStructSequence_Desc *desc) /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; slots[1] = (PyType_Slot){Py_tp_repr, (reprfunc)structseq_repr}; - slots[2] = (PyType_Slot){Py_tp_doc, (void *)desc->doc}; - slots[3] = (PyType_Slot){Py_tp_methods, structseq_methods}; - slots[4] = (PyType_Slot){Py_tp_new, structseq_new}; - slots[5] = (PyType_Slot){Py_tp_members, members}; - slots[6] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; - slots[7] = (PyType_Slot){0, 0}; + slots[2] = (PyType_Slot){Py_tp_methods, structseq_methods}; + slots[3] = (PyType_Slot){Py_tp_new, structseq_new}; + slots[4] = (PyType_Slot){Py_tp_members, members}; + slots[5] = (PyType_Slot){Py_tp_traverse, (traverseproc)structseq_traverse}; + if (desc->doc) { + slots[6] = (PyType_Slot){Py_tp_doc, (void *)desc->doc}; + slots[7] = (PyType_Slot){0, 0}; + } + else { + slots[6] = (PyType_Slot){0, 0}; + } /* Initialize Spec */ /* The name in this PyType_Spec is statically allocated so it is */