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 ^ 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 diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index 4f6a3309b8cd5..28306b5609b08 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 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" 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;