Skip to content

Commit 9ca3626

Browse files
committed
Fix ext/standard
1 parent 777303f commit 9ca3626

File tree

10 files changed

+88
-44
lines changed

10 files changed

+88
-44
lines changed

ext/standard/file.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,12 @@ PHP_FUNCTION(file_put_contents)
498498
if (php_stream_copy_to_stream_ex(srcstream, stream, PHP_STREAM_COPY_ALL, &len) != SUCCESS) {
499499
numbytes = -1;
500500
} else {
501+
#if SIZEOF_SIZE_T >= SIZEOF_ZEND_LONG
501502
if (len > ZEND_LONG_MAX) {
502503
php_error_docref(NULL, E_WARNING, "content truncated from %zu to " ZEND_LONG_FMT " bytes", len, ZEND_LONG_MAX);
503504
len = ZEND_LONG_MAX;
504505
}
506+
#endif
505507
numbytes = len;
506508
}
507509
break;

ext/standard/formatted_print.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ php_sprintf_appendstring(zend_string **buffer, size_t *pos, char *add,
103103
if (req_size > ZSTR_LEN(*buffer)) {
104104
size_t size = ZSTR_LEN(*buffer);
105105
while (req_size > size) {
106-
if (size > ZEND_SIZE_MAX/2) {
106+
if (size > SIZE_MAX/2) {
107107
zend_error_noreturn(E_ERROR, "Field width %zd is too long", req_size);
108108
}
109109
size <<= 1;

ext/standard/head.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ PHPAPI bool php_header(void)
7777
}
7878

7979
#define ILLEGAL_COOKIE_CHARACTER "\",\", \";\", \" \", \"\\t\", \"\\r\", \"\\n\", \"\\013\", or \"\\014\""
80-
PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires,
80+
PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, zend_long expires,
8181
zend_string *path, zend_string *domain, bool secure, bool httponly,
8282
zend_string *samesite, bool url_encode)
8383
{
@@ -110,7 +110,8 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e
110110
get_active_function_name());
111111
return FAILURE;
112112
}
113-
#ifdef ZEND_ENABLE_ZVAL_LONG64
113+
114+
#if SIZEOF_ZEND_LONG >= 8
114115
if (expires >= 253402300800) {
115116
zend_value_error("%s(): \"expires\" option cannot have a year greater than 9999",
116117
get_active_function_name());

ext/standard/head.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
extern PHP_RINIT_FUNCTION(head);
2929

3030
PHPAPI bool php_header(void);
31-
PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t expires,
31+
PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, zend_long expires,
3232
zend_string *path, zend_string *domain, bool secure, bool httponly,
3333
zend_string *samesite, bool url_encode);
3434

ext/standard/math.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,8 +1225,8 @@ PHPAPI zend_string *_php_math_number_format_long(zend_long num, zend_long dec, c
12251225
1, 10, 100, 1000, 10000,
12261226
100000, 1000000, 10000000, 100000000, 1000000000,
12271227
#if SIZEOF_ZEND_LONG == 8
1228-
10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000,
1229-
1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000ul
1228+
Z_UL(10000000000), Z_UL(100000000000), Z_UL(1000000000000), Z_UL(10000000000000), Z_UL(100000000000000),
1229+
Z_UL(1000000000000000), Z_UL(10000000000000000), Z_UL(100000000000000000), Z_UL(1000000000000000000), Z_UL(10000000000000000000)
12301230
#elif SIZEOF_ZEND_LONG > 8
12311231
# error "Unknown SIZEOF_ZEND_LONG"
12321232
#endif
@@ -1256,7 +1256,7 @@ PHPAPI zend_string *_php_math_number_format_long(zend_long num, zend_long dec, c
12561256
// rounding the number
12571257
if (dec < 0) {
12581258
// Check rounding to more negative places than possible
1259-
if (dec < -(sizeof(powers) / sizeof(powers[0]) - 1)) {
1259+
if (dec < -(zend_long)(sizeof(powers) / sizeof(powers[0]) - 1)) {
12601260
tmpnum = 0;
12611261
} else {
12621262
power = powers[-dec];

ext/standard/string.c

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2225,27 +2225,39 @@ static inline void _zend_substr(zval *return_value, zend_string *str, zend_long
22252225
/* if "from" position is negative, count start position from the end
22262226
* of the string
22272227
*/
2228-
if (-(size_t)f > ZSTR_LEN(str)) {
2228+
f = (zend_long)ZSTR_LEN(str) + f;
2229+
if (f < 0) {
22292230
f = 0;
2230-
} else {
2231-
f = (zend_long)ZSTR_LEN(str) + f;
22322231
}
2233-
} else if ((size_t)f > ZSTR_LEN(str)) {
2234-
RETURN_EMPTY_STRING();
2232+
} else {
2233+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2234+
if (UNEXPECTED(f > SIZE_MAX)) {
2235+
f = SIZE_MAX;
2236+
}
2237+
#endif
2238+
if ((size_t)f > ZSTR_LEN(str)) {
2239+
RETURN_EMPTY_STRING();
2240+
}
22352241
}
22362242

22372243
if (!len_is_null) {
22382244
if (l < 0) {
22392245
/* if "length" position is negative, set it to the length
22402246
* needed to stop that many chars from the end of the string
22412247
*/
2242-
if (-(size_t)l > ZSTR_LEN(str) - (size_t)f) {
2248+
l = (zend_long)ZSTR_LEN(str) - f + l;
2249+
if (l < 0) {
22432250
l = 0;
2244-
} else {
2245-
l = (zend_long)ZSTR_LEN(str) - f + l;
22462251
}
2247-
} else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
2248-
l = (zend_long)ZSTR_LEN(str) - f;
2252+
} else {
2253+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2254+
if (UNEXPECTED(l > SIZE_MAX)) {
2255+
l = SIZE_MAX;
2256+
}
2257+
#endif
2258+
if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
2259+
l = (zend_long)ZSTR_LEN(str) - f;
2260+
}
22492261
}
22502262
} else {
22512263
l = (zend_long)ZSTR_LEN(str) - f;
@@ -2360,8 +2372,15 @@ PHP_FUNCTION(substr_replace)
23602372
if (f < 0) {
23612373
f = 0;
23622374
}
2363-
} else if ((size_t)f > ZSTR_LEN(str)) {
2364-
f = ZSTR_LEN(str);
2375+
} else {
2376+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2377+
if (UNEXPECTED(f > SIZE_MAX)) {
2378+
f = SIZE_MAX;
2379+
}
2380+
#endif
2381+
if ((size_t)f > ZSTR_LEN(str)) {
2382+
f = ZSTR_LEN(str);
2383+
}
23652384
}
23662385
/* if "length" position is negative, set it to the length
23672386
* needed to stop that many chars from the end of the string
@@ -2373,6 +2392,12 @@ PHP_FUNCTION(substr_replace)
23732392
}
23742393
}
23752394

2395+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2396+
if (UNEXPECTED(l > SIZE_MAX)) {
2397+
l = SIZE_MAX;
2398+
}
2399+
#endif
2400+
23762401
if ((size_t)l > ZSTR_LEN(str)) {
23772402
l = ZSTR_LEN(str);
23782403
}
@@ -2522,6 +2547,12 @@ PHP_FUNCTION(substr_replace)
25222547
}
25232548
}
25242549

2550+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
2551+
if (UNEXPECTED(l > SIZE_MAX)) {
2552+
l = SIZE_MAX;
2553+
}
2554+
#endif
2555+
25252556
ZEND_ASSERT(0 <= f && f <= ZEND_LONG_MAX);
25262557
ZEND_ASSERT(0 <= l && l <= ZEND_LONG_MAX);
25272558
if (((size_t) f + l) > ZSTR_LEN(orig_str)) {
@@ -5756,6 +5787,13 @@ PHP_FUNCTION(str_pad)
57565787
Z_PARAM_LONG(pad_type_val)
57575788
ZEND_PARSE_PARAMETERS_END();
57585789

5790+
#if SIZEOF_SIZE_T < SIZEOF_ZEND_LONG
5791+
if (pad_length > SIZE_MAX/2) {
5792+
zend_argument_value_error(2, "must be lower or equal to %zd", SIZE_MAX/2);
5793+
RETURN_THROWS();
5794+
}
5795+
#endif
5796+
57595797
/* If resulting string turns out to be shorter than input string,
57605798
we simply copy the input and return. */
57615799
if (pad_length < 0 || (size_t)pad_length <= ZSTR_LEN(input)) {

ext/standard/tests/strings/gh15613.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
GH-15613 overflow on hex strings repeater value
33
--SKIPIF--
44
<?php
5-
if (PHP_INT_SIZE != 8) die("skip this test is for 64 bit platform only");
5+
if (PHP_SYS_SIZE != 8) die("skip this test is for 64 bit platform only");
66
?>
77
--INI--
88
memory_limit=-1

ext/standard/tests/strings/sprintf_rope_optimization_004.phpt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,24 @@ gmp
77

88
$a = new GMP("42");
99
$b = new GMP("-1337");
10-
$c = new GMP("999999999999999999999999999999999");
10+
$c = new GMP((string)PHP_INT_MAX);
11+
$d = new GMP((string)PHP_INT_MIN);
12+
$e = new GMP("999999999999999999999999999999999");
1113

1214
try {
1315
if (PHP_INT_SIZE == 8) {
14-
var_dump(sprintf("%d/%d/%d/%s", $a, $b, $c, $c + 1));
15-
var_dump("42/-1337/2147483647/1000000000000000000000000000000000");
16+
var_dump(sprintf("%d/%d/%d/%d/%d/%s", $a, $b, $c, $d, $e, $e + 1));
17+
var_dump("42/-1337/2147483647/-2147483648/2147483647/1000000000000000000000000000000000");
1618
} else {
17-
var_dump("42/-1337/4089650035136921599/1000000000000000000000000000000000");
18-
var_dump(sprintf("%d/%d/%d/%s", $a, $b, $c, $c + 1));
19+
var_dump("42/-1337/9223372036854775807/-9223372036854775808/4089650035136921599/1000000000000000000000000000000000");
20+
var_dump(sprintf("%d/%d/%d/%d/%d/%s", $a, $b, $c, $d, $e, $e + 1));
1921
}
2022
} catch (\Throwable $e) {echo $e, PHP_EOL; } echo PHP_EOL;
2123

2224
echo "Done";
2325
?>
2426
--EXPECTF--
25-
string(63) "42/-1337/4089650035136921599/1000000000000000000000000000000000"
26-
string(54) "42/-1337/2147483647/1000000000000000000000000000000000"
27+
string(104) "42/-1337/9223372036854775807/-9223372036854775808/4089650035136921599/1000000000000000000000000000000000"
28+
string(77) "42/-1337/2147483647/-2147483648/2147483647/1000000000000000000000000000000000"
2729

2830
Done

ext/standard/tests/strings/str_pad_variation1.phpt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
--TEST--
22
Test str_pad() function : usage variations - large values for '$pad_length' argument
3+
--INI--
4+
memory_limit=1g
35
--SKIPIF--
46
<?php
57
if (getenv("USE_ZEND_ALLOC") === "0") {
@@ -12,7 +14,7 @@ if (getenv("USE_ZEND_ALLOC") === "0") {
1214
* and expected type for '$input'
1315
*/
1416

15-
echo "*** Testing str_pad() function: with large value for for 'pad_length' argument ***\n";
17+
echo "*** Testing str_pad() function: with large value for 'pad_length' argument ***\n";
1618

1719
//defining '$input' argument
1820
$input = "Test string";
@@ -24,13 +26,12 @@ try {
2426
echo $e->getMessage() . "\n";
2527
}
2628

27-
$php_int_max_pad_length = PHP_INT_MAX;
28-
var_dump( str_pad($input, $php_int_max_pad_length) );
29-
29+
// INT32_MAX
30+
var_dump( str_pad($input, 2147483647) );
3031

3132
?>
3233
--EXPECTF--
33-
*** Testing str_pad() function: with large value for for 'pad_length' argument ***
34+
*** Testing str_pad() function: with large value for 'pad_length' argument ***
3435
str_pad(): Argument #2 ($length) must be of type int, float given
3536

3637
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d

ext/standard/tests/strings/str_pad_variation5.phpt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,26 @@ Test str_pad() function : usage variations - unexpected large value for '$pad_le
44
memory_limit=128M
55
--SKIPIF--
66
<?php
7-
if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only");
7+
if (PHP_SYS_SIZE >= PHP_INT_SIZE) {
8+
die("skip this test is for PHP_SyS_SIZE < PHP_INT_SIZE only");
9+
}
810
if (getenv("USE_ZEND_ALLOC") === "0") {
911
die("skip Zend MM disabled");
1012
}
11-
?>
13+
1214
--FILE--
1315
<?php
14-
/* Test str_pad() function: with unexpected inputs for '$pad_length'
15-
* and expected type for '$input'
16-
*/
16+
$input = "Test string";
1717

18-
echo "*** Testing str_pad() function: with large value for for 'pad_length' argument ***\n";
18+
try {
19+
var_dump( str_pad($input, PHP_INT_MAX) );
20+
} catch (ValueError $e) {
21+
echo $e::class . ": {$e->getMessage()}\n";
22+
}
1923

20-
//defining '$input' argument
21-
$input = "Test string";
22-
$pad_length = PHP_INT_MAX - 16; /* zend_string header is 16 bytes */
23-
var_dump( str_pad($input, $pad_length) );
24+
var_dump( str_pad($input, 2**(PHP_SYS_SIZE*8-1)-1) );
2425

25-
?>
2626
--EXPECTF--
27-
*** Testing str_pad() function: with large value for for 'pad_length' argument ***
27+
ValueError: str_pad(): Argument #2 ($length) must be lower or equal to %d
2828

2929
Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d

0 commit comments

Comments
 (0)