From 2473f57ba7c0ceeb6c08dfe335995925d0497028 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 29 Nov 2024 12:15:26 +0100 Subject: [PATCH 1/5] Elevate C4013 to level 1 in CI (GH-16986) C4013 warns about undefined functions[1], but for some reason it's only a level 3 warning, and such suppressed by default (usually there will be link errors afterwards, though). It appears to be sensible to elevate the warning to level 1, so it will be converted to a compile error. [1] --- .github/scripts/windows/build_task.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/windows/build_task.bat b/.github/scripts/windows/build_task.bat index 7a2824e299708..3c8dc04d59b40 100644 --- a/.github/scripts/windows/build_task.bat +++ b/.github/scripts/windows/build_task.bat @@ -31,7 +31,7 @@ if %errorlevel% neq 0 exit /b 3 if "%THREAD_SAFE%" equ "0" set ADD_CONF=%ADD_CONF% --disable-zts if "%INTRINSICS%" neq "" set ADD_CONF=%ADD_CONF% --enable-native-intrinsics=%INTRINSICS% -set CFLAGS=/W1 /WX +set CFLAGS=/W1 /WX /w14013 cmd /c configure.bat ^ --enable-snapshot-build ^ From d17ed3445d088825b520ca76f9f1ea24ba5939d7 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Fri, 29 Nov 2024 21:28:38 +0900 Subject: [PATCH 2/5] Fixed GH-16978: Avoid unnecessary padding with leading zeros (#16988) Fixed an issue where leading zeros were padded beyond the allocated memory. fixes #16978 closes #16988 --- NEWS | 4 ++++ ext/bcmath/libbcmath/src/div.c | 1 + ext/bcmath/tests/gh16978.phpt | 12 ++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 ext/bcmath/tests/gh16978.phpt diff --git a/NEWS b/NEWS index f8f96db6881bc..c18859f8f649b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.4.2 +- BcMath: + . Fixed bug GH-16978 (Avoid unnecessary padding with leading zeros) + (Saki Takamachi) + - Core: . Fixed bug GH-16344 (setRawValueWithoutLazyInitialization() and skipLazyInitialization() may change initialized proxy). (Arnaud) diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 9c8344fe771a8..e9377fcfc4279 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -436,6 +436,7 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) numerator_bottom_extension = 0; numeratorend -= scale_diff > numerator_top_extension ? scale_diff - numerator_top_extension : 0; } + numerator_top_extension = MIN(numerator_top_extension, scale); } else { numerator_bottom_extension += scale - numerator_scale; } diff --git a/ext/bcmath/tests/gh16978.phpt b/ext/bcmath/tests/gh16978.phpt new file mode 100644 index 0000000000000..4bb19a9be6bbe --- /dev/null +++ b/ext/bcmath/tests/gh16978.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-16978 Stack buffer overflow ext/bcmath/libbcmath/src/div.c:464:12 in bc_divide +--EXTENSIONS-- +bcmath +--FILE-- + +--EXPECT-- +0.0000000000 +0.0 From 5ed438fe0756cc611a7bf73b68fb6196f836544b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Nov 2024 16:28:27 +0300 Subject: [PATCH 3/5] Update IR IR commit: 673308a039eed5a2fdf4a2783b3dd3d6010a8c19 --- ext/opcache/jit/ir/ir.c | 13 +++++++++---- ext/opcache/jit/ir/ir_emit.c | 5 ++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/ext/opcache/jit/ir/ir.c b/ext/opcache/jit/ir/ir.c index 815551a9b7d53..b21f8ce7d9519 100644 --- a/ext/opcache/jit/ir/ir.c +++ b/ext/opcache/jit/ir/ir.c @@ -1176,7 +1176,7 @@ void ir_build_def_use_lists(ir_ctx *ctx) use_list->count = 0; } - edges = ir_mem_malloc(edges_count * sizeof(ir_ref)); + edges = ir_mem_malloc(IR_ALIGNED_SIZE(edges_count * sizeof(ir_ref), 4096)); for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) { n = insn->inputs_count; for (j = n, p = insn->ops + 1; j > 0; j--, p++) { @@ -1245,7 +1245,7 @@ void ir_build_def_use_lists(ir_ctx *ctx) } ctx->use_edges_count = edges_count; - edges = ir_mem_malloc(edges_count * sizeof(ir_ref)); + edges = ir_mem_malloc(IR_ALIGNED_SIZE(edges_count * sizeof(ir_ref), 4096)); for (use_list = lists + ctx->insns_count - 1; use_list != lists; use_list--) { n = use_list->refs; if (n) { @@ -1356,8 +1356,13 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref) use_list->count++; return 0; } else { - /* Reallocate the whole edges buffer (this is inefficient) */ - ctx->use_edges = ir_mem_realloc(ctx->use_edges, (ctx->use_edges_count + use_list->count + 1) * sizeof(ir_ref)); + size_t old_size = IR_ALIGNED_SIZE(ctx->use_edges_count * sizeof(ir_ref), 4096); + size_t new_size = IR_ALIGNED_SIZE((ctx->use_edges_count + use_list->count + 1) * sizeof(ir_ref), 4096); + + if (old_size < new_size) { + /* Reallocate the whole edges buffer (this is inefficient) */ + ctx->use_edges = ir_mem_realloc(ctx->use_edges, new_size); + } memcpy(ctx->use_edges + ctx->use_edges_count, ctx->use_edges + use_list->refs, use_list->count * sizeof(ir_ref)); use_list->refs = ctx->use_edges_count; ctx->use_edges[use_list->refs + use_list->count] = ref; diff --git a/ext/opcache/jit/ir/ir_emit.c b/ext/opcache/jit/ir/ir_emit.c index ea39830da08c9..83fc242a20c11 100644 --- a/ext/opcache/jit/ir/ir_emit.c +++ b/ext/opcache/jit/ir/ir_emit.c @@ -566,6 +566,9 @@ static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_ if (IR_IS_TYPE_INT(type)) { #ifdef IR_HAVE_SWAP_INT if (pred[from] == to) { + if (ir_type_size[types[to]] > ir_type_size[type]) { + type = types[to]; + } ir_emit_swap(ctx, type, to, from); IR_REGSET_EXCL(todo, from); loc[to] = from; @@ -579,7 +582,7 @@ static int ir_parallel_copy(ir_ctx *ctx, ir_copy *copies, int count, ir_reg tmp_ loc[to] = tmp_reg; } else { #ifdef IR_HAVE_SWAP_FP - if (pred[from] == to) { + if (pred[from] == to && types[to] == type) { ir_emit_swap_fp(ctx, type, to, from); IR_REGSET_EXCL(todo, from); loc[to] = from; From 9bae8933a3f4fee78cdd6c9b2f592ab8d62e9cf1 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 29 Nov 2024 15:06:32 +0100 Subject: [PATCH 4/5] Fix GH-16991: Getting typeinfo of non DISPATCH variant segfaults We must not assume that any `VARIANT` implements `IDispatch`. Closes GH-16992. --- NEWS | 4 ++++ ext/com_dotnet/com_typeinfo.c | 2 +- ext/com_dotnet/tests/gh16991.phpt | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 ext/com_dotnet/tests/gh16991.phpt diff --git a/NEWS b/NEWS index dadbb0241da20..eca09704cfc59 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed jdtogregorian overflow. (David Carlier) . Fixed cal_to_jd julian_days argument overflow. (David Carlier) +- COM: + . Fixed bug GH-16991 (Getting typeinfo of non DISPATCH variant segfaults). + (cmb) + - Core: . Fail early in *nix configuration build script. (hakre) . Fixed bug GH-16727 (Opcache bad signal 139 crash in ZTS bookworm diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index ccdcc3ff7e8c8..e120dc5446989 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -331,7 +331,7 @@ ITypeInfo *php_com_locate_typeinfo(zend_string *type_lib_name, php_com_dotnet_ob if (obj->typeinfo) { ITypeInfo_AddRef(obj->typeinfo); return obj->typeinfo; - } else { + } else if (V_VT(&obj->v) == VT_DISPATCH) { IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo); if (typeinfo) { return typeinfo; diff --git a/ext/com_dotnet/tests/gh16991.phpt b/ext/com_dotnet/tests/gh16991.phpt new file mode 100644 index 0000000000000..3623f1f3c4a63 --- /dev/null +++ b/ext/com_dotnet/tests/gh16991.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-16991 (Getting typeinfo of non DISPATCH variant segfaults) +--EXTENSIONS-- +com_dotnet +--FILE-- + +--EXPECTF-- +Warning: com_print_typeinfo(): Unable to find typeinfo using the parameters supplied in %s on line %d From f8547b1d9733b71c57e3083af80e7395ea5025e6 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Wed, 27 Nov 2024 16:56:54 +0000 Subject: [PATCH 5/5] ext/gmp: Check for valid bit index/start consistently --- ext/gmp/gmp.c | 28 ++++++++++++++-------------- ext/gmp/tests/gmp_clrbit.phpt | 6 +++--- ext/gmp/tests/gmp_scan0.phpt | 4 ++-- ext/gmp/tests/gmp_scan1.phpt | 4 ++-- ext/gmp/tests/gmp_setbit.phpt | 4 ++-- ext/gmp/tests/gmp_setbit_long.phpt | 2 +- ext/gmp/tests/gmp_testbit.phpt | 6 +++--- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index edcc3c46e1301..6d67691aa3e0c 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -1524,6 +1524,10 @@ ZEND_FUNCTION(gmp_random_range) } /* }}} */ +static bool gmp_is_bit_index_valid(zend_long index) { + return index >= 0 && (index / GMP_NUMB_BITS < INT_MAX); +} + /* {{{ Sets or clear bit in a */ ZEND_FUNCTION(gmp_setbit) { @@ -1536,12 +1540,8 @@ ZEND_FUNCTION(gmp_setbit) RETURN_THROWS(); } - if (index < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); - RETURN_THROWS(); - } - if (index / GMP_NUMB_BITS >= INT_MAX) { - zend_argument_value_error(2, "must be less than %d * %d", INT_MAX, GMP_NUMB_BITS); + if (!gmp_is_bit_index_valid(index)) { + zend_argument_value_error(2, "must be between 0 and %d * %d", INT_MAX, GMP_NUMB_BITS); RETURN_THROWS(); } @@ -1566,8 +1566,8 @@ ZEND_FUNCTION(gmp_clrbit) RETURN_THROWS(); } - if (index < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (!gmp_is_bit_index_valid(index)) { + zend_argument_value_error(2, "must be between 0 and %d * %d", INT_MAX, GMP_NUMB_BITS); RETURN_THROWS(); } @@ -1587,8 +1587,8 @@ ZEND_FUNCTION(gmp_testbit) Z_PARAM_LONG(index) ZEND_PARSE_PARAMETERS_END(); - if (index < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (!gmp_is_bit_index_valid(index)) { + zend_argument_value_error(2, "must be between 0 and %d * %d", INT_MAX, GMP_NUMB_BITS); RETURN_THROWS(); } @@ -1634,8 +1634,8 @@ ZEND_FUNCTION(gmp_scan0) Z_PARAM_LONG(start) ZEND_PARSE_PARAMETERS_END(); - if (start < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (!gmp_is_bit_index_valid(start)) { + zend_argument_value_error(2, "must be between 0 and %d * %d", INT_MAX, GMP_NUMB_BITS); RETURN_THROWS(); } @@ -1654,8 +1654,8 @@ ZEND_FUNCTION(gmp_scan1) Z_PARAM_LONG(start) ZEND_PARSE_PARAMETERS_END(); - if (start < 0) { - zend_argument_value_error(2, "must be greater than or equal to 0"); + if (!gmp_is_bit_index_valid(start)) { + zend_argument_value_error(2, "must be between 0 and %d * %d", INT_MAX, GMP_NUMB_BITS); RETURN_THROWS(); } diff --git a/ext/gmp/tests/gmp_clrbit.phpt b/ext/gmp/tests/gmp_clrbit.phpt index 7ed301b9db0dd..afefa740f10eb 100644 --- a/ext/gmp/tests/gmp_clrbit.phpt +++ b/ext/gmp/tests/gmp_clrbit.phpt @@ -44,11 +44,11 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(1) "0" -gmp_clrbit(): Argument #2 ($index) must be greater than or equal to 0 +gmp_clrbit(): Argument #2 ($index) must be between 0 and %d * %d string(2) "-1" -gmp_clrbit(): Argument #2 ($index) must be greater than or equal to 0 +gmp_clrbit(): Argument #2 ($index) must be between 0 and %d * %d string(7) "1000000" string(7) "1000000" string(30) "238462734628347239571822592658" diff --git a/ext/gmp/tests/gmp_scan0.phpt b/ext/gmp/tests/gmp_scan0.phpt index c850b1fe8dd50..3accf37eee10e 100644 --- a/ext/gmp/tests/gmp_scan0.phpt +++ b/ext/gmp/tests/gmp_scan0.phpt @@ -27,8 +27,8 @@ try { echo "Done\n"; ?> ---EXPECT-- -gmp_scan0(): Argument #2 ($start) must be greater than or equal to 0 +--EXPECTF-- +gmp_scan0(): Argument #2 ($start) must be between 0 and %d * %d int(2) int(0) int(5) diff --git a/ext/gmp/tests/gmp_scan1.phpt b/ext/gmp/tests/gmp_scan1.phpt index 04f153a6eb96f..8021f7e679d86 100644 --- a/ext/gmp/tests/gmp_scan1.phpt +++ b/ext/gmp/tests/gmp_scan1.phpt @@ -27,8 +27,8 @@ try { echo "Done\n"; ?> ---EXPECT-- -gmp_scan1(): Argument #2 ($start) must be greater than or equal to 0 +--EXPECTF-- +gmp_scan1(): Argument #2 ($start) must be between 0 and %d * %d int(1) int(12) int(9) diff --git a/ext/gmp/tests/gmp_setbit.phpt b/ext/gmp/tests/gmp_setbit.phpt index b00393faf97b4..70b9e50694823 100644 --- a/ext/gmp/tests/gmp_setbit.phpt +++ b/ext/gmp/tests/gmp_setbit.phpt @@ -50,9 +50,9 @@ try { echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- string(2) "-1" -gmp_setbit(): Argument #2 ($index) must be greater than or equal to 0 +gmp_setbit(): Argument #2 ($index) must be between 0 and %d * %d string(1) "5" string(1) "1" string(1) "7" diff --git a/ext/gmp/tests/gmp_setbit_long.phpt b/ext/gmp/tests/gmp_setbit_long.phpt index 0be0b0e51371b..bbd472de967e6 100644 --- a/ext/gmp/tests/gmp_setbit_long.phpt +++ b/ext/gmp/tests/gmp_setbit_long.phpt @@ -41,5 +41,5 @@ FFFFFFFF 3FFFFFFFF FFFFFFFFF 3FFFFFFFFF -gmp_setbit(): Argument #2 ($index) must be less than %d * %d +gmp_setbit(): Argument #2 ($index) must be between 0 and %d * %d Done diff --git a/ext/gmp/tests/gmp_testbit.phpt b/ext/gmp/tests/gmp_testbit.phpt index b787832f1cdff..1cef8cd4166b2 100644 --- a/ext/gmp/tests/gmp_testbit.phpt +++ b/ext/gmp/tests/gmp_testbit.phpt @@ -47,13 +47,13 @@ var_dump(gmp_strval($n)); echo "Done\n"; ?> ---EXPECT-- -gmp_testbit(): Argument #2 ($index) must be greater than or equal to 0 +--EXPECTF-- +gmp_testbit(): Argument #2 ($index) must be between 0 and %d * %d bool(false) bool(false) bool(false) bool(true) -gmp_testbit(): Argument #2 ($index) must be greater than or equal to 0 +gmp_testbit(): Argument #2 ($index) must be between 0 and %d * %d bool(false) bool(true) string(7) "1000002"