summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-10-29 13:11:41 +0300
committerDmitry Stogov <dmitry@zend.com>2018-10-29 13:11:41 +0300
commit359f19edc9b200dd94a3d30dc14bd4a22903d80c (patch)
treedeb5a37f0f00a141f972b77516c33d0172eaf937
parent52d91260df54995a680f420884338dfd9d5a0d49 (diff)
downloadphp-git-359f19edc9b200dd94a3d30dc14bd4a22903d80c.tar.gz
Optimize substr() edge-case conditions
-rw-r--r--ext/standard/string.c81
1 files changed, 41 insertions, 40 deletions
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) {