Skip to content

Commit 5f97728

Browse files
committed
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
2 parents 1ec9041 + 173dccb commit 5f97728

File tree

5 files changed

+132
-16
lines changed

5 files changed

+132
-16
lines changed

ext/intl/dateformat/dateformat_parse.c

+13-16
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ PHP_FUNCTION(datefmt_parse)
145145
DATE_FORMAT_METHOD_FETCH_OBJECT;
146146

147147
if (z_parse_pos) {
148-
zend_long long_parse_pos;
149-
ZVAL_DEREF(z_parse_pos);
150-
long_parse_pos = zval_get_long(z_parse_pos);
148+
zval *z_parse_pos_tmp = z_parse_pos;
149+
ZVAL_DEREF(z_parse_pos_tmp);
150+
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
151151
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
152152
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
153153
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
@@ -160,8 +160,7 @@ PHP_FUNCTION(datefmt_parse)
160160
}
161161
internal_parse_to_timestamp( dfo, text_to_parse, text_len, z_parse_pos ? &parse_pos : NULL, false, return_value);
162162
if (z_parse_pos) {
163-
zval_ptr_dtor(z_parse_pos);
164-
ZVAL_LONG(z_parse_pos, parse_pos);
163+
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
165164
}
166165
}
167166
/* }}} */
@@ -186,12 +185,12 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
186185
DATE_FORMAT_METHOD_FETCH_OBJECT;
187186

188187
if (z_parse_pos) {
189-
zend_long long_parse_pos;
190-
ZVAL_DEREF(z_parse_pos);
188+
zval *z_parse_pos_tmp = z_parse_pos;
189+
ZVAL_DEREF(z_parse_pos_tmp);
191190
bool failed = false;
192-
long_parse_pos = zval_try_get_long(z_parse_pos, &failed);
191+
zend_long long_parse_pos = zval_try_get_long(z_parse_pos_tmp, &failed);
193192
if (failed) {
194-
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos));
193+
zend_argument_type_error(2, "must be of type int, %s given", zend_zval_value_name(z_parse_pos_tmp));
195194
RETURN_THROWS();
196195
}
197196
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
@@ -206,8 +205,7 @@ PHP_METHOD(IntlDateFormatter, parseToCalendar)
206205
}
207206
internal_parse_to_timestamp( dfo, ZSTR_VAL(text_to_parse), ZSTR_LEN(text_to_parse), z_parse_pos ? &parse_pos : NULL, true, return_value);
208207
if (z_parse_pos) {
209-
zval_ptr_dtor(z_parse_pos);
210-
ZVAL_LONG(z_parse_pos, parse_pos);
208+
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
211209
}
212210
}
213211

@@ -231,9 +229,9 @@ PHP_FUNCTION(datefmt_localtime)
231229
DATE_FORMAT_METHOD_FETCH_OBJECT;
232230

233231
if (z_parse_pos) {
234-
zend_long long_parse_pos;
235-
ZVAL_DEREF(z_parse_pos);
236-
long_parse_pos = zval_get_long(z_parse_pos);
232+
zval *z_parse_pos_tmp = z_parse_pos;
233+
ZVAL_DEREF(z_parse_pos_tmp);
234+
zend_long long_parse_pos = zval_get_long(z_parse_pos_tmp);
237235
if (ZEND_LONG_INT_OVFL(long_parse_pos)) {
238236
intl_error_set_code(NULL, U_ILLEGAL_ARGUMENT_ERROR);
239237
intl_error_set_custom_msg(NULL, "String index is out of valid range.", 0);
@@ -246,8 +244,7 @@ PHP_FUNCTION(datefmt_localtime)
246244
}
247245
internal_parse_to_localtime( dfo, text_to_parse, text_len, z_parse_pos?&parse_pos:NULL, return_value);
248246
if (z_parse_pos) {
249-
zval_ptr_dtor(z_parse_pos);
250-
ZVAL_LONG(z_parse_pos, parse_pos);
247+
ZEND_TRY_ASSIGN_REF_LONG(z_parse_pos, parse_pos);
251248
}
252249
}
253250
/* }}} */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
datefmt_parse/datefmt_localtime references type system
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
8+
class Test {
9+
public float $prop = 1.0;
10+
}
11+
12+
$test = new Test;
13+
$offset1 =& $test->prop;
14+
$offset2 =& $test->prop;
15+
16+
$fmt = datefmt_create(
17+
'en_US',
18+
IntlDateFormatter::FULL,
19+
IntlDateFormatter::FULL,
20+
'America/Los_Angeles',
21+
IntlDateFormatter::GREGORIAN
22+
);
23+
datefmt_localtime($fmt, 'Wednesday, December 31, 1969 4:00:00 PM PT', $offset1);
24+
datefmt_parse($fmt, 'Wednesday, December 31, 1969 4:00:00 PM PT', $offset2);
25+
var_dump($offset1, $offset2);
26+
var_dump($test);
27+
28+
?>
29+
--EXPECT--
30+
float(1)
31+
float(1)
32+
object(Test)#1 (1) {
33+
["prop"]=>
34+
&float(1)
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
IntlDateFormatter::parseToCalendar() reference type system breaks
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
class Test {
8+
public float $prop = 0.0;
9+
}
10+
$test = new Test;
11+
$offset =& $test->prop;
12+
13+
$oIntlDateFormatter = new IntlDateFormatter("en_GB");
14+
$oIntlDateFormatter->setTimeZone('Europe/Berlin');
15+
$oIntlDateFormatter->setPattern('VV');
16+
var_dump($oIntlDateFormatter->parseToCalendar('America/Los_Angeles', $offset));
17+
var_dump($offset);
18+
var_dump($test);
19+
?>
20+
--EXPECTF--
21+
int(%d)
22+
float(%f)
23+
object(Test)#%d (1) {
24+
["prop"]=>
25+
&float(%f)
26+
}

ext/zip/php_zip.c

+8
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,10 @@ int php_zip_pcre(zend_string *regexp, char *path, int path_len, zval *return_val
760760

761761
re = pcre_get_compiled_regex(regexp, &capture_count);
762762
if (!re) {
763+
for (i = 0; i < files_cnt; i++) {
764+
zend_string_release_ex(namelist[i], 0);
765+
}
766+
efree(namelist);
763767
php_error_docref(NULL, E_WARNING, "Invalid expression");
764768
return -1;
765769
}
@@ -1838,6 +1842,10 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
18381842
#endif
18391843
}
18401844
}
1845+
} else if (found == 0) {
1846+
RETURN_EMPTY_ARRAY();
1847+
} else {
1848+
RETURN_FALSE;
18411849
}
18421850
}
18431851
/* }}} */

ext/zip/tests/gh18438.phpt

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
GH-18438 (Handling of empty data and errors in ZipArchive::addPattern)
3+
--EXTENSIONS--
4+
zip
5+
--SKIPIF--
6+
<?php
7+
if (PHP_ZTS) die("skip not for ZTS because of path prefixing breaking custom wrapper test");
8+
?>
9+
--FILE--
10+
<?php
11+
class CustomStreamWrapper {
12+
public $context;
13+
function dir_closedir(): bool {
14+
return true;
15+
}
16+
function dir_opendir(string $path, int $options): bool {
17+
return true;
18+
}
19+
function dir_readdir(): string|false {
20+
return false;
21+
}
22+
function dir_rewinddir(): bool {
23+
return false;
24+
}
25+
}
26+
27+
$file = __DIR__ . '/gh18438.zip';
28+
$zip = new ZipArchive;
29+
$zip->open($file, ZIPARCHIVE::CREATE);
30+
var_dump($zip->addPattern('/nomatches/'));
31+
var_dump($zip->addPattern('/invalid'));
32+
33+
stream_wrapper_register('custom', CustomStreamWrapper::class);
34+
var_dump($zip->addPattern('/invalid', 'custom://'));
35+
?>
36+
--CLEAN--
37+
<?php
38+
$file = __DIR__ . '/gh18438.zip';
39+
@unlink($file);
40+
?>
41+
--EXPECTF--
42+
array(0) {
43+
}
44+
45+
Warning: ZipArchive::addPattern(): No ending delimiter '/' found in %s on line %d
46+
47+
Warning: ZipArchive::addPattern(): Invalid expression in %s on line %d
48+
bool(false)
49+
array(0) {
50+
}

0 commit comments

Comments
 (0)