From: Dmitry Stogov Date: Mon, 29 Oct 2018 10:11:41 +0000 (+0300) Subject: Optimize substr() edge-case conditions X-Git-Tag: php-7.4.0alpha1~1614 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=359f19edc9b200dd94a3d30dc14bd4a22903d80c;p=php Optimize substr() edge-case conditions --- diff --git a/ext/standard/string.c b/ext/standard/string.c index 2f20d62a74..b28ad050d7 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -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) {