Skip to content

Commit

Permalink
Optimize substr() edge-case conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Oct 29, 2018
1 parent 52d9126 commit 359f19e
Showing 1 changed file with 41 additions and 40 deletions.
81 changes: 41 additions & 40 deletions ext/standard/string.c
Expand Up @@ -2415,52 +2415,53 @@ PHP_FUNCTION(substr)
Z_PARAM_LONG(l)
ZEND_PARSE_PARAMETERS_END();

if (argc > 2) {
if ((l < 0 && (size_t)(-l) > ZSTR_LEN(str))) {
RETURN_FALSE;
} else if (l > (zend_long)ZSTR_LEN(str)) {
l = ZSTR_LEN(str);
}
} else {
l = ZSTR_LEN(str);
}

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) {
} else if (f < 0) {
/* if "from" position is negative, count start position from the end
* of the string
*/
if ((size_t)-f > ZSTR_LEN(str)) {
f = 0;
} else {
f = (zend_long)ZSTR_LEN(str) + f;
}
}

/* 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 (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) {
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;
}
}

if (f > (zend_long)ZSTR_LEN(str)) {
RETURN_FALSE;
}

if ((size_t)l > ZSTR_LEN(str) - (size_t)f) {
l = ZSTR_LEN(str) - f;
} else {
truncate_len:
l = (zend_long)ZSTR_LEN(str) - f;
}

if (l == 0) {
Expand Down

0 comments on commit 359f19e

Please sign in to comment.