From dcac024bb0857d97091b1d0e9fb16c9cb41cd505 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:21:24 -0800 Subject: [PATCH 1/4] spl: Avoid pointless copies for internal construction calls (#20610) --- ext/spl/spl_directory.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 5ef7540f822d..ad6fc54aeb3e 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -480,9 +480,8 @@ static spl_filesystem_object *spl_filesystem_object_create_info(zend_string *fil RETVAL_OBJ(&intern->std); if (ce->constructor->common.scope != spl_ce_SplFileInfo) { - ZVAL_STR_COPY(&arg1, file_path); + ZVAL_STR(&arg1, file_path); zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1); - zval_ptr_dtor(&arg1); } else { spl_filesystem_info_set_filename(intern, file_path); } @@ -520,9 +519,8 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp } if (ce->constructor->common.scope != spl_ce_SplFileInfo) { - ZVAL_STR_COPY(&arg1, source->file_name); + ZVAL_STR(&arg1, source->file_name); zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1); - zval_ptr_dtor(&arg1); } else { intern->file_name = zend_string_copy(source->file_name); intern->path = spl_filesystem_object_get_path(source); @@ -549,11 +547,9 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp } if (ce->constructor->common.scope != spl_ce_SplFileObject) { - ZVAL_STR_COPY(&arg1, source->file_name); - ZVAL_STR_COPY(&arg2, open_mode); + ZVAL_STR(&arg1, source->file_name); + ZVAL_STR(&arg2, open_mode); zend_call_method_with_2_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1, &arg2); - zval_ptr_dtor(&arg1); - zval_ptr_dtor(&arg2); } else { intern->file_name = source->file_name; intern->path = spl_filesystem_object_get_path(source); From 5ae1261c6f8ff2738ab0e9262da0d17cf440e3e7 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:21:33 -0800 Subject: [PATCH 2/4] phar: Remove dead store (#20611) This is overwritten later anyway by contents_len. --- ext/phar/phar_object.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index acd9aa0cff65..11a0dd17a4e5 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1622,8 +1622,6 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ data->internal_file->offset_abs = data->internal_file->offset = php_stream_tell(p_obj->fp); data->fp = NULL; php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); - data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize = - php_stream_tell(p_obj->fp) - data->internal_file->offset; if (php_stream_stat(fp, &ssb) != -1) { data->internal_file->flags = ssb.sb.st_mode & PHAR_ENT_PERM_MASK ; } else { From c8e13af4558659ba91cec07e502733e127dcb1ce Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 28 Nov 2025 12:40:33 +0000 Subject: [PATCH 3/4] Fix GH-20602: imagescale() overflow with large height values. close GH-20605 --- NEWS | 2 ++ ext/gd/gd.c | 8 ++++++++ ext/gd/tests/gh20602.phpt | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 ext/gd/tests/gh20602.phpt diff --git a/NEWS b/NEWS index 863d672d736d..214f1105b5c2 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,8 @@ PHP NEWS - GD: . Fixed bug GH-20511 (imagegammacorrect out of range input/output values). (David Carlier) + . Fixed bug GH-20602 (imagescale overflow with large height values). + (David Carlier) - LibXML: . Fix some deprecations on newer libxml versions regarding input diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 558d0764d666..925d64f01c5e 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -3689,9 +3689,17 @@ PHP_FUNCTION(imagescale) src_y = gdImageSY(im); if (src_x && tmp_h < 0) { + if (tmp_w > (ZEND_LONG_MAX / src_y)) { + zend_argument_value_error(2, "must be less than or equal to " ZEND_LONG_FMT, (zend_long)(ZEND_LONG_MAX / src_y)); + RETURN_THROWS(); + } tmp_h = tmp_w * src_y / src_x; } if (src_y && tmp_w < 0) { + if (tmp_h > (ZEND_LONG_MAX / src_x)) { + zend_argument_value_error(3, "must be less than or equal to " ZEND_LONG_FMT, (zend_long)(ZEND_LONG_MAX / src_x)); + RETURN_THROWS(); + } tmp_w = tmp_h * src_x / src_y; } } diff --git a/ext/gd/tests/gh20602.phpt b/ext/gd/tests/gh20602.phpt new file mode 100644 index 000000000000..29c781e76a2d --- /dev/null +++ b/ext/gd/tests/gh20602.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-20551: (imagegammacorrect out of range input/output value) +--EXTENSIONS-- +gd +--FILE-- +getMessage(), PHP_EOL; +} +try { + imagescale($im, -1, PHP_INT_MAX); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +imagescale(): Argument #2 ($width) must be less than or equal to %d +imagescale(): Argument #3 ($height) must be less than or equal to %d From 927830da8668d58422b3d16645b3dcce160cd233 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+ndossche@users.noreply.github.com> Date: Sat, 29 Nov 2025 05:36:59 -0800 Subject: [PATCH 4/4] phar: Remove unused min_timestamp field (#20617) --- ext/phar/phar.c | 10 ++-------- ext/phar/phar_internal.h | 1 - 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 23624ce6bcc7..30c3b371e6bb 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -1149,15 +1149,9 @@ static zend_result phar_parse_pharfile(php_stream *fp, char *fname, size_t fname PHAR_GET_32(buffer, entry.uncompressed_filesize); PHAR_GET_32(buffer, entry.timestamp); - if (offset == halt_offset + manifest_len + 4) { - mydata->min_timestamp = entry.timestamp; + if (offset == halt_offset + manifest_len + 4 + || mydata->max_timestamp < entry.timestamp) { mydata->max_timestamp = entry.timestamp; - } else { - if (mydata->min_timestamp > entry.timestamp) { - mydata->min_timestamp = entry.timestamp; - } else if (mydata->max_timestamp < entry.timestamp) { - mydata->max_timestamp = entry.timestamp; - } } PHAR_GET_32(buffer, entry.compressed_filesize); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 46e45ec61b72..5fc435454531 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -258,7 +258,6 @@ struct _phar_archive_data { /* hash of mounted directory paths */ HashTable mounted_dirs; uint32_t flags; - uint32_t min_timestamp; uint32_t max_timestamp; int refcount; php_stream *fp;