Skip to content

Commit 2ab84b5

Browse files
committed
Make stripos optimization linear
1 parent 23c4443 commit 2ab84b5

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

Zend/zend_operators.h

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ static zend_always_inline void zend_unwrap_reference(zval *op) /* {{{ */
919919
}
920920
/* }}} */
921921

922-
static zend_always_inline const char *strnichr(const char *ptr, char value, size_t num)
922+
static zend_always_inline const char *zend_strnichr(const char *ptr, char value, size_t num)
923923
{
924924
char value_lower = zend_tolower_ascii(value);
925925
char value_upper = zend_toupper_ascii(value);
@@ -936,7 +936,7 @@ static zend_always_inline const char *strnichr(const char *ptr, char value, size
936936
return ptr_lower ? ptr_lower : ptr_upper;
937937
}
938938

939-
static zend_always_inline bool strnieq(const char *ptr1, const char *ptr2, size_t num)
939+
static zend_always_inline bool zend_strnieq(const char *ptr1, const char *ptr2, size_t num)
940940
{
941941
for (size_t i = 0; i < num; i++) {
942942
if (zend_tolower_ascii(*ptr1++) != zend_tolower_ascii(*ptr2++)) {
@@ -955,7 +955,7 @@ zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const
955955
ZEND_ASSERT(end >= p);
956956

957957
if (needle_len == 1) {
958-
return (const char *)strnichr(p, *needle, (end-p));
958+
return (const char *)zend_strnichr(p, *needle, (end-p));
959959
} else if (UNEXPECTED(needle_len == 0)) {
960960
return p;
961961
}
@@ -966,18 +966,46 @@ zend_memnistr(const char *haystack, const char *needle, size_t needle_len, const
966966
return NULL;
967967
}
968968

969+
const char ns_upper = zend_tolower_ascii(*needle);
970+
const char ns_lower = zend_toupper_ascii(*needle);
969971
const char ne = zend_tolower_ascii(needle[needle_len-1]);
970972
end -= needle_len;
971973

972-
while (p <= end) {
973-
if ((p = (const char *)strnichr(p, *needle, (end-p+1)))) {
974-
if (ne == zend_tolower_ascii(p[needle_len-1]) && strnieq(needle+1, p+1, needle_len-2)) {
974+
if (ns_upper == ns_lower) {
975+
while (p <= end) {
976+
if ((p = (const char *)memchr(p, ns_lower, (end-p+1)))) {
977+
if (ne == zend_tolower_ascii(p[needle_len-1]) && zend_strnieq(needle+1, p+1, needle_len-2)) {
978+
return p;
979+
}
980+
} else {
981+
return NULL;
982+
}
983+
p++;
984+
}
985+
} else {
986+
const char *next_lower = (const char *)memchr(p, ns_lower, (end-p+1));
987+
const char *next_upper = (const char *)memchr(p, ns_upper, (end-p+1));
988+
while (p <= end) {
989+
if (next_lower && (!next_upper || next_lower < next_upper)) {
990+
p = next_lower;
991+
next_lower = NULL;
992+
} else if (next_upper) {
993+
p = next_upper;
994+
next_upper = NULL;
995+
} else {
996+
return NULL;
997+
}
998+
if (ne == zend_tolower_ascii(p[needle_len-1]) && zend_strnieq(needle+1, p+1, needle_len-2)) {
975999
return p;
9761000
}
977-
} else {
978-
return NULL;
1001+
p++;
1002+
if (!next_lower) {
1003+
next_lower = (const char *)memchr(p, ns_lower, (end-p+1));
1004+
}
1005+
if (!next_upper) {
1006+
next_upper = (const char *)memchr(p, ns_upper, (end-p+1));
1007+
}
9791008
}
980-
p++;
9811009
}
9821010

9831011
return NULL;

0 commit comments

Comments
 (0)