Skip to content

Commit 85ffe8d

Browse files
committed
Avoid signed integer overflow in substr()
Perform negation after the (size_t) cast rather than before, so as to avoid a signed integer overflow for PHP_INT_MIN. Fixes oss-fuzz #31069.
1 parent 553a0c5 commit 85ffe8d

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

ext/standard/string.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,7 @@ PHP_FUNCTION(substr)
21772177
/* if "from" position is negative, count start position from the end
21782178
* of the string
21792179
*/
2180-
if ((size_t)-f > ZSTR_LEN(str)) {
2180+
if (-(size_t)f > ZSTR_LEN(str)) {
21812181
f = 0;
21822182
} else {
21832183
f = (zend_long)ZSTR_LEN(str) + f;
@@ -2191,7 +2191,7 @@ PHP_FUNCTION(substr)
21912191
/* if "length" position is negative, set it to the length
21922192
* needed to stop that many chars from the end of the string
21932193
*/
2194-
if ((size_t)(-l) > ZSTR_LEN(str) - (size_t)f) {
2194+
if (-(size_t)l > ZSTR_LEN(str) - (size_t)f) {
21952195
l = 0;
21962196
} else {
21972197
l = (zend_long)ZSTR_LEN(str) - f + l;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
substr() with PHP_INT_MIN offset or length
3+
--FILE--
4+
<?php
5+
var_dump(substr('x', PHP_INT_MIN));
6+
var_dump(substr('x', 0, PHP_INT_MIN));
7+
?>
8+
--EXPECT--
9+
string(1) "x"
10+
string(0) ""

0 commit comments

Comments
 (0)