mirror of https://github.com/python/cpython
gh-120674: Protect multi-line macros in _testbuffer.c and _testcapimodule.c (#120675)
Add do { ... } while (0) pattern.
This commit is contained in:
parent
4bc27abdbe
commit
7c5da94b5d
|
@ -24,11 +24,13 @@ static PyTypeObject NDArray_Type;
|
||||||
#define NDArray_Check(v) Py_IS_TYPE(v, &NDArray_Type)
|
#define NDArray_Check(v) Py_IS_TYPE(v, &NDArray_Type)
|
||||||
|
|
||||||
#define CHECK_LIST_OR_TUPLE(v) \
|
#define CHECK_LIST_OR_TUPLE(v) \
|
||||||
if (!PyList_Check(v) && !PyTuple_Check(v)) { \
|
do { \
|
||||||
PyErr_SetString(PyExc_TypeError, \
|
if (!PyList_Check(v) && !PyTuple_Check(v)) { \
|
||||||
#v " must be a list or a tuple"); \
|
PyErr_SetString(PyExc_TypeError, \
|
||||||
return NULL; \
|
#v " must be a list or a tuple"); \
|
||||||
} \
|
return NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define PyMem_XFree(v) \
|
#define PyMem_XFree(v) \
|
||||||
do { if (v) PyMem_Free(v); } while (0)
|
do { if (v) PyMem_Free(v); } while (0)
|
||||||
|
@ -1180,7 +1182,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides,
|
||||||
Py_ssize_t itemsize;
|
Py_ssize_t itemsize;
|
||||||
|
|
||||||
/* ndim = len(shape) */
|
/* ndim = len(shape) */
|
||||||
CHECK_LIST_OR_TUPLE(shape)
|
CHECK_LIST_OR_TUPLE(shape);
|
||||||
ndim = PySequence_Fast_GET_SIZE(shape);
|
ndim = PySequence_Fast_GET_SIZE(shape);
|
||||||
if (ndim > ND_MAX_NDIM) {
|
if (ndim > ND_MAX_NDIM) {
|
||||||
PyErr_Format(PyExc_ValueError,
|
PyErr_Format(PyExc_ValueError,
|
||||||
|
@ -1190,7 +1192,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides,
|
||||||
|
|
||||||
/* len(strides) = len(shape) */
|
/* len(strides) = len(shape) */
|
||||||
if (strides) {
|
if (strides) {
|
||||||
CHECK_LIST_OR_TUPLE(strides)
|
CHECK_LIST_OR_TUPLE(strides);
|
||||||
if (PySequence_Fast_GET_SIZE(strides) == 0)
|
if (PySequence_Fast_GET_SIZE(strides) == 0)
|
||||||
strides = NULL;
|
strides = NULL;
|
||||||
else if (flags & ND_FORTRAN) {
|
else if (flags & ND_FORTRAN) {
|
||||||
|
@ -1222,7 +1224,7 @@ init_ndbuf(PyObject *items, PyObject *shape, PyObject *strides,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CHECK_LIST_OR_TUPLE(items)
|
CHECK_LIST_OR_TUPLE(items);
|
||||||
Py_INCREF(items);
|
Py_INCREF(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,8 +81,11 @@ static PyObject*
|
||||||
test_config(PyObject *self, PyObject *Py_UNUSED(ignored))
|
test_config(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
#define CHECK_SIZEOF(FATNAME, TYPE) \
|
#define CHECK_SIZEOF(FATNAME, TYPE) \
|
||||||
if (FATNAME != sizeof(TYPE)) \
|
do { \
|
||||||
return sizeof_error(self, #FATNAME, #TYPE, FATNAME, sizeof(TYPE))
|
if (FATNAME != sizeof(TYPE)) { \
|
||||||
|
return sizeof_error(self, #FATNAME, #TYPE, FATNAME, sizeof(TYPE)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
CHECK_SIZEOF(SIZEOF_SHORT, short);
|
CHECK_SIZEOF(SIZEOF_SHORT, short);
|
||||||
CHECK_SIZEOF(SIZEOF_INT, int);
|
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 push
|
||||||
#pragma GCC diagnostic ignored "-Wtype-limits"
|
#pragma GCC diagnostic ignored "-Wtype-limits"
|
||||||
#endif
|
#endif
|
||||||
#define CHECK_SIZEOF(TYPE, EXPECTED) \
|
#define CHECK_SIZEOF(TYPE, EXPECTED) \
|
||||||
if (EXPECTED != sizeof(TYPE)) { \
|
do { \
|
||||||
PyErr_Format(get_testerror(self), \
|
if (EXPECTED != sizeof(TYPE)) { \
|
||||||
"sizeof(%s) = %u instead of %u", \
|
PyErr_Format(get_testerror(self), \
|
||||||
#TYPE, sizeof(TYPE), EXPECTED); \
|
"sizeof(%s) = %u instead of %u", \
|
||||||
return (PyObject*)NULL; \
|
#TYPE, sizeof(TYPE), EXPECTED); \
|
||||||
}
|
return (PyObject*)NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
#define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0)
|
#define IS_SIGNED(TYPE) (((TYPE)-1) < (TYPE)0)
|
||||||
#define CHECK_SIGNNESS(TYPE, SIGNED) \
|
#define CHECK_SIGNNESS(TYPE, SIGNED) \
|
||||||
if (IS_SIGNED(TYPE) != SIGNED) { \
|
do { \
|
||||||
PyErr_Format(get_testerror(self), \
|
if (IS_SIGNED(TYPE) != SIGNED) { \
|
||||||
"%s signness is %i, instead of %i", \
|
PyErr_Format(get_testerror(self), \
|
||||||
#TYPE, IS_SIGNED(TYPE), SIGNED); \
|
"%s signness is %i, instead of %i", \
|
||||||
return (PyObject*)NULL; \
|
#TYPE, IS_SIGNED(TYPE), SIGNED); \
|
||||||
}
|
return (PyObject*)NULL; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* integer types */
|
/* integer types */
|
||||||
CHECK_SIZEOF(Py_UCS1, 1);
|
CHECK_SIZEOF(Py_UCS1, 1);
|
||||||
|
@ -884,27 +891,34 @@ test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) {
|
||||||
double result;
|
double result;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
|
||||||
#define CHECK_STRING(STR, expected) \
|
#define CHECK_STRING(STR, expected) \
|
||||||
result = PyOS_string_to_double(STR, NULL, NULL); \
|
do { \
|
||||||
if (result == -1.0 && PyErr_Occurred()) \
|
result = PyOS_string_to_double(STR, NULL, NULL); \
|
||||||
return NULL; \
|
if (result == -1.0 && PyErr_Occurred()) { \
|
||||||
if (result != (double)expected) { \
|
return NULL; \
|
||||||
msg = "conversion of " STR " to float failed"; \
|
} \
|
||||||
goto fail; \
|
if (result != (double)expected) { \
|
||||||
}
|
msg = "conversion of " STR " to float failed"; \
|
||||||
|
goto fail; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define CHECK_INVALID(STR) \
|
#define CHECK_INVALID(STR) \
|
||||||
result = PyOS_string_to_double(STR, NULL, NULL); \
|
do { \
|
||||||
if (result == -1.0 && PyErr_Occurred()) { \
|
result = PyOS_string_to_double(STR, NULL, NULL); \
|
||||||
if (PyErr_ExceptionMatches(PyExc_ValueError)) \
|
if (result == -1.0 && PyErr_Occurred()) { \
|
||||||
PyErr_Clear(); \
|
if (PyErr_ExceptionMatches(PyExc_ValueError)) { \
|
||||||
else \
|
PyErr_Clear(); \
|
||||||
return NULL; \
|
} \
|
||||||
} \
|
else { \
|
||||||
else { \
|
return NULL; \
|
||||||
msg = "conversion of " STR " didn't raise ValueError"; \
|
} \
|
||||||
goto fail; \
|
} \
|
||||||
}
|
else { \
|
||||||
|
msg = "conversion of " STR " didn't raise ValueError"; \
|
||||||
|
goto fail; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
CHECK_STRING("0.1", 0.1);
|
CHECK_STRING("0.1", 0.1);
|
||||||
CHECK_STRING("1.234", 1.234);
|
CHECK_STRING("1.234", 1.234);
|
||||||
|
@ -971,16 +985,22 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
};
|
};
|
||||||
known_capsule *known = &known_capsules[0];
|
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 \
|
#define CHECK_DESTRUCTOR \
|
||||||
if (capsule_error) { \
|
do { \
|
||||||
FAIL(capsule_error); \
|
if (capsule_error) { \
|
||||||
} \
|
FAIL(capsule_error); \
|
||||||
else if (!capsule_destructor_call_count) { \
|
} \
|
||||||
FAIL("destructor not called!"); \
|
else if (!capsule_destructor_call_count) { \
|
||||||
} \
|
FAIL("destructor not called!"); \
|
||||||
capsule_destructor_call_count = 0; \
|
} \
|
||||||
|
capsule_destructor_call_count = 0; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor);
|
object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor);
|
||||||
PyCapsule_SetContext(object, capsule_context);
|
PyCapsule_SetContext(object, capsule_context);
|
||||||
|
@ -1024,12 +1044,12 @@ test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
static char buffer[256];
|
static char buffer[256];
|
||||||
#undef FAIL
|
#undef FAIL
|
||||||
#define FAIL(x) \
|
#define FAIL(x) \
|
||||||
{ \
|
do { \
|
||||||
sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \
|
sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \
|
||||||
x, known->module, known->attribute); \
|
x, known->module, known->attribute); \
|
||||||
error = buffer; \
|
error = buffer; \
|
||||||
goto exit; \
|
goto exit; \
|
||||||
} \
|
} while (0)
|
||||||
|
|
||||||
PyObject *module = PyImport_ImportModule(known->module);
|
PyObject *module = PyImport_ImportModule(known->module);
|
||||||
if (module) {
|
if (module) {
|
||||||
|
@ -1978,11 +1998,15 @@ test_pythread_tss_key_state(PyObject *self, PyObject *args)
|
||||||
"an already initialized key");
|
"an already initialized key");
|
||||||
}
|
}
|
||||||
#define CHECK_TSS_API(expr) \
|
#define CHECK_TSS_API(expr) \
|
||||||
|
do { \
|
||||||
(void)(expr); \
|
(void)(expr); \
|
||||||
if (!PyThread_tss_is_created(&tss_key)) { \
|
if (!PyThread_tss_is_created(&tss_key)) { \
|
||||||
return raiseTestError(self, "test_pythread_tss_key_state", \
|
return raiseTestError(self, "test_pythread_tss_key_state", \
|
||||||
"TSS key initialization state was not " \
|
"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_set(&tss_key, NULL));
|
||||||
CHECK_TSS_API(PyThread_tss_get(&tss_key));
|
CHECK_TSS_API(PyThread_tss_get(&tss_key));
|
||||||
#undef CHECK_TSS_API
|
#undef CHECK_TSS_API
|
||||||
|
@ -2304,7 +2328,7 @@ test_py_setref(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
\
|
\
|
||||||
Py_DECREF(obj); \
|
Py_DECREF(obj); \
|
||||||
Py_RETURN_NONE; \
|
Py_RETURN_NONE; \
|
||||||
} while (0) \
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
// Test Py_NewRef() and Py_XNewRef() macros
|
// Test Py_NewRef() and Py_XNewRef() macros
|
||||||
|
|
Loading…
Reference in New Issue