Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3fa9e28
Drop unused local variables (GH-17682)
cmb69 Feb 3, 2025
4e6a3ce
Don't forward declare static functions in sendmail.h (GH-17684)
cmb69 Feb 3, 2025
f88445b
Fix GH-17654: Multiple classes using same trait causes function JIT c…
ndossche Jan 31, 2025
6d6380c
Merge branch 'PHP-8.3' into PHP-8.4
ndossche Feb 3, 2025
9b7e086
Merge branch 'PHP-8.4'
ndossche Feb 3, 2025
0c3cf1f
Fix GH-17577: JIT packed type guard crash
ndossche Jan 26, 2025
78da288
Merge branch 'PHP-8.3' into PHP-8.4
ndossche Feb 3, 2025
1879ec1
Merge branch 'PHP-8.4'
ndossche Feb 3, 2025
4373c60
Remove more unused local variables (GH-17688)
cmb69 Feb 3, 2025
c1f7b87
Fix MSVC C4267 warnings in gd.c (GH-17680)
cmb69 Feb 3, 2025
7e06a81
Fix fallback paths in fast_long_{add,sub}_function
ndossche Feb 1, 2025
c7d3c5f
Merge branch 'PHP-8.3' into PHP-8.4
ndossche Feb 3, 2025
9040e79
Merge branch 'PHP-8.4'
ndossche Feb 3, 2025
481bafe
ext/pdo: Add static modifier for PDORow object handlers
Girgias Jan 30, 2025
9054a8f
ext/pdo: Add test for lazy fetch mode
Girgias Jan 30, 2025
4fcbdea
ext/pdo: Turn lazy_object_ref into a zend_object* from a zval
Girgias Jan 30, 2025
d8aedb5
[skip ci] Another flaky phar macOS test
iluuu1994 Feb 4, 2025
99d2055
Merge branch 'PHP-8.1' into PHP-8.2
iluuu1994 Feb 4, 2025
88e1917
Merge branch 'PHP-8.2' into PHP-8.3
iluuu1994 Feb 4, 2025
d3101fb
Merge branch 'PHP-8.3' into PHP-8.4
iluuu1994 Feb 4, 2025
7ee1a87
Merge branch 'PHP-8.4'
iluuu1994 Feb 4, 2025
55e676e
Fix GH-17503: Undefined float conversion in mb_convert_variables
cmb69 Feb 4, 2025
47a0922
Merge branch 'PHP-8.3' into PHP-8.4
cmb69 Feb 4, 2025
61f42f2
Merge branch 'PHP-8.4'
cmb69 Feb 4, 2025
598f982
ext/pdo: Add const modifiers to pdo_get_TYPE_param() functions
Girgias Feb 4, 2025
b6febd1
ext/pdo: Revome useless ext/standard header include
Girgias Feb 4, 2025
790286a
ext/pdo: Pass argument number to pdo_dbh_attribute_set()
Girgias Feb 4, 2025
dc7161c
UPGRADING: fix some typos [skip ci] (#17701)
DanielEScherzer Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TSRM/tsrm_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
shm_pair *shm;
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
HANDLE shm_handle = NULL, info_handle = NULL;
HANDLE shm_handle = NULL;
BOOL created = FALSE;

if (key != IPC_PRIVATE) {
Expand Down
4 changes: 2 additions & 2 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ PHP 8.5 UPGRADE NOTES

- Session:
. session_start is stricter in regard of the option argument.
it throws a ValueError if the whole is not a hashmap or
It throws a ValueError if the whole is not a hashmap or
a TypeError if read_on_close value is not a valid type
compatible with int.

Expand All @@ -170,7 +170,7 @@ PHP 8.5 UPGRADE NOTES
. socket_create_listen, socket_bind and socket_sendto throw a
ValueError if the port is lower than 0 or greater than 65535,
also if any of the hints array entry is indexes numerically.
. socket_addrinfo_lookup throw a TypeError if any of the hints
. socket_addrinfo_lookup throws a TypeError if any of the hints
values cannot be cast to a int and can throw a ValueError if
any of these values overflow.
. socket_set_option with MCAST_LEAVE_GROUP/MCAST_LEAVE_SOURCE_GROUP
Expand Down
18 changes: 14 additions & 4 deletions Zend/zend_operators.h
Original file line number Diff line number Diff line change
Expand Up @@ -777,11 +777,13 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
* have read the values of op1 and op2.
*/

zend_long sum = (zend_long) ((zend_ulong) Z_LVAL_P(op1) + (zend_ulong) Z_LVAL_P(op2));

if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (sum & LONG_SIGN_MASK))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
ZVAL_LONG(result, sum);
}
#endif
}
Expand Down Expand Up @@ -873,11 +875,19 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
ZVAL_LONG(result, llresult);
}
#else
ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
/*
* 'result' may alias with op1 or op2, so we need to
* ensure that 'result' is not updated until after we
* have read the values of op1 and op2.
*/

zend_long sub = (zend_long) ((zend_ulong) Z_LVAL_P(op1) - (zend_ulong) Z_LVAL_P(op2));

if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (sub & LONG_SIGN_MASK))) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, sub);
}
#endif
}
Expand Down
1 change: 0 additions & 1 deletion ext/com_dotnet/com_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ static void function_dtor(zval *zv)
static PHP_FUNCTION(com_method_handler)
{
zval *object = getThis();
zend_string *method = EX(func)->common.function_name;
zval *args = NULL;
php_com_dotnet_object *obj = CDNO_FETCH(object);
int nargs;
Expand Down
28 changes: 21 additions & 7 deletions ext/gd/gd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1409,7 +1409,8 @@ gdImagePtr _php_image_create_from_string(zend_string *data, const char *tn, gdIm
gdImagePtr im;
gdIOCtx *io_ctx;

io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(data), ZSTR_VAL(data), 0);
ZEND_ASSERT(ZSTR_LEN(data) <= INT_MAX); /* checked in imagecreatefromstring() */
io_ctx = gdNewDynamicCtxEx((int) ZSTR_LEN(data), ZSTR_VAL(data), 0);

if (!io_ctx) {
return NULL;
Expand Down Expand Up @@ -1439,6 +1440,10 @@ PHP_FUNCTION(imagecreatefromstring)
Z_PARAM_STR(data)
ZEND_PARSE_PARAMETERS_END();

if (ZSTR_LEN(data) > INT_MAX) {
zend_argument_value_error(1, "is too long");
}

imtype = _php_image_type(data);

switch (imtype) {
Expand Down Expand Up @@ -1562,17 +1567,23 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
buff = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);

if (!buff) {
php_error_docref(NULL, E_WARNING,"Cannot read image data");
php_error_docref(NULL, E_WARNING, "Cannot read image data");
goto out_err;
}

if (ZSTR_LEN(buff) > INT_MAX) {
zend_string_release_ex(buff, 0);
php_error_docref(NULL, E_WARNING, "Cannot read images with more than %d bytes", INT_MAX);
goto out_err;
}

/* needs to be malloc (persistent) - GD will free() it later */
pstr = pestrndup(ZSTR_VAL(buff), ZSTR_LEN(buff), 1);
io_ctx = gdNewDynamicCtxEx(ZSTR_LEN(buff), pstr, 0);
io_ctx = gdNewDynamicCtxEx((int) ZSTR_LEN(buff), pstr, 0);
if (!io_ctx) {
pefree(pstr, 1);
zend_string_release_ex(buff, 0);
php_error_docref(NULL, E_WARNING,"Cannot allocate GD IO context");
php_error_docref(NULL, E_WARNING, "Cannot allocate GD IO context");
goto out_err;
}

Expand Down Expand Up @@ -1796,7 +1807,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, cons
fflush(fp);
fclose(fp);
} else {
int b;
size_t b;
FILE *tmp;
char buf[4096];
zend_string *path;
Expand Down Expand Up @@ -2983,7 +2994,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
zend_long X, Y, COL;
zend_string *C;
gdImagePtr im;
int ch = 0, col, x, y, i, l = 0;
int ch = 0, col, x, y, i;
size_t l = 0;
unsigned char *str = NULL;
zend_object *font_obj = NULL;
zend_long font_int = 0;
Expand Down Expand Up @@ -4337,7 +4349,9 @@ static void _php_image_output_putc(struct gdIOCtx *ctx, int c) /* {{{ */

static int _php_image_output_putbuf(struct gdIOCtx *ctx, const void* buf, int l) /* {{{ */
{
return php_write((void *)buf, l);
size_t written = php_write((void *)buf, l);
ZEND_ASSERT(written <= INT_MAX); /* since l <= INT_MAX */
return (int) written;
} /* }}} */

static void _php_image_output_ctxfree(struct gdIOCtx *ctx) /* {{{ */
Expand Down
3 changes: 2 additions & 1 deletion ext/mbstring/mbstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -3348,7 +3348,8 @@ try_next_encoding:;
}

for (size_t i = 0; i < length; i++) {
array[i].demerits = (uint64_t) (array[i].demerits * array[i].multiplier);
double demerits = array[i].demerits * (double) array[i].multiplier;
array[i].demerits = demerits < (double) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX;
}

return length;
Expand Down
11 changes: 11 additions & 0 deletions ext/mbstring/tests/gh17503.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--TEST--
GH-17503 (Undefined float conversion in mb_convert_variables)
--EXTENSIONS--
mbstring
--FILE--
<?php
$a = array_fill(0, 500, "<blah>");
var_dump(mb_convert_variables("ASCII", ["UTF-8", "UTF-16"], $a));
?>
--EXPECT--
string(5) "UTF-8"
6 changes: 3 additions & 3 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -10053,9 +10053,9 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
func = call_info->callee_func;
}
if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)
&& JIT_G(current_frame)
&& JIT_G(current_frame)->call
&& !JIT_G(current_frame)->call->func) {
&& (!JIT_G(current_frame)
|| !JIT_G(current_frame)->call
|| !JIT_G(current_frame)->call->func)) {
call_info = NULL; func = NULL; /* megamorphic call from trait */
}
}
Expand Down
20 changes: 14 additions & 6 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1872,7 +1872,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
if (!(orig_op1_type & IS_TRACE_PACKED)) {
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];

if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
info->type |= MAY_BE_PACKED_GUARD;
info->type &= ~MAY_BE_ARRAY_PACKED;
}
Expand All @@ -1881,7 +1882,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
&& val_type != IS_UNDEF) {
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];

if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
info->type |= MAY_BE_PACKED_GUARD;
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
}
Expand Down Expand Up @@ -1965,7 +1967,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin

zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];

if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
info->type |= MAY_BE_PACKED_GUARD;
if (orig_op1_type & IS_TRACE_PACKED) {
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
Expand Down Expand Up @@ -2067,7 +2070,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin

zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];

if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
info->type |= MAY_BE_PACKED_GUARD;
if (orig_op1_type & IS_TRACE_PACKED) {
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
Expand Down Expand Up @@ -2097,7 +2101,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin

zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];

if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
info->type |= MAY_BE_PACKED_GUARD;
info->type &= ~MAY_BE_ARRAY_PACKED;
}
Expand Down Expand Up @@ -4236,10 +4241,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
if ((info & MAY_BE_PACKED_GUARD) != 0
&& (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LOOP
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET)
|| (trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET
&& EX_VAR_TO_NUM((opline-1)->result.var) == i))
&& (ssa->vars[i].use_chain != -1
|| (ssa->vars[i].phi_use_chain
&& !(ssa->var_info[ssa->vars[i].phi_use_chain->ssa_var].type & MAY_BE_PACKED_GUARD)))) {
ZEND_ASSERT(STACK_TYPE(stack, i) == IS_ARRAY);

if (!zend_jit_packed_guard(&ctx, opline, EX_NUM_TO_VAR(i), info)) {
goto jit_failure;
}
Expand Down
27 changes: 27 additions & 0 deletions ext/opcache/tests/jit/gh17577.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
--TEST--
GH-17577 (JIT packed type guard crash)
--EXTENSIONS--
opcache
--INI--
opcache.jit_buffer_size=16M
opcache.jit_hot_func=1
--FILE--
<?php
$a = array(
array(1,2,3),
0,
);
function my_dump($var) {
}
foreach($a as $b) {
for ($i = 0; $i < 3; $i++) {
my_dump($b[$i]);
}
}
?>
--EXPECTF--
Warning: Trying to access array offset on int in %s on line %d

Warning: Trying to access array offset on int in %s on line %d

Warning: Trying to access array offset on int in %s on line %d
38 changes: 38 additions & 0 deletions ext/opcache/tests/jit/gh17654.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
GH-17654 (Multiple classes using same trait causes function JIT crash)
--EXTENSIONS--
opcache
--INI--
opcache.jit=1214
opcache.jit_buffer_size=16M
--FILE--
<?php
trait TestTrait {
public function addUnit(string $x) {
self::addRawUnit($this, $x);
}

public function addRawUnit(self $data, string $x) {
var_dump($x);
}
}

class Test {
use TestTrait;
}

class Test2 {
use TestTrait;
}

function main()
{
(new Test2)->addUnit("test2");
(new Test)->addUnit("test");
}

main();
?>
--EXPECT--
string(5) "test2"
string(4) "test"
Loading