mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Optimize substr() edge-case conditions
This commit is contained in:
parent
52d91260df
commit
359f19edc9
1 changed files with 45 additions and 44 deletions
|
@ -2415,52 +2415,53 @@ PHP_FUNCTION(substr)
|
||||||
Z_PARAM_LONG(l)
|
Z_PARAM_LONG(l)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
|
||||||
if (argc > 2) {
|
if (f > (zend_long)ZSTR_LEN(str)) {
|
||||||
if ((l < 0 && (size_t)(-l) > ZSTR_LEN(str))) {
|
RETURN_FALSE;
|
||||||
RETURN_FALSE;
|
} else if (f < 0) {
|
||||||
} else if (l > (zend_long)ZSTR_LEN(str)) {
|
/* if "from" position is negative, count start position from the end
|
||||||
l = ZSTR_LEN(str);
|
* of the string
|
||||||
|
*/
|
||||||
|
if ((size_t)-f > ZSTR_LEN(str)) {
|
||||||
|
f = 0;
|
||||||
|
} else {
|
||||||
|
f = (zend_long)ZSTR_LEN(str) + f;
|
||||||
|
}
|
||||||
|
if (argc > 2) {
|
||||||
|
if (l < 0) {
|
||||||
|
/* if "length" position is negative, set it to the length
|
||||||
|
* needed to stop that many chars from the end of the string
|
||||||
|
*/
|
||||||
|
if ((size_t)(-l) > ZSTR_LEN(str) - (size_t)f) {
|
||||||
|
if ((size_t)(-l) > ZSTR_LEN(str)) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
} else {
|
||||||
|
l = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
l = (zend_long)ZSTR_LEN(str) - f + l;
|
||||||
|
}
|
||||||
|
} else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
|
||||||
|
goto truncate_len;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
goto truncate_len;
|
||||||
|
}
|
||||||
|
} else if (argc > 2) {
|
||||||
|
if (l < 0) {
|
||||||
|
/* if "length" position is negative, set it to the length
|
||||||
|
* needed to stop that many chars from the end of the string
|
||||||
|
*/
|
||||||
|
if ((size_t)(-l) > ZSTR_LEN(str) - (size_t)f) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
} else {
|
||||||
|
l = (zend_long)ZSTR_LEN(str) - f + l;
|
||||||
|
}
|
||||||
|
} else if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
|
||||||
|
goto truncate_len;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l = ZSTR_LEN(str);
|
truncate_len:
|
||||||
}
|
l = (zend_long)ZSTR_LEN(str) - f;
|
||||||
|
|
||||||
if (f > (zend_long)ZSTR_LEN(str)) {
|
|
||||||
RETURN_FALSE;
|
|
||||||
} else if (f < 0 && (size_t)-f > ZSTR_LEN(str)) {
|
|
||||||
f = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (l < 0 && (l + (zend_long)ZSTR_LEN(str) - f) < 0) {
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if "from" position is negative, count start position from the end
|
|
||||||
* of the string
|
|
||||||
*/
|
|
||||||
if (f < 0) {
|
|
||||||
f = (zend_long)ZSTR_LEN(str) + f;
|
|
||||||
if (f < 0) {
|
|
||||||
f = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if "length" position is negative, set it to the length
|
|
||||||
* needed to stop that many chars from the end of the string
|
|
||||||
*/
|
|
||||||
if (l < 0) {
|
|
||||||
l = ((zend_long)ZSTR_LEN(str) - f) + l;
|
|
||||||
if (l < 0) {
|
|
||||||
l = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f > (zend_long)ZSTR_LEN(str)) {
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
|
|
||||||
l = ZSTR_LEN(str) - f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l == 0) {
|
if (l == 0) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue