Skip to content

Commit 359f19e

Browse files
committed
Optimize substr() edge-case conditions
1 parent 52d9126 commit 359f19e

File tree

1 file changed

+41
-40
lines changed

1 file changed

+41
-40
lines changed

ext/standard/string.c

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,52 +2415,53 @@ PHP_FUNCTION(substr)
24152415
Z_PARAM_LONG(l)
24162416
ZEND_PARSE_PARAMETERS_END();
24172417

2418-
if (argc > 2) {
2419-
if ((l < 0 && (size_t)(-l) > ZSTR_LEN(str))) {
2420-
RETURN_FALSE;
2421-
} else if (l > (zend_long)ZSTR_LEN(str)) {
2422-
l = ZSTR_LEN(str);
2423-
}
2424-
} else {
2425-
l = ZSTR_LEN(str);
2426-
}
2427-
24282418
if (f > (zend_long)ZSTR_LEN(str)) {
24292419
RETURN_FALSE;
2430-
} else if (f < 0 && (size_t)-f > ZSTR_LEN(str)) {
2431-
f = 0;
2432-
}
2433-
2434-
if (l < 0 && (l + (zend_long)ZSTR_LEN(str) - f) < 0) {
2435-
RETURN_FALSE;
2436-
}
2437-
2438-
/* if "from" position is negative, count start position from the end
2439-
* of the string
2440-
*/
2441-
if (f < 0) {
2442-
f = (zend_long)ZSTR_LEN(str) + f;
2443-
if (f < 0) {
2420+
} else if (f < 0) {
2421+
/* if "from" position is negative, count start position from the end
2422+
* of the string
2423+
*/
2424+
if ((size_t)-f > ZSTR_LEN(str)) {
24442425
f = 0;
2426+
} else {
2427+
f = (zend_long)ZSTR_LEN(str) + f;
24452428
}
2446-
}
2447-
2448-
/* if "length" position is negative, set it to the length
2449-
* needed to stop that many chars from the end of the string
2450-
*/
2451-
if (l < 0) {
2452-
l = ((zend_long)ZSTR_LEN(str) - f) + l;
2429+
if (argc > 2) {
2430+
if (l < 0) {
2431+
/* if "length" position is negative, set it to the length
2432+
* needed to stop that many chars from the end of the string
2433+
*/
2434+
if ((size_t)(-l) > ZSTR_LEN(str) - (size_t)f) {
2435+
if ((size_t)(-l) > ZSTR_LEN(str)) {
2436+
RETURN_FALSE;
2437+
} else {
2438+
l = 0;
2439+
}
2440+
} else {
2441+
l = (zend_long)ZSTR_LEN(str) - f + l;
2442+
}
2443+
} else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
2444+
goto truncate_len;
2445+
}
2446+
} else {
2447+
goto truncate_len;
2448+
}
2449+
} else if (argc > 2) {
24532450
if (l < 0) {
2454-
l = 0;
2451+
/* if "length" position is negative, set it to the length
2452+
* needed to stop that many chars from the end of the string
2453+
*/
2454+
if ((size_t)(-l) > ZSTR_LEN(str) - (size_t)f) {
2455+
RETURN_FALSE;
2456+
} else {
2457+
l = (zend_long)ZSTR_LEN(str) - f + l;
2458+
}
2459+
} else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
2460+
goto truncate_len;
24552461
}
2456-
}
2457-
2458-
if (f > (zend_long)ZSTR_LEN(str)) {
2459-
RETURN_FALSE;
2460-
}
2461-
2462-
if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
2463-
l = ZSTR_LEN(str) - f;
2462+
} else {
2463+
truncate_len:
2464+
l = (zend_long)ZSTR_LEN(str) - f;
24642465
}
24652466

24662467
if (l == 0) {

0 commit comments

Comments
 (0)