From ba2b961d548e83e1ec4a661e07e2fcd8c7b258ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 16 Jun 2024 10:58:51 +0200 Subject: [PATCH 1/5] protect macros expansion in `_testbuffer.c` --- Modules/_testbuffer.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 54ee468803261a..580607190dc4d3 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -24,11 +24,13 @@ static PyTypeObject NDArray_Type; #define NDArray_Check(v) Py_IS_TYPE(v, &NDArray_Type) #define CHECK_LIST_OR_TUPLE(v) \ - if (!PyList_Check(v) && !PyTuple_Check(v)) { \ - PyErr_SetString(PyExc_TypeError, \ - #v " must be a list or a tuple"); \ - return NULL; \ - } \ + do { \ + if (!PyList_Check(v) && !PyTuple_Check(v)) { \ + PyErr_SetString(PyExc_TypeError, \ + #v " must be a list or a tuple"); \ + return NULL; \ + } \ + } while (0) #define PyMem_XFree(v) \ do { if (v) PyMem_Free(v); } while (0) @@ -1180,7 +1182,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides, Py_ssize_t itemsize; /* ndim = len(shape) */ - CHECK_LIST_OR_TUPLE(shape) + CHECK_LIST_OR_TUPLE(shape); ndim = PySequence_Fast_GET_SIZE(shape); if (ndim > ND_MAX_NDIM) { PyErr_Format(PyExc_ValueError, @@ -1190,7 +1192,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides, /* len(strides) = len(shape) */ if (strides) { - CHECK_LIST_OR_TUPLE(strides) + CHECK_LIST_OR_TUPLE(strides); if (PySequence_Fast_GET_SIZE(strides) == 0) strides = NULL; else if (flags & ND_FORTRAN) { @@ -1222,7 +1224,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides, return NULL; } else { - CHECK_LIST_OR_TUPLE(items) + CHECK_LIST_OR_TUPLE(items); Py_INCREF(items); } From 52ce758539a90da3332db41f923fd507f2619bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sun, 16 Jun 2024 10:59:01 +0200 Subject: [PATCH 2/5] protect macros expansion in `_testcapimodule.c` --- Modules/_testcapimodule.c | 127 ++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 52 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b139b46c826a3f..af908f9ca119c7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -81,8 +81,11 @@ static PyObject* test_config(PyObject *self, PyObject *Py_UNUSED(ignored)) { #define CHECK_SIZEOF(FATNAME, TYPE) \ - if (FATNAME != sizeof(TYPE)) \ - return sizeof_error(self, #FATNAME, #TYPE, FATNAME, sizeof(TYPE)) + do { \ + if (FATNAME != sizeof(TYPE)) { \ + return sizeof_error(self, #FATNAME, #TYPE, FATNAME, sizeof(TYPE)); \ + } \ + } while (0) CHECK_SIZEOF(SIZEOF_SHORT, short); CHECK_SIZEOF(SIZEOF_INT, int); @@ -103,21 +106,25 @@ test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored)) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wtype-limits" #endif -#define CHECK_SIZEOF(TYPE, EXPECTED) \ - if (EXPECTED != sizeof(TYPE)) { \ - PyErr_Format(get_testerror(self), \ - "sizeof(%s) = %u instead of %u", \ - #TYPE, sizeof(TYPE), EXPECTED); \ - return (PyObject*)NULL; \ - } +#define CHECK_SIZEOF(TYPE, EXPECTED) \ + do { \ + if (EXPECTED != sizeof(TYPE)) { \ + PyErr_Format(get_testerror(self), \ + "sizeof(%s) = %u instead of %u", \ + #TYPE, sizeof(TYPE), EXPECTED); \ + return (PyObject*)NULL; \ + } \ + } while (0) #define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0) -#define CHECK_SIGNNESS(TYPE, SIGNED) \ - if (IS_SIGNED(TYPE) != SIGNED) { \ - PyErr_Format(get_testerror(self), \ - "%s signness is %i, instead of %i", \ - #TYPE, IS_SIGNED(TYPE), SIGNED); \ - return (PyObject*)NULL; \ - } +#define CHECK_SIGNNESS(TYPE, SIGNED) \ + do { \ + if (IS_SIGNED(TYPE) != SIGNED) { \ + PyErr_Format(get_testerror(self), \ + "%s signness is %i, instead of %i", \ + #TYPE, IS_SIGNED(TYPE), SIGNED); \ + return (PyObject*)NULL; \ + } \ + } while (0) /* integer types */ CHECK_SIZEOF(Py_UCS1, 1); @@ -884,27 +891,34 @@ test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { double result; const char *msg; -#define CHECK_STRING(STR, expected) \ - result = PyOS_string_to_double(STR, NULL, NULL); \ - if (result == -1.0 && PyErr_Occurred()) \ - return NULL; \ - if (result != (double)expected) { \ - msg = "conversion of " STR " to float failed"; \ - goto fail; \ - } +#define CHECK_STRING(STR, expected) \ + do { \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) { \ + return NULL; \ + } \ + if (result != (double)expected) { \ + msg = "conversion of " STR " to float failed"; \ + goto fail; \ + } \ + } while (0) -#define CHECK_INVALID(STR) \ - result = PyOS_string_to_double(STR, NULL, NULL); \ - if (result == -1.0 && PyErr_Occurred()) { \ - if (PyErr_ExceptionMatches(PyExc_ValueError)) \ - PyErr_Clear(); \ - else \ - return NULL; \ - } \ - else { \ - msg = "conversion of " STR " didn't raise ValueError"; \ - goto fail; \ - } +#define CHECK_INVALID(STR) \ + do { \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) { \ + if (PyErr_ExceptionMatches(PyExc_ValueError)) { \ + PyErr_Clear(); \ + } \ + else { \ + return NULL; \ + } \ + } \ + else { \ + msg = "conversion of " STR " didn't raise ValueError"; \ + goto fail; \ + } \ + } while (0) CHECK_STRING("0.1", 0.1); CHECK_STRING("1.234", 1.234); @@ -971,16 +985,22 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) }; known_capsule *known = &known_capsules[0]; -#define FAIL(x) { error = (x); goto exit; } +#define FAIL(x) \ + do { \ + error = (x); \ + goto exit; \ + } while (0) #define CHECK_DESTRUCTOR \ - if (capsule_error) { \ - FAIL(capsule_error); \ - } \ - else if (!capsule_destructor_call_count) { \ - FAIL("destructor not called!"); \ - } \ - capsule_destructor_call_count = 0; \ + do { \ + if (capsule_error) { \ + FAIL(capsule_error); \ + } \ + else if (!capsule_destructor_call_count) { \ + FAIL("destructor not called!"); \ + } \ + capsule_destructor_call_count = 0; \ + } while (0) object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor); PyCapsule_SetContext(object, capsule_context); @@ -1024,12 +1044,12 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) static char buffer[256]; #undef FAIL #define FAIL(x) \ - { \ + do { \ sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ - x, known->module, known->attribute); \ + x, known->module, known->attribute); \ error = buffer; \ goto exit; \ - } \ + } while (0) PyObject *module = PyImport_ImportModule(known->module); if (module) { @@ -1069,7 +1089,7 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) PyErr_Clear(); } - exit: +exit: if (error) { return raiseTestError(self, "test_capsule", error); } @@ -1955,8 +1975,7 @@ py_w_stopcode(PyObject *self, PyObject *args) static PyObject * -test_pythread_tss_key_state(PyObject *self, PyObject *args) -{ +test_pythread_tss_key_state(PyObject *self, PyObject *args) { Py_tss_t tss_key = Py_tss_NEEDS_INIT; if (PyThread_tss_is_created(&tss_key)) { return raiseTestError(self, "test_pythread_tss_key_state", @@ -1978,11 +1997,15 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args) "an already initialized key"); } #define CHECK_TSS_API(expr) \ + do { \ (void)(expr); \ if (!PyThread_tss_is_created(&tss_key)) { \ return raiseTestError(self, "test_pythread_tss_key_state", \ "TSS key initialization state was not " \ - "preserved after calling " #expr); } + "preserved after calling " #expr); \ + } \ + } while (0) + CHECK_TSS_API(PyThread_tss_set(&tss_key, NULL)); CHECK_TSS_API(PyThread_tss_get(&tss_key)); #undef CHECK_TSS_API @@ -2304,7 +2327,7 @@ test_py_setref(PyObject *self, PyObject *Py_UNUSED(ignored)) \ Py_DECREF(obj); \ Py_RETURN_NONE; \ - } while (0) \ + } while (0) // Test Py_NewRef() and Py_XNewRef() macros From 35711e20825e265789b3a31c7b7c5cc4bad0dd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:19:58 +0200 Subject: [PATCH 3/5] revert non-intended changes --- Modules/_testcapimodule.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index af908f9ca119c7..24b0347368410b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1089,7 +1089,7 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) PyErr_Clear(); } -exit: + exit: if (error) { return raiseTestError(self, "test_capsule", error); } @@ -1975,7 +1975,8 @@ py_w_stopcode(PyObject *self, PyObject *args) static PyObject * -test_pythread_tss_key_state(PyObject *self, PyObject *args) { +test_pythread_tss_key_state(PyObject *self, PyObject *args) +{ Py_tss_t tss_key = Py_tss_NEEDS_INIT; if (PyThread_tss_is_created(&tss_key)) { return raiseTestError(self, "test_pythread_tss_key_state", From 35d8d9b906e1d50ab6689bbd1e1ad12f0c8a4dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:20:44 +0200 Subject: [PATCH 4/5] keep nested indentation --- Modules/_testcapimodule.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 24b0347368410b..708f2de6c5b9dd 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1044,12 +1044,12 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) static char buffer[256]; #undef FAIL #define FAIL(x) \ - do { \ - sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ - x, known->module, known->attribute); \ - error = buffer; \ - goto exit; \ - } while (0) + do { \ + sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ + x, known->module, known->attribute); \ + error = buffer; \ + goto exit; \ + } while (0) PyObject *module = PyImport_ImportModule(known->module); if (module) { From 27e23cadd8be0321965eef95ba240f90e33f2010 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 18 Jun 2024 13:41:15 +0200 Subject: [PATCH 5/5] Update Modules/_testbuffer.c --- Modules/_testbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 580607190dc4d3..b47bc8a830cb5e 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -26,7 +26,7 @@ static PyTypeObject NDArray_Type; #define CHECK_LIST_OR_TUPLE(v) \ do { \ if (!PyList_Check(v) && !PyTuple_Check(v)) { \ - PyErr_SetString(PyExc_TypeError, \ + PyErr_SetString(PyExc_TypeError, \ #v " must be a list or a tuple"); \ return NULL; \ } \