1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix IntlDateFormatter::parseToCalendar() reference type system breaks
  datefmt_parse/datefmt_localtime references type system fixes
  Fix GH-18438: Handling of empty data and errors in ZipArchive::addPattern
This commit is contained in:
Niels Dossche
2025-04-27 11:33:33 +02:00
5 changed files with 132 additions and 16 deletions

View File

@@ -145,9 +145,9 @@ PHP_FUNCTION(datefmt_parse)
DATE_FORMAT_METHOD_FETCH_OBJECT;
if (z_parse_pos) {
zend_long long_parse_pos;
ZVAL_DEREF(z_parse_pos);
long_parse_pos = zval_get_long(z_parse_pos);
zval *z_parse_pos_tmp = z_parse_pos;
ZVAL_DEREF(z_parse_pos_tmp);
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
@@ -160,8 +160,7 @@ PHP_FUNCTION(datefmt_parse)
}
internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos ? &parse_pos : NULL, false, return_value);
if (z_parse_pos) {
zval_ptr_dtor(z_parse_pos);
ZVAL_LONG(z_parse_pos, parse_pos);
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
}
}
/* }}} */
@@ -186,12 +185,12 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
DATE_FORMAT_METHOD_FETCH_OBJECT;
if (z_parse_pos) {
zend_long long_parse_pos;
ZVAL_DEREF(z_parse_pos);
zval *z_parse_pos_tmp = z_parse_pos;
ZVAL_DEREF(z_parse_pos_tmp);
bool failed = false;
long_parse_pos = zval_try_get_long(z_parse_pos, &failed);
zend_long long_parse_pos = zval_try_get_long(z_parse_pos_tmp, &failed);
if (failed) {
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos));
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos_tmp));
RETURN_THROWS();
}
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
@@ -206,8 +205,7 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
}
internal_parse_to_timestamp( dfo, ZSTR_VAL(text_to_parse), ZSTR_LEN(text_to_parse), z_parse_pos ? &parse_pos : NULL, true, return_value);
if (z_parse_pos) {
zval_ptr_dtor(z_parse_pos);
ZVAL_LONG(z_parse_pos, parse_pos);
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
}
}
@@ -231,9 +229,9 @@ PHP_FUNCTION(datefmt_localtime)
DATE_FORMAT_METHOD_FETCH_OBJECT;
if (z_parse_pos) {
zend_long long_parse_pos;
ZVAL_DEREF(z_parse_pos);
long_parse_pos = zval_get_long(z_parse_pos);
zval *z_parse_pos_tmp = z_parse_pos;
ZVAL_DEREF(z_parse_pos_tmp);
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
@@ -246,8 +244,7 @@ PHP_FUNCTION(datefmt_localtime)
}
internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value);
if (z_parse_pos) {
zval_ptr_dtor(z_parse_pos);
ZVAL_LONG(z_parse_pos, parse_pos);
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
}
}
/* }}} */

View File

@@ -0,0 +1,35 @@
--TEST--
datefmt_parse/datefmt_localtime references type system
--EXTENSIONS--
intl
--FILE--
<?php
class Test {
public float $prop = 1.0;
}
$test = new Test;
$offset1 =& $test->prop;
$offset2 =& $test->prop;
$fmt = datefmt_create(
'en_US',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'America/Los_Angeles',
IntlDateFormatter::GREGORIAN
);
datefmt_localtime($fmt, 'Wednesday, December 31, 1969 4:00:00 PM PT', $offset1);
datefmt_parse($fmt, 'Wednesday, December 31, 1969 4:00:00 PM PT', $offset2);
var_dump($offset1, $offset2);
var_dump($test);
?>
--EXPECT--
float(1)
float(1)
object(Test)#1 (1) {
["prop"]=>
&float(1)
}

View File

@@ -0,0 +1,26 @@
--TEST--
IntlDateFormatter::parseToCalendar() reference type system breaks
--EXTENSIONS--
intl
--FILE--
<?php
class Test {
public float $prop = 0.0;
}
$test = new Test;
$offset =& $test->prop;
$oIntlDateFormatter = new IntlDateFormatter("en_GB");
$oIntlDateFormatter->setTimeZone('Europe/Berlin');
$oIntlDateFormatter->setPattern('VV');
var_dump($oIntlDateFormatter->parseToCalendar('America/Los_Angeles', $offset));
var_dump($offset);
var_dump($test);
?>
--EXPECTF--
int(%d)
float(%f)
object(Test)#%d (1) {
["prop"]=>
&float(%f)
}

View File

@@ -760,6 +760,10 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val
re = pcre_get_compiled_regex(regexp, &capture_count);
if (!re) {
for (i = 0; i < files_cnt; i++) {
zend_string_release_ex(namelist[i], 0);
}
efree(namelist);
php_error_docref(NULL, E_WARNING, "Invalid expression");
return -1;
}
@@ -1838,6 +1842,10 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
#endif
}
}
} else if (found == 0) {
RETURN_EMPTY_ARRAY();
} else {
RETURN_FALSE;
}
}
/* }}} */

View File

@@ -0,0 +1,50 @@
--TEST--
GH-18438 (Handling of empty data and errors in ZipArchive::addPattern)
--EXTENSIONS--
zip
--SKIPIF--
<?php
if (PHP_ZTS) die("skip not for ZTS because of path prefixing breaking custom wrapper test");
?>
--FILE--
<?php
class CustomStreamWrapper {
public $context;
function dir_closedir(): bool {
return true;
}
function dir_opendir(string $path, int $options): bool {
return true;
}
function dir_readdir(): string|false {
return false;
}
function dir_rewinddir(): bool {
return false;
}
}
$file = __DIR__ . '/gh18438.zip';
$zip = new ZipArchive;
$zip->open($file, ZIPARCHIVE::CREATE);
var_dump($zip->addPattern('/nomatches/'));
var_dump($zip->addPattern('/invalid'));
stream_wrapper_register('custom', CustomStreamWrapper::class);
var_dump($zip->addPattern('/invalid', 'custom://'));
?>
--CLEAN--
<?php
$file = __DIR__ . '/gh18438.zip';
@unlink($file);
?>
--EXPECTF--
array(0) {
}
Warning: ZipArchive::addPattern(): No ending delimiter '/' found in %s on line %d
Warning: ZipArchive::addPattern(): Invalid expression in %s on line %d
bool(false)
array(0) {
}