From 8fe006fc40e29a67e0ec9d2986612544185576e2 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, 8 Sep 2024 17:01:24 +0200 Subject: [PATCH 01/26] protect `RETURN_WITH_ERROR` macros expansion via `do { ... } while (0)` constructions This affects `Python/{assemble,flowgraph,instruction_sequence}.c`. --- Python/assemble.c | 8 +++++--- Python/flowgraph.c | 8 +++++--- Python/instruction_sequence.c | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Python/assemble.c b/Python/assemble.c index f7b88b519f5f71..ab5cb3968b1e6a 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -19,9 +19,11 @@ #define ERROR -1 #define RETURN_IF_ERROR(X) \ - if ((X) < 0) { \ - return ERROR; \ - } + do { \ + if ((X) < 0) { \ + return ERROR; \ + } \ + } while (0) \ typedef _Py_SourceLocation location; typedef _PyInstruction instruction; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index ec91b0e616c0a6..6740368b9caee6 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -16,9 +16,11 @@ #define ERROR -1 #define RETURN_IF_ERROR(X) \ - if ((X) == -1) { \ - return ERROR; \ - } + do { \ + if ((X) == -1) { \ + return ERROR; \ + } \ + } while (0) \ #define DEFAULT_BLOCK_SIZE 16 diff --git a/Python/instruction_sequence.c b/Python/instruction_sequence.c index a3f85f754d71bb..fe511ed53a0674 100644 --- a/Python/instruction_sequence.c +++ b/Python/instruction_sequence.c @@ -28,9 +28,11 @@ typedef _Py_SourceLocation location; #define ERROR -1 #define RETURN_IF_ERROR(X) \ - if ((X) == -1) { \ - return ERROR; \ - } + do { \ + if ((X) == -1) { \ + return ERROR; \ + } \ + } while (0) \ static int instr_sequence_next_inst(instr_sequence *seq) { From 6629a4973155c64dd7ddc804010b7b56c0e946fb 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, 8 Sep 2024 17:26:10 +0200 Subject: [PATCH 02/26] protect `COPY_{NOT_FLAG,FLAG}` macros expansion via `do { ... } while (0)` constructions This affects `Python/initconfig.c` and `Python/preconfig.c`. --- Python/initconfig.c | 40 ++++++++++++++++++++++++---------------- Python/preconfig.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/Python/initconfig.c b/Python/initconfig.c index d93244f7f41084..777bcbb5d154f0 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -1564,14 +1564,18 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS return; } -#define COPY_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = VALUE; \ - } -#define COPY_NOT_FLAG(ATTR, VALUE) \ - if (config->ATTR == -1) { \ - config->ATTR = !(VALUE); \ - } +#define COPY_FLAG(ATTR, VALUE) \ + do { \ + if (config->ATTR == -1) { \ + config->ATTR = VALUE; \ + } \ + } while (0) +#define COPY_NOT_FLAG(ATTR, VALUE) \ + do { \ + if (config->ATTR == -1) { \ + config->ATTR = !(VALUE); \ + } \ + } while (0) COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); @@ -1604,14 +1608,18 @@ config_set_global_vars(const PyConfig *config) { _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS -#define COPY_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = config->ATTR; \ - } -#define COPY_NOT_FLAG(ATTR, VAR) \ - if (config->ATTR != -1) { \ - VAR = !config->ATTR; \ - } +#define COPY_FLAG(ATTR, VAR) \ + do { \ + if (config->ATTR != -1) { \ + VAR = config->ATTR; \ + } \ + } while (0) +#define COPY_NOT_FLAG(ATTR, VAR) \ + do { \ + if (config->ATTR != -1) { \ + VAR = !config->ATTR; \ + } \ + } while (0) COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); diff --git a/Python/preconfig.c b/Python/preconfig.c index 5b26c75de8b3a0..2a53918b56f211 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -470,14 +470,18 @@ preconfig_get_global_vars(PyPreConfig *config) return; } -#define COPY_FLAG(ATTR, VALUE) \ - if (config->ATTR < 0) { \ - config->ATTR = VALUE; \ - } -#define COPY_NOT_FLAG(ATTR, VALUE) \ - if (config->ATTR < 0) { \ - config->ATTR = !(VALUE); \ - } +#define COPY_FLAG(ATTR, VALUE) \ + do { \ + if (config->ATTR < 0) { \ + config->ATTR = VALUE; \ + } \ + } while (0) +#define COPY_NOT_FLAG(ATTR, VALUE) \ + do { \ + if (config->ATTR < 0) { \ + config->ATTR = !(VALUE); \ + } \ + } while (0) _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS @@ -499,14 +503,18 @@ _Py_COMP_DIAG_POP static void preconfig_set_global_vars(const PyPreConfig *config) { -#define COPY_FLAG(ATTR, VAR) \ - if (config->ATTR >= 0) { \ - VAR = config->ATTR; \ - } -#define COPY_NOT_FLAG(ATTR, VAR) \ - if (config->ATTR >= 0) { \ - VAR = !config->ATTR; \ - } +#define COPY_FLAG(ATTR, VAR) \ + do { \ + if (config->ATTR >= 0) { \ + VAR = config->ATTR; \ + } \ + } while (0) +#define COPY_NOT_FLAG(ATTR, VAR) \ + do { \ + if (config->ATTR >= 0) { \ + VAR = !config->ATTR; \ + } \ + } while (0) _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS From a4a469eb7efd8882f515c4758d051488e745b96b 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, 8 Sep 2024 17:05:33 +0200 Subject: [PATCH 03/26] `Python/ast_opt.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/ast_opt.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 5a51305d2a7ade..fc6152e7b7020c 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -654,23 +654,31 @@ static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimize static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); -#define CALL(FUNC, TYPE, ARG) \ - if (!FUNC((ARG), ctx_, state)) \ - return 0; - -#define CALL_OPT(FUNC, TYPE, ARG) \ - if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) \ - return 0; - -#define CALL_SEQ(FUNC, TYPE, ARG) { \ - Py_ssize_t i; \ - asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ - for (i = 0; i < asdl_seq_LEN(seq); i++) { \ - TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ - if (elt != NULL && !FUNC(elt, ctx_, state)) \ - return 0; \ - } \ -} +#define CALL(FUNC, TYPE, ARG) \ + do { \ + if (!FUNC((ARG), ctx_, state)) { \ + return 0; \ + } \ + } while (0) + +#define CALL_OPT(FUNC, TYPE, ARG) \ + do { \ + if ((ARG) != NULL && !FUNC((ARG), ctx_, state)) { \ + return 0; \ + } \ + } while (0) + +#define CALL_SEQ(FUNC, TYPE, ARG) \ + do { \ + Py_ssize_t i; \ + asdl_ ## TYPE ## _seq *seq = (ARG); /* avoid variable capture */ \ + for (i = 0; i < asdl_seq_LEN(seq); i++) { \ + TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, i); \ + if (elt != NULL && !FUNC(elt, ctx_, state)) { \ + return 0; \ + } \ + } \ + } while (0) static int From a10560af55a50467826e65b8ff9f38b75ff37e86 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, 8 Sep 2024 17:17:29 +0200 Subject: [PATCH 04/26] `Python/ceval_gil.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/ceval_gil.c | 93 +++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c index 6f4476d055b5ec..cd262afbdaff12 100644 --- a/Python/ceval_gil.c +++ b/Python/ceval_gil.c @@ -106,41 +106,64 @@ update_eval_breaker_for_thread(PyInterpreterState *interp, PyThreadState *tstate #include "condvar.h" -#define MUTEX_INIT(mut) \ - if (PyMUTEX_INIT(&(mut))) { \ - Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; -#define MUTEX_FINI(mut) \ - if (PyMUTEX_FINI(&(mut))) { \ - Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; -#define MUTEX_LOCK(mut) \ - if (PyMUTEX_LOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; -#define MUTEX_UNLOCK(mut) \ - if (PyMUTEX_UNLOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; - -#define COND_INIT(cond) \ - if (PyCOND_INIT(&(cond))) { \ - Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; -#define COND_FINI(cond) \ - if (PyCOND_FINI(&(cond))) { \ - Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; -#define COND_SIGNAL(cond) \ - if (PyCOND_SIGNAL(&(cond))) { \ - Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; -#define COND_WAIT(cond, mut) \ - if (PyCOND_WAIT(&(cond), &(mut))) { \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ - { \ - int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ - if (r < 0) \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ - if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ - timeout_result = 1; \ - else \ - timeout_result = 0; \ - } \ +#define MUTEX_INIT(MUT) \ + do { \ + if (PyMUTEX_INIT(&(MUT))) { \ + Py_FatalError("PyMUTEX_INIT(" #MUT ") failed"); \ + } \ + } while (0) +#define MUTEX_FINI(MUT) \ + do { \ + if (PyMUTEX_FINI(&(MUT))) { \ + Py_FatalError("PyMUTEX_FINI(" #MUT ") failed"); \ + } \ + } while (0) +#define MUTEX_LOCK(MUT) \ + do { \ + if (PyMUTEX_LOCK(&(MUT))) { \ + Py_FatalError("PyMUTEX_LOCK(" #MUT ") failed"); \ + } \ + } while (0) +#define MUTEX_UNLOCK(MUT) \ + do { \ + if (PyMUTEX_UNLOCK(&(MUT))) { \ + Py_FatalError("PyMUTEX_UNLOCK(" #MUT ") failed"); \ + } \ + } while (0) + +#define COND_INIT(COND) \ + do { \ + if (PyCOND_INIT(&(COND))) { \ + Py_FatalError("PyCOND_INIT(" #COND ") failed"); \ + } \ + } while (0) +#define COND_FINI(COND) \ + do { \ + if (PyCOND_FINI(&(COND))) { \ + Py_FatalError("PyCOND_FINI(" #COND ") failed"); \ + } \ + } while (0) +#define COND_SIGNAL(COND) \ + do { \ + if (PyCOND_SIGNAL(&(COND))) { \ + Py_FatalError("PyCOND_SIGNAL(" #COND ") failed"); \ + } \ + } while (0) +#define COND_WAIT(COND, MUT) \ + do { \ + if (PyCOND_WAIT(&(COND), &(MUT))) { \ + Py_FatalError("PyCOND_WAIT(" #COND ") failed"); \ + } \ + } while (0) +#define COND_TIMED_WAIT(COND, MUT, MICROSECONDS, TIMEOUT_RESULT) \ + do { \ + int r = PyCOND_TIMEDWAIT(&(COND), &(MUT), (MICROSECONDS)); \ + if (r < 0) { \ + Py_FatalError("PyCOND_WAIT(" #COND ") failed"); \ + } \ + /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ + TIMEOUT_RESULT = r ? 1 : 0; \ + } while (0) #define DEFAULT_INTERVAL 5000 From b47891059f148fb8d3e42f613d62c8719f017bef 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, 8 Sep 2024 17:20:03 +0200 Subject: [PATCH 05/26] `Python/pyhash.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/pyhash.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Python/pyhash.c b/Python/pyhash.c index 216f437dd9a2d4..369ffe92044049 100644 --- a/Python/pyhash.c +++ b/Python/pyhash.c @@ -352,19 +352,25 @@ static PyHash_FuncDef PyHash_Func = {fnv, "fnv", 8 * SIZEOF_PY_HASH_T, # define ROTATE(x, b) (uint64_t)( ((x) << (b)) | ( (x) >> (64 - (b))) ) #endif -#define HALF_ROUND(a,b,c,d,s,t) \ - a += b; c += d; \ - b = ROTATE(b, s) ^ a; \ - d = ROTATE(d, t) ^ c; \ - a = ROTATE(a, 32); - -#define SINGLE_ROUND(v0,v1,v2,v3) \ - HALF_ROUND(v0,v1,v2,v3,13,16); \ - HALF_ROUND(v2,v1,v0,v3,17,21); +#define HALF_ROUND(a,b,c,d,s,t) \ + do { \ + a += b; c += d; \ + b = ROTATE(b, s) ^ a; \ + d = ROTATE(d, t) ^ c; \ + a = ROTATE(a, 32); \ + } while (0) + +#define SINGLE_ROUND(v0,v1,v2,v3) \ + do { \ + HALF_ROUND(v0,v1,v2,v3,13,16); \ + HALF_ROUND(v2,v1,v0,v3,17,21); \ + } while (0) #define DOUBLE_ROUND(v0,v1,v2,v3) \ - SINGLE_ROUND(v0,v1,v2,v3); \ - SINGLE_ROUND(v0,v1,v2,v3); + do { \ + SINGLE_ROUND(v0,v1,v2,v3); \ + SINGLE_ROUND(v0,v1,v2,v3); \ + } while (0) static uint64_t From cd3873f4b63c59bf931a5f029004dbda39ec8b75 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, 8 Sep 2024 17:40:00 +0200 Subject: [PATCH 06/26] `Python/optimizer.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/optimizer.c | 110 ++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/Python/optimizer.c b/Python/optimizer.c index 9198e410627dd4..14b18c800a419d 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -443,8 +443,12 @@ BRANCH_TO_GUARD[4][2] = { #define CONFIDENCE_CUTOFF 333 #ifdef Py_DEBUG -#define DPRINTF(level, ...) \ - if (lltrace >= (level)) { printf(__VA_ARGS__); } +#define DPRINTF(level, ...) \ + do { \ + if (lltrace >= (level)) { \ + printf(__VA_ARGS__); \ + } \ + } while (0) #else #define DPRINTF(level, ...) #endif @@ -468,56 +472,70 @@ add_to_trace( } #ifdef Py_DEBUG -#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \ - assert(trace_length < max_length); \ - trace_length = add_to_trace(trace, trace_length, (OPCODE), (OPARG), (OPERAND), (TARGET)); \ - if (lltrace >= 2) { \ - printf("%4d ADD_TO_TRACE: ", trace_length); \ - _PyUOpPrint(&trace[trace_length-1]); \ - printf("\n"); \ - } +#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \ + do { \ + assert(trace_length < max_length); \ + trace_length = add_to_trace(trace, trace_length, \ + (OPCODE), (OPARG), \ + (OPERAND), (TARGET)); \ + if (lltrace >= 2) { \ + printf("%4d ADD_TO_TRACE: ", trace_length); \ + _PyUOpPrint(&trace[trace_length-1]); \ + printf("\n"); \ + } \ + } while (0) #else -#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \ - assert(trace_length < max_length); \ - trace_length = add_to_trace(trace, trace_length, (OPCODE), (OPARG), (OPERAND), (TARGET)); +#define ADD_TO_TRACE(OPCODE, OPARG, OPERAND, TARGET) \ + do { \ + assert(trace_length < max_length); \ + trace_length = add_to_trace(trace, trace_length, \ + (OPCODE), (OPARG), \ + (OPERAND), (TARGET)); \ + } while (0) #endif #define INSTR_IP(INSTR, CODE) \ ((uint32_t)((INSTR) - ((_Py_CODEUNIT *)(CODE)->co_code_adaptive))) // Reserve space for n uops -#define RESERVE_RAW(n, opname) \ - if (trace_length + (n) > max_length) { \ - DPRINTF(2, "No room for %s (need %d, got %d)\n", \ - (opname), (n), max_length - trace_length); \ - OPT_STAT_INC(trace_too_long); \ - goto done; \ - } +#define RESERVE_RAW(N, OPNAME) \ + do { \ + if (trace_length + (N) > max_length) { \ + DPRINTF(2, "No room for %s (need %d, got %d)\n", \ + (OPNAME), (N), max_length - trace_length); \ + OPT_STAT_INC(trace_too_long); \ + goto done; \ + } \ + } while (0) // Reserve space for N uops, plus 3 for _SET_IP, _CHECK_VALIDITY and _EXIT_TRACE #define RESERVE(needed) RESERVE_RAW((needed) + 3, _PyUOpName(opcode)) // Trace stack operations (used by _PUSH_FRAME, _RETURN_VALUE) -#define TRACE_STACK_PUSH() \ - if (trace_stack_depth >= TRACE_STACK_SIZE) { \ - DPRINTF(2, "Trace stack overflow\n"); \ - OPT_STAT_INC(trace_stack_overflow); \ - return 0; \ - } \ - assert(func == NULL || func->func_code == (PyObject *)code); \ - trace_stack[trace_stack_depth].func = func; \ - trace_stack[trace_stack_depth].code = code; \ - trace_stack[trace_stack_depth].instr = instr; \ - trace_stack_depth++; -#define TRACE_STACK_POP() \ - if (trace_stack_depth <= 0) { \ - Py_FatalError("Trace stack underflow\n"); \ - } \ - trace_stack_depth--; \ - func = trace_stack[trace_stack_depth].func; \ - code = trace_stack[trace_stack_depth].code; \ - assert(func == NULL || func->func_code == (PyObject *)code); \ - instr = trace_stack[trace_stack_depth].instr; +#define TRACE_STACK_PUSH() \ + do { \ + if (trace_stack_depth >= TRACE_STACK_SIZE) { \ + DPRINTF(2, "Trace stack overflow\n"); \ + OPT_STAT_INC(trace_stack_overflow); \ + return 0; \ + } \ + assert(func == NULL || func->func_code == (PyObject *)code); \ + trace_stack[trace_stack_depth].func = func; \ + trace_stack[trace_stack_depth].code = code; \ + trace_stack[trace_stack_depth].instr = instr; \ + trace_stack_depth++; \ + } while (0) +#define TRACE_STACK_POP() \ + do { \ + if (trace_stack_depth <= 0) { \ + Py_FatalError("Trace stack underflow\n"); \ + } \ + trace_stack_depth--; \ + func = trace_stack[trace_stack_depth].func; \ + code = trace_stack[trace_stack_depth].code; \ + assert(func == NULL || func->func_code == (PyObject *)code); \ + instr = trace_stack[trace_stack_depth].instr; \ + } while (0) /* Returns the length of the trace on success, * 0 if it failed to produce a worthwhile trace, @@ -1070,11 +1088,13 @@ allocate_executor(int exit_count, int length) #ifdef Py_DEBUG -#define CHECK(PRED) \ -if (!(PRED)) { \ - printf(#PRED " at %d\n", i); \ - assert(0); \ -} +#define CHECK(PRED) \ + do { \ + if (!(PRED)) { \ + printf(#PRED " at %d\n", i); \ + assert(0); \ + } \ + } while (0) static int target_unused(int opcode) From 446ccb5261086180446c209459495e766fa6a442 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, 8 Sep 2024 17:51:15 +0200 Subject: [PATCH 07/26] `Python/perf_jit_trampoline.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/perf_jit_trampoline.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Python/perf_jit_trampoline.c b/Python/perf_jit_trampoline.c index 0a8945958b4b3c..d71765b6ffd2c9 100644 --- a/Python/perf_jit_trampoline.c +++ b/Python/perf_jit_trampoline.c @@ -430,17 +430,19 @@ elfctx_append_uleb128(ELFObjectContext* ctx, uint32_t v) #define DWRF_UV(x) (ctx->p = p, elfctx_append_uleb128(ctx, (x)), p = ctx->p) #define DWRF_SV(x) (ctx->p = p, elfctx_append_sleb128(ctx, (x)), p = ctx->p) #define DWRF_STR(str) (ctx->p = p, elfctx_append_string(ctx, (str)), p = ctx->p) -#define DWRF_ALIGNNOP(s) \ - while ((uintptr_t)p & ((s)-1)) { \ - *p++ = DWRF_CFA_nop; \ - } -#define DWRF_SECTION(name, stmt) \ - { \ - uint32_t* szp_##name = (uint32_t*)p; \ - p += 4; \ - stmt; \ - *szp_##name = (uint32_t)((p - (uint8_t*)szp_##name) - 4); \ - } +#define DWRF_ALIGNNOP(s) \ + do { \ + while ((uintptr_t)p & ((s)-1)) { \ + *p++ = DWRF_CFA_nop; \ + } \ + } while (0) +#define DWRF_SECTION(NAME, STMT) \ + do { \ + uint32_t* szp_##NAME = (uint32_t*)p; \ + p += 4; \ + STMT; \ + *szp_##NAME = (uint32_t)((p - (uint8_t*)szp_##NAME) - 4); \ + } while (0) /* Initialize .eh_frame section. */ static void @@ -461,7 +463,7 @@ elf_init_ehframe(ELFObjectContext* ctx) DWRF_U8(DWRF_CFA_def_cfa); DWRF_UV(DWRF_REG_SP); DWRF_UV(sizeof(uintptr_t)); DWRF_U8(DWRF_CFA_offset|DWRF_REG_RA); DWRF_UV(1); DWRF_ALIGNNOP(sizeof(uintptr_t)); - ) + ); ctx->eh_frame_p = p; @@ -490,7 +492,7 @@ elf_init_ehframe(ELFObjectContext* ctx) #else # error "Unsupported target architecture" #endif - DWRF_ALIGNNOP(sizeof(uintptr_t));) + DWRF_ALIGNNOP(sizeof(uintptr_t));); ctx->p = p; } From c76137a2a7f24076eb2bbc21b21f4ce747e8dd29 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, 8 Sep 2024 17:56:13 +0200 Subject: [PATCH 08/26] `Python/_ssl.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_ssl.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 1f5f0215980971..5729d24cc1112f 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -5542,14 +5542,20 @@ _ssl_get_default_verify_paths_impl(PyObject *module) PyObject *odir_env = NULL; PyObject *odir = NULL; -#define CONVERT(info, target) { \ - const char *tmp = (info); \ - target = NULL; \ - if (!tmp) { target = Py_NewRef(Py_None); } \ - else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ - target = PyBytes_FromString(tmp); } \ - if (!target) goto error; \ - } +#define CONVERT(INFO, TARGET) \ + do { \ + const char *tmp = (INFO); \ + TARGET = NULL; \ + if (!tmp) { \ + TARGET = Py_NewRef(Py_None); \ + } \ + else if ((TARGET = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ + TARGET = PyBytes_FromString(tmp); \ + } \ + if (!TARGET) { \ + goto error; \ + } \ + } while (0) CONVERT(X509_get_default_cert_file_env(), ofile_env); CONVERT(X509_get_default_cert_file(), ofile); From df70f7a9019032bfe6267f36c6a2d778c1ffad6f 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, 8 Sep 2024 16:42:49 +0200 Subject: [PATCH 09/26] `Python/specialize.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/specialize.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Python/specialize.c b/Python/specialize.c index da618952e85978..ae53043f421534 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -131,10 +131,14 @@ _Py_GetSpecializationStats(void) { } -#define PRINT_STAT(i, field) \ - if (stats[i].field) { \ - fprintf(out, " opcode[%s]." #field " : %" PRIu64 "\n", _PyOpcode_OpName[i], stats[i].field); \ - } +#define PRINT_STAT(IDX, FIELD) \ + do { \ + if (stats[IDX].FIELD) { \ + fprintf(out, \ + " opcode[%s]." #FIELD " : %" PRIu64 "\n", \ + _PyOpcode_OpName[IDX], stats[IDX].FIELD); \ + } \ + } while (0) static void print_spec_stats(FILE *out, OpcodeStats *stats) From 1acfac63cd7723f188c3d9bd3f22a7fc30a8ab44 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, 8 Sep 2024 17:59:17 +0200 Subject: [PATCH 10/26] `Python/dtoa.c`: protect macros expansion via `do { ... } while (0)` constructions --- Python/dtoa.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Python/dtoa.c b/Python/dtoa.c index d0c89b2b468f75..7a24423e6994ff 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -169,7 +169,11 @@ typedef uint64_t ULLong; /* End Python #define linking */ #ifdef DEBUG -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#define Bug(X) \ + do { \ + fprintf(stderr, "%s\n", X); \ + exit(1); \ + } while (0) #endif typedef union { double d; ULong L[2]; } U; From 7050840028a4e9ca33d839608e4115662b233cf5 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, 8 Sep 2024 16:58:38 +0200 Subject: [PATCH 11/26] `Objects/sliceobject.c`: protect macros expansion via `do { ... } while (0)` constructions --- Objects/sliceobject.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 1b6d35998c2b69..b1382a864e251d 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -636,15 +636,17 @@ static Py_hash_t slicehash(PySliceObject *v) { Py_uhash_t acc = _PyHASH_XXPRIME_5; -#define _PyHASH_SLICE_PART(com) { \ - Py_uhash_t lane = PyObject_Hash(v->com); \ - if(lane == (Py_uhash_t)-1) { \ - return -1; \ - } \ - acc += lane * _PyHASH_XXPRIME_2; \ - acc = _PyHASH_XXROTATE(acc); \ - acc *= _PyHASH_XXPRIME_1; \ -} +#define _PyHASH_SLICE_PART(COM) \ + do { \ + Py_uhash_t lane = PyObject_Hash(v->COM); \ + if(lane == (Py_uhash_t)-1) { \ + return -1; \ + } \ + acc += lane * _PyHASH_XXPRIME_2; \ + acc = _PyHASH_XXROTATE(acc); \ + acc *= _PyHASH_XXPRIME_1; \ + } while (0) + _PyHASH_SLICE_PART(start); _PyHASH_SLICE_PART(stop); _PyHASH_SLICE_PART(step); From d1942fac11af2fb31dde10c779499cd3ca934873 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, 8 Sep 2024 16:48:17 +0200 Subject: [PATCH 12/26] `Objects/memoryview.c`: protect macros expansion via `do { ... } while (0)` constructions --- Objects/memoryobject.c | 72 ++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 498a37c1a3d869..bc9ba9ea2c4ffd 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -183,45 +183,55 @@ PyTypeObject _PyManagedBuffer_Type = { (((PyMemoryViewObject *)mv)->flags&_Py_MEMORYVIEW_RELEASED || \ ((PyMemoryViewObject *)mv)->mbuf->flags&_Py_MANAGED_BUFFER_RELEASED) -#define CHECK_RELEASED(mv) \ - if (BASE_INACCESSIBLE(mv)) { \ - PyErr_SetString(PyExc_ValueError, \ - "operation forbidden on released memoryview object"); \ - return NULL; \ - } +#define CHECK_RELEASED(MV) \ + do { \ + if (BASE_INACCESSIBLE(MV)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return NULL; \ + } \ + } while (0) -#define CHECK_RELEASED_INT(mv) \ - if (BASE_INACCESSIBLE(mv)) { \ - PyErr_SetString(PyExc_ValueError, \ - "operation forbidden on released memoryview object"); \ - return -1; \ - } +#define CHECK_RELEASED_INT(MV) \ + do { \ + if (BASE_INACCESSIBLE(MV)) { \ + PyErr_SetString(PyExc_ValueError, \ + "operation forbidden on released memoryview object"); \ + return -1; \ + } \ + } while (0) -#define CHECK_RESTRICTED(mv) \ - if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ - PyErr_SetString(PyExc_ValueError, \ - "cannot create new view on restricted memoryview"); \ - return NULL; \ - } +#define CHECK_RESTRICTED(MV) \ + do { \ + if (((PyMemoryViewObject *)(MV))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return NULL; \ + } \ + } while (0) -#define CHECK_RESTRICTED_INT(mv) \ - if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ - PyErr_SetString(PyExc_ValueError, \ - "cannot create new view on restricted memoryview"); \ - return -1; \ - } +#define CHECK_RESTRICTED_INT(MV) \ + do { \ + if (((PyMemoryViewObject *)(MV))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return -1; \ + } \ + } while (0) /* See gh-92888. These macros signal that we need to check the memoryview again due to possible read after frees. */ #define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv) #define CHECK_RELEASED_INT_AGAIN(mv) CHECK_RELEASED_INT(mv) -#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; \ - } +#define CHECK_LIST_OR_TUPLE(OBJ) \ + do { \ + if (!PyList_Check(OBJ) && !PyTuple_Check(OBJ)) { \ + PyErr_SetString(PyExc_TypeError, \ + #OBJ " must be a list or a tuple"); \ + return NULL; \ + } \ + } while (0) #define VIEW_ADDR(mv) (&((PyMemoryViewObject *)mv)->view) @@ -1456,7 +1466,7 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, return NULL; } if (shape) { - CHECK_LIST_OR_TUPLE(shape) + CHECK_LIST_OR_TUPLE(shape); ndim = PySequence_Fast_GET_SIZE(shape); if (ndim > PyBUF_MAX_NDIM) { PyErr_SetString(PyExc_ValueError, From e195b55e186f3bdae78e8ece5c1a01c08692a0c5 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, 8 Sep 2024 16:53:00 +0200 Subject: [PATCH 13/26] `Objects/dictobject.c`: protect macros expansion via `do { ... } while (0)` constructions --- Objects/dictobject.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index b81ed189456ec1..7d036ee36f4034 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -154,14 +154,18 @@ ASSERT_DICT_LOCKED(PyObject *op) _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); } #define ASSERT_DICT_LOCKED(op) ASSERT_DICT_LOCKED(_Py_CAST(PyObject*, op)) -#define ASSERT_WORLD_STOPPED_OR_DICT_LOCKED(op) \ - if (!_PyInterpreterState_GET()->stoptheworld.world_stopped) { \ - ASSERT_DICT_LOCKED(op); \ - } -#define ASSERT_WORLD_STOPPED_OR_OBJ_LOCKED(op) \ - if (!_PyInterpreterState_GET()->stoptheworld.world_stopped) { \ - _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op); \ - } +#define ASSERT_WORLD_STOPPED_OR_DICT_LOCKED(OP) \ + do { \ + if (!_PyInterpreterState_GET()->stoptheworld.world_stopped) { \ + ASSERT_DICT_LOCKED(OP); \ + } \ + } while (0) +#define ASSERT_WORLD_STOPPED_OR_OBJ_LOCKED(OP) \ + do { \ + if (!_PyInterpreterState_GET()->stoptheworld.world_stopped) { \ + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(OP); \ + } \ + } while (0) #define IS_DICT_SHARED(mp) _PyObject_GC_IS_SHARED(mp) #define SET_DICT_SHARED(mp) _PyObject_GC_SET_SHARED(mp) @@ -170,15 +174,19 @@ ASSERT_DICT_LOCKED(PyObject *op) #define ASSERT_OWNED_OR_SHARED(mp) \ assert(_Py_IsOwnedByCurrentThread((PyObject *)mp) || IS_DICT_SHARED(mp)); -#define LOCK_KEYS_IF_SPLIT(keys, kind) \ - if (kind == DICT_KEYS_SPLIT) { \ - LOCK_KEYS(keys); \ - } - -#define UNLOCK_KEYS_IF_SPLIT(keys, kind) \ - if (kind == DICT_KEYS_SPLIT) { \ - UNLOCK_KEYS(keys); \ - } +#define LOCK_KEYS_IF_SPLIT(KEYS, KIND) \ + do { \ + if (KIND == DICT_KEYS_SPLIT) { \ + LOCK_KEYS(KEYS); \ + } \ + } while (0) + +#define UNLOCK_KEYS_IF_SPLIT(KEYS, KIND) \ + do { \ + if (KIND == DICT_KEYS_SPLIT) { \ + UNLOCK_KEYS(KEYS); \ + } \ + } while (0) static inline Py_ssize_t load_keys_nentries(PyDictObject *mp) From 1b65e9822975d6f48cdc0b4f5f50b63d6dea34e2 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, 8 Sep 2024 17:51:08 +0200 Subject: [PATCH 14/26] `Modules/posixmodule.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/posixmodule.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index f24ab81cbcb77b..2f1f825ab67bc5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6224,15 +6224,15 @@ os_uname_impl(PyObject *module) if (value == NULL) return NULL; -#define SET(i, field) \ - { \ - PyObject *o = PyUnicode_DecodeFSDefault(field); \ - if (!o) { \ - Py_DECREF(value); \ - return NULL; \ - } \ - PyStructSequence_SET_ITEM(value, i, o); \ - } \ +#define SET(INDEX, FIELD) \ + do { \ + PyObject *o = PyUnicode_DecodeFSDefault(FIELD); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, INDEX, o); \ + } while (0) SET(0, u.sysname); SET(1, u.nodename); @@ -10556,15 +10556,15 @@ build_times_result(PyObject *module, double user, double system, if (value == NULL) return NULL; -#define SET(i, field) \ - { \ - PyObject *o = PyFloat_FromDouble(field); \ - if (!o) { \ - Py_DECREF(value); \ - return NULL; \ - } \ - PyStructSequence_SET_ITEM(value, i, o); \ - } \ +#define SET(INDEX, FIELD) \ + do { \ + PyObject *o = PyFloat_FromDouble(FIELD); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, INDEX, o); \ + } while (0) SET(0, user); SET(1, system); From e32c48a63f3856d6aa38038957a1eede37ebda02 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, 8 Sep 2024 17:56:18 +0200 Subject: [PATCH 15/26] `Modules/getaddrinfo.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/getaddrinfo.c | 58 ++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/Modules/getaddrinfo.c b/Modules/getaddrinfo.c index 6fb6062a6520d9..6caac9cb31145a 100644 --- a/Modules/getaddrinfo.c +++ b/Modules/getaddrinfo.c @@ -167,35 +167,37 @@ if (pai->ai_flags & AI_CANONNAME) {\ } #ifdef HAVE_SOCKADDR_SA_LEN -#define GET_AI(ai, gai_afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((gai_afd)->a_socklen)))\ - == NULL) goto free;\ - memcpy(ai, pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ - (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\ - (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ - ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ -} +#define GET_AI(ai, gai_afd, addr, port) \ + do { \ + char *p; \ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) + \ + ((gai_afd)->a_socklen))) \ + == NULL) goto free; \ + memcpy(ai, pai, sizeof(struct addrinfo)); \ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1); \ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen); \ + (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen; \ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af; \ + ((struct sockinet *)(ai)->ai_addr)->si_port = port; \ + p = (char *)((ai)->ai_addr); \ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen); \ + } while (0) #else -#define GET_AI(ai, gai_afd, addr, port) {\ - char *p;\ - if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ - ((gai_afd)->a_socklen)))\ - == NULL) goto free;\ - memcpy(ai, pai, sizeof(struct addrinfo));\ - (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ - memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ - (ai)->ai_addrlen = (gai_afd)->a_socklen;\ - (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ - ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ - p = (char *)((ai)->ai_addr);\ - memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ -} +#define GET_AI(ai, gai_afd, addr, port) \ + do { \ + char *p; \ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) + \ + ((gai_afd)->a_socklen))) \ + == NULL) goto free; \ + memcpy(ai, pai, sizeof(struct addrinfo)); \ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1); \ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen); \ + (ai)->ai_addrlen = (gai_afd)->a_socklen; \ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af; \ + ((struct sockinet *)(ai)->ai_addr)->si_port = port; \ + p = (char *)((ai)->ai_addr); \ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen); \ + } while (0) #endif #define ERR(err) { error = (err); goto bad; } From 44474eb0dd23a2f2bfceb5667e4eb289cba34e6c 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, 8 Sep 2024 18:00:45 +0200 Subject: [PATCH 16/26] `Modules/_testcapi/monitoring.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_testcapi/monitoring.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Modules/_testcapi/monitoring.c b/Modules/_testcapi/monitoring.c index 6fd4a405688f48..4b24a4c1ce5e3a 100644 --- a/Modules/_testcapi/monitoring.c +++ b/Modules/_testcapi/monitoring.c @@ -105,10 +105,15 @@ static PyTypeObject PyCodeLike_Type = { .tp_str = (reprfunc) CodeLike_str, }; -#define RAISE_UNLESS_CODELIKE(v) if (!Py_IS_TYPE((v), &PyCodeLike_Type)) { \ - PyErr_Format(PyExc_TypeError, "expected a code-like, got %s", Py_TYPE(v)->tp_name); \ - return NULL; \ - } +#define RAISE_UNLESS_CODELIKE(v) \ + do { \ + if (!Py_IS_TYPE((v), &PyCodeLike_Type)) { \ + PyErr_Format(PyExc_TypeError, \ + "expected a code-like, got %s", \ + Py_TYPE(v)->tp_name); \ + return NULL; \ + } \ + } while (0) /*******************************************************************/ From ae3adff5939b322ea8cda02b295922af897abf8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:03:47 +0200 Subject: [PATCH 17/26] `Modules/ctypes/_ctypes.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_ctypes/_ctypes.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 2b23be7b753e34..cc5a84400949fc 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -5707,10 +5707,12 @@ wstring_at(const wchar_t *ptr, int size) static int _ctypes_add_types(PyObject *mod) { -#define TYPE_READY(TYPE) \ - if (PyType_Ready(TYPE) < 0) { \ - return -1; \ - } +#define TYPE_READY(TYPE) do { \ + if (PyType_Ready(TYPE) < 0) { \ + return -1; \ + } \ +} while (0) + #define CREATE_TYPE(TP, SPEC, META, BASE) do { \ PyObject *type = PyType_FromMetaclass(META, mod, SPEC, \ (PyObject *)BASE); \ From 0baba9ccbb6d17a6907a4c0ac636800dfbfaf46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:03:55 +0200 Subject: [PATCH 18/26] `Modules/_csv.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_csv.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Modules/_csv.c b/Modules/_csv.c index a623ea449da779..1366d033f15583 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -501,12 +501,17 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) DIALECT_GETATTR(quoting, "quoting"); DIALECT_GETATTR(skipinitialspace, "skipinitialspace"); DIALECT_GETATTR(strict, "strict"); +#undef DIALECT_GETATTR } /* check types and convert to C values */ -#define DIASET(meth, name, target, src, dflt) \ - if (meth(name, target, src, dflt)) \ - goto err +#define DIASET(meth, name, target, src, dflt) \ + do { \ + if (meth(name, target, src, dflt)) { \ + goto err; \ + } \ + } while (0) + DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ','); DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, true); DIASET(_set_char_or_none, "escapechar", &self->escapechar, escapechar, NOT_SET); @@ -515,6 +520,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL); DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, false); DIASET(_set_bool, "strict", &self->strict, strict, false); +#undef DIASET /* validate options */ if (dialect_check_quoting(self->quoting)) From 21995096eb73e8d352de95371af98e9fb9246b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:01 +0200 Subject: [PATCH 19/26] `Modules/_asynciomodule.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_asynciomodule.c | 58 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 870084100a1b85..552b1b3e959e3e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3767,42 +3767,46 @@ module_init(asyncio_state *state) goto fail; } -#define WITH_MOD(NAME) \ - Py_CLEAR(module); \ - module = PyImport_ImportModule(NAME); \ - if (module == NULL) { \ - goto fail; \ - } +#define WITH_MOD(NAME) \ + do { \ + Py_CLEAR(module); \ + module = PyImport_ImportModule(NAME); \ + if (module == NULL) { \ + goto fail; \ + } \ + } while (0) -#define GET_MOD_ATTR(VAR, NAME) \ - VAR = PyObject_GetAttrString(module, NAME); \ - if (VAR == NULL) { \ - goto fail; \ - } +#define GET_MOD_ATTR(VAR, NAME) \ + do { \ + VAR = PyObject_GetAttrString(module, NAME); \ + if (VAR == NULL) { \ + goto fail; \ + } \ + } while (0) - WITH_MOD("asyncio.events") - GET_MOD_ATTR(state->asyncio_get_event_loop_policy, "get_event_loop_policy") + WITH_MOD("asyncio.events"); + GET_MOD_ATTR(state->asyncio_get_event_loop_policy, "get_event_loop_policy"); - WITH_MOD("asyncio.base_futures") - GET_MOD_ATTR(state->asyncio_future_repr_func, "_future_repr") + WITH_MOD("asyncio.base_futures"); + GET_MOD_ATTR(state->asyncio_future_repr_func, "_future_repr"); - WITH_MOD("asyncio.exceptions") - GET_MOD_ATTR(state->asyncio_InvalidStateError, "InvalidStateError") - GET_MOD_ATTR(state->asyncio_CancelledError, "CancelledError") + WITH_MOD("asyncio.exceptions"); + GET_MOD_ATTR(state->asyncio_InvalidStateError, "InvalidStateError"); + GET_MOD_ATTR(state->asyncio_CancelledError, "CancelledError"); - WITH_MOD("asyncio.base_tasks") - GET_MOD_ATTR(state->asyncio_task_repr_func, "_task_repr") - GET_MOD_ATTR(state->asyncio_task_get_stack_func, "_task_get_stack") - GET_MOD_ATTR(state->asyncio_task_print_stack_func, "_task_print_stack") + WITH_MOD("asyncio.base_tasks"); + GET_MOD_ATTR(state->asyncio_task_repr_func, "_task_repr"); + GET_MOD_ATTR(state->asyncio_task_get_stack_func, "_task_get_stack"); + GET_MOD_ATTR(state->asyncio_task_print_stack_func, "_task_print_stack"); - WITH_MOD("asyncio.coroutines") - GET_MOD_ATTR(state->asyncio_iscoroutine_func, "iscoroutine") + WITH_MOD("asyncio.coroutines"); + GET_MOD_ATTR(state->asyncio_iscoroutine_func, "iscoroutine"); - WITH_MOD("traceback") - GET_MOD_ATTR(state->traceback_extract_stack, "extract_stack") + WITH_MOD("traceback"); + GET_MOD_ATTR(state->traceback_extract_stack, "extract_stack"); PyObject *weak_set; - WITH_MOD("weakref") + WITH_MOD("weakref"); GET_MOD_ATTR(weak_set, "WeakSet"); state->non_asyncio_tasks = PyObject_CallNoArgs(weak_set); Py_CLEAR(weak_set); From b0fbddecc64899a1ec0fe98feb37297760ff5b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:18 +0200 Subject: [PATCH 20/26] `Modules/_testlimitedcapi/unicode.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_testlimitedcapi/unicode.c | 41 ++++++++++++++++-------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/Modules/_testlimitedcapi/unicode.c b/Modules/_testlimitedcapi/unicode.c index 2b70d09108a333..ed18c98d220d87 100644 --- a/Modules/_testlimitedcapi/unicode.c +++ b/Modules/_testlimitedcapi/unicode.c @@ -1418,25 +1418,28 @@ test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) PyObject *result; PyObject *unicode = PyUnicode_FromString("None"); -#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2) \ - result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \ - if (EXPECTED == NULL) { \ - if (!check_raised_systemerror(result, FORMAT)) { \ - goto Fail; \ - } \ - } \ - else if (result == NULL) \ - return NULL; \ - else if (PyUnicode_CompareWithASCIIString(result, EXPECTED) != 0) { \ - PyObject *utf8 = PyUnicode_AsUTF8String(result); \ - PyErr_Format(PyExc_AssertionError, \ - "test_string_from_format: failed at \"%s\" " \ - "expected \"%s\" got \"%s\"", \ - FORMAT, EXPECTED, utf8); \ - Py_XDECREF(utf8); \ - goto Fail; \ - } \ - Py_XDECREF(result) +#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2) \ + do { \ + result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \ + if (EXPECTED == NULL) { \ + if (!check_raised_systemerror(result, FORMAT)) { \ + goto Fail; \ + } \ + } \ + else if (result == NULL) { \ + return NULL; \ + } \ + else if (PyUnicode_CompareWithASCIIString(result, EXPECTED) != 0) { \ + PyObject *utf8 = PyUnicode_AsUTF8String(result); \ + PyErr_Format(PyExc_AssertionError, \ + "test_string_from_format: failed at \"%s\" " \ + "expected \"%s\" got \"%s\"", \ + FORMAT, EXPECTED, utf8); \ + Py_XDECREF(utf8); \ + goto Fail; \ + } \ + Py_XDECREF(result); \ + } while (0) #define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG) \ CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0) From 8eda720bd5f0abe70a1b0fd1d924cd4b7c0efbb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:26 +0200 Subject: [PATCH 21/26] `Modules/_testcapi/mem.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_testcapi/mem.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c index ab4ad934644c38..fdeb23b1ff65fe 100644 --- a/Modules/_testcapi/mem.c +++ b/Modules/_testcapi/mem.c @@ -214,12 +214,14 @@ test_setallocators(PyMemAllocatorDomain domain) break; } -#define CHECK_CTX(FUNC) \ - if (hook.ctx != &hook) { \ - error_msg = FUNC " wrong context"; \ - goto fail; \ - } \ - hook.ctx = NULL; /* reset for next check */ +#define CHECK_CTX(FUNC) \ + do { \ + if (hook.ctx != &hook) { \ + error_msg = FUNC " wrong context"; \ + goto fail; \ + } \ + hook.ctx = NULL; /* reset for next check */ \ + } while (0) if (ptr == NULL) { error_msg = "malloc failed"; From c495a8747097497370553e29cbbf2e4f42fdf42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:33 +0200 Subject: [PATCH 22/26] `Modules/_io/textio.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_io/textio.c | 68 +++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 439e26c5271939..bc7878b5bfd7a5 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -305,12 +305,14 @@ check_decoded(PyObject *decoded) return 0; } -#define CHECK_INITIALIZED_DECODER(self) \ - if (self->errors == NULL) { \ - PyErr_SetString(PyExc_ValueError, \ - "IncrementalNewlineDecoder.__init__() not called"); \ - return NULL; \ - } +#define CHECK_INITIALIZED_DECODER(self) \ + do { \ + if (self->errors == NULL) { \ + PyErr_SetString(PyExc_ValueError, \ + "IncrementalNewlineDecoder.__init__() not called"); \ + return NULL; \ + } \ + } while (0) #define SEEN_CR 1 #define SEEN_LF 2 @@ -1516,31 +1518,37 @@ _io_TextIOWrapper_closed_get_impl(textio *self); return NULL; \ } while (0) -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } +#define CHECK_INITIALIZED(self) \ + do { \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return NULL; \ + } \ + } while (0) -#define CHECK_ATTACHED(self) \ - CHECK_INITIALIZED(self); \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - return NULL; \ - } +#define CHECK_ATTACHED(self) \ + do { \ + CHECK_INITIALIZED(self); \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ + return NULL; \ + } \ + } while (0) -#define CHECK_ATTACHED_INT(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return -1; \ - } else if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "underlying buffer has been detached"); \ - return -1; \ - } +#define CHECK_ATTACHED_INT(self) \ + do { \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return -1; \ + } else if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "underlying buffer has been detached"); \ + return -1; \ + } \ + } while (0) /*[clinic input] @@ -2947,7 +2955,7 @@ static PyObject * _io_TextIOWrapper_truncate_impl(textio *self, PyObject *pos) /*[clinic end generated code: output=90ec2afb9bb7745f input=8bddb320834c93ee]*/ { - CHECK_ATTACHED(self) + CHECK_ATTACHED(self); if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; From 88b98dc9bab0853487b06bbb3de9c4edaf1531e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:37 +0200 Subject: [PATCH 23/26] `Modules/_io/stringio.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_io/stringio.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 6d48bcb552b4bf..d9a525108db87e 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -51,24 +51,30 @@ typedef struct { static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs); -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - return NULL; \ - } - -#define CHECK_CLOSED(self) \ - if (self->closed) { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on closed file"); \ - return NULL; \ - } - -#define ENSURE_REALIZED(self) \ - if (realize(self) < 0) { \ - return NULL; \ - } +#define CHECK_INITIALIZED(self) \ + do { \ + if (self->ok <= 0) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + return NULL; \ + } \ + } while (0) + +#define CHECK_CLOSED(self) \ + do { \ + if (self->closed) { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on closed file"); \ + return NULL; \ + } \ + } while (0) + +#define ENSURE_REALIZED(self) \ + do { \ + if (realize(self) < 0) { \ + return NULL; \ + } \ + } while (0) /* Internal routine for changing the size, in terms of characters, of the From 3a9744860be2dc836c03d707596eb1a5782ff69c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:41 +0200 Subject: [PATCH 24/26] `Modules/_io/bytesio.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_io/bytesio.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index fb66d3db0f7a1f..c08eba97e6d085 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -54,15 +54,19 @@ check_exports(bytesio *self) return 0; } -#define CHECK_CLOSED(self) \ - if (check_closed(self)) { \ - return NULL; \ - } - -#define CHECK_EXPORTS(self) \ - if (check_exports(self)) { \ - return NULL; \ - } +#define CHECK_CLOSED(self) \ + do { \ + if (check_closed(self)) { \ + return NULL; \ + } \ + } while (0) + +#define CHECK_EXPORTS(self) \ + do { \ + if (check_exports(self)) { \ + return NULL; \ + } \ + } while (0) #define SHARED_BUF(self) (Py_REFCNT((self)->buf) > 1) From 160a6c150ba5fd905511256257082d2bc7b4f120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:47 +0200 Subject: [PATCH 25/26] `Modules/_io/bufferedio.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_io/bufferedio.c | 124 +++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 58 deletions(-) diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index bc5fff54a62b6d..00eec29a58a5e9 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -332,29 +332,33 @@ _enter_buffered_busy(buffered *self) PyThread_release_lock(self->lock); \ } while(0); -#define CHECK_INITIALIZED(self) \ - if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "raw stream has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ - return NULL; \ - } - -#define CHECK_INITIALIZED_INT(self) \ - if (self->ok <= 0) { \ - if (self->detached) { \ - PyErr_SetString(PyExc_ValueError, \ - "raw stream has been detached"); \ - } else { \ - PyErr_SetString(PyExc_ValueError, \ - "I/O operation on uninitialized object"); \ - } \ - return -1; \ - } +#define CHECK_INITIALIZED(self) \ + do { \ + if (self->ok <= 0) { \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "raw stream has been detached"); \ + } else { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + } \ + return NULL; \ + } \ + } while (0) + +#define CHECK_INITIALIZED_INT(self) \ + do { \ + if (self->ok <= 0) { \ + if (self->detached) { \ + PyErr_SetString(PyExc_ValueError, \ + "raw stream has been detached"); \ + } else { \ + PyErr_SetString(PyExc_ValueError, \ + "I/O operation on uninitialized object"); \ + } \ + return -1; \ + } \ + } while (0) #define IS_CLOSED(self) \ (!self->buffer || \ @@ -362,11 +366,15 @@ _enter_buffered_busy(buffered *self) ? _PyFileIO_closed(self->raw) \ : buffered_closed(self))) -#define CHECK_CLOSED(self, error_msg) \ - if (IS_CLOSED(self) && (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) { \ - PyErr_SetString(PyExc_ValueError, error_msg); \ - return NULL; \ - } \ +#define CHECK_CLOSED(self, error_msg) \ + do { \ + if (IS_CLOSED(self) \ + && (Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t) == 0)) \ + { \ + PyErr_SetString(PyExc_ValueError, error_msg); \ + return NULL; \ + } \ + } while (0) #define VALID_READ_BUFFER(self) \ (self->readable && self->read_end != -1) @@ -498,7 +506,7 @@ static PyObject * _io__Buffered_simple_flush_impl(buffered *self) /*[clinic end generated code: output=29ebb3820db1bdfd input=5248cb84a65f80bd]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush)); } @@ -507,7 +515,7 @@ buffered_closed(buffered *self) { int closed; PyObject *res; - CHECK_INITIALIZED_INT(self) + CHECK_INITIALIZED_INT(self); res = PyObject_GetAttr(self->raw, &_Py_ID(closed)); if (res == NULL) return -1; @@ -526,7 +534,7 @@ static PyObject * _io__Buffered_closed_get_impl(buffered *self) /*[clinic end generated code: output=f08ce57290703a1a input=18eddefdfe4a3d2f]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_GetAttr(self->raw, &_Py_ID(closed)); } @@ -542,7 +550,7 @@ _io__Buffered_close_impl(buffered *self) PyObject *res = NULL; int r; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); if (!ENTER_BUFFERED(self)) { return NULL; } @@ -603,7 +611,7 @@ _io__Buffered_detach_impl(buffered *self) /*[clinic end generated code: output=dd0fc057b8b779f7 input=d4ef1828a678be37]*/ { PyObject *raw; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); if (_PyFile_Flush((PyObject *)self) < 0) { return NULL; } @@ -625,7 +633,7 @@ static PyObject * _io__Buffered_seekable_impl(buffered *self) /*[clinic end generated code: output=90172abb5ceb6e8f input=e3a4fc1d297b2fd3]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable)); } @@ -638,7 +646,7 @@ static PyObject * _io__Buffered_readable_impl(buffered *self) /*[clinic end generated code: output=92afa07661ecb698 input=abe54107d59bca9a]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable)); } @@ -651,7 +659,7 @@ static PyObject * _io__Buffered_writable_impl(buffered *self) /*[clinic end generated code: output=4e3eee8d6f9d8552 input=45eb76bf6a10e6f7]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable)); } @@ -666,7 +674,7 @@ static PyObject * _io__Buffered_name_get_impl(buffered *self) /*[clinic end generated code: output=d2adf384051d3d10 input=6b84a0e6126f545e]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_GetAttr(self->raw, &_Py_ID(name)); } @@ -680,7 +688,7 @@ static PyObject * _io__Buffered_mode_get_impl(buffered *self) /*[clinic end generated code: output=0feb205748892fa4 input=0762d5e28542fd8c]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_GetAttr(self->raw, &_Py_ID(mode)); } @@ -695,7 +703,7 @@ static PyObject * _io__Buffered_fileno_impl(buffered *self) /*[clinic end generated code: output=b717648d58a95ee3 input=1c4fead777bae20a]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno)); } @@ -708,7 +716,7 @@ static PyObject * _io__Buffered_isatty_impl(buffered *self) /*[clinic end generated code: output=c20e55caae67baea input=e53d182d7e490e3a]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty)); } @@ -922,8 +930,8 @@ _io__Buffered_flush_impl(buffered *self) { PyObject *res; - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "flush of closed file") + CHECK_INITIALIZED(self); + CHECK_CLOSED(self, "flush of closed file"); if (!ENTER_BUFFERED(self)) return NULL; @@ -947,8 +955,8 @@ _io__Buffered_peek_impl(buffered *self, Py_ssize_t size) { PyObject *res = NULL; - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "peek of closed file") + CHECK_INITIALIZED(self); + CHECK_CLOSED(self, "peek of closed file"); if (!ENTER_BUFFERED(self)) return NULL; @@ -979,14 +987,14 @@ _io__Buffered_read_impl(buffered *self, Py_ssize_t n) { PyObject *res; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); if (n < -1) { PyErr_SetString(PyExc_ValueError, "read length must be non-negative or -1"); return NULL; } - CHECK_CLOSED(self, "read of closed file") + CHECK_CLOSED(self, "read of closed file"); if (n == -1) { /* The number of bytes is unspecified, read until the end of stream */ @@ -1022,12 +1030,12 @@ _io__Buffered_read1_impl(buffered *self, Py_ssize_t n) Py_ssize_t have, r; PyObject *res = NULL; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); if (n < 0) { n = self->buffer_size; } - CHECK_CLOSED(self, "read of closed file") + CHECK_CLOSED(self, "read of closed file"); if (n == 0) return PyBytes_FromStringAndSize(NULL, 0); @@ -1079,8 +1087,8 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) Py_ssize_t n, written = 0, remaining; PyObject *res = NULL; - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "readinto of closed file") + CHECK_INITIALIZED(self); + CHECK_CLOSED(self, "readinto of closed file"); n = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t); if (n > 0) { @@ -1192,7 +1200,7 @@ _buffered_readline(buffered *self, Py_ssize_t limit) Py_ssize_t n; const char *start, *s, *end; - CHECK_CLOSED(self, "readline of closed file") + CHECK_CLOSED(self, "readline of closed file"); /* First, try to find a line in the buffer. This can run unlocked because the calls to the C API are simple enough that they can't trigger @@ -1303,7 +1311,7 @@ static PyObject * _io__Buffered_readline_impl(buffered *self, Py_ssize_t size) /*[clinic end generated code: output=24dd2aa6e33be83c input=e81ca5abd4280776]*/ { - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); return _buffered_readline(self, size); } @@ -1319,7 +1327,7 @@ _io__Buffered_tell_impl(buffered *self) { Py_off_t pos; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); pos = _buffered_raw_tell(self); if (pos == -1) return NULL; @@ -1347,7 +1355,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) Py_off_t target, n; PyObject *res = NULL; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); /* Do some error checking instead of trusting OS 'seek()' ** error detection, just in case. @@ -1365,7 +1373,7 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) return NULL; } - CHECK_CLOSED(self, "seek of closed file") + CHECK_CLOSED(self, "seek of closed file"); _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL) { @@ -1449,8 +1457,8 @@ _io__Buffered_truncate_impl(buffered *self, PyTypeObject *cls, PyObject *pos) { PyObject *res = NULL; - CHECK_INITIALIZED(self) - CHECK_CLOSED(self, "truncate of closed file") + CHECK_INITIALIZED(self); + CHECK_CLOSED(self, "truncate of closed file"); if (!self->writable) { _PyIO_State *state = get_io_state_by_cls(cls); return bufferediobase_unsupported(state, "truncate"); @@ -2073,7 +2081,7 @@ _io_BufferedWriter_write_impl(buffered *self, Py_buffer *buffer) Py_ssize_t written, avail, remaining; Py_off_t offset; - CHECK_INITIALIZED(self) + CHECK_INITIALIZED(self); if (!ENTER_BUFFERED(self)) return NULL; From 5c90db8206a4dfeffdbdfdf5712df6d92995cad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Mon, 9 Sep 2024 14:04:56 +0200 Subject: [PATCH 26/26] `Modules/_ctypes/cfield.c`: protect macros expansion via `do { ... } while (0)` constructions --- Modules/_ctypes/cfield.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index abcab6557de914..b592c509927a92 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -425,11 +425,13 @@ Py_ssize_t BUILD_SIZE(Py_ssize_t bitsize, Py_ssize_t offset) { /* This macro CHANGES the first parameter IN PLACE. For proper sign handling, we must first shift left, then right. */ -#define GET_BITFIELD(v, size) \ - if (NUM_BITS(size)) { \ - v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \ - v >>= (sizeof(v)*8 - NUM_BITS(size)); \ - } +#define GET_BITFIELD(v, size) \ + do { \ + if (NUM_BITS(size)) { \ + v <<= (sizeof(v)*8 - LOW_BIT(size) - NUM_BITS(size)); \ + v >>= (sizeof(v)*8 - NUM_BITS(size)); \ + } \ + } while (0) /* This macro RETURNS the first parameter with the bit field CHANGED. */ #define SET(type, x, v, size) \