Skip to content

Commit a15916a

Browse files
author
Andrei Zmievski
committed
Made strspn() and strcspn() binary-safe. # Please test if you can, especially cases with embedded chr(0). @ Made strspn() and strcspn() binary-safe.
1 parent 457a13d commit a15916a

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ ext/standard
2525
------------
2626
* strpad() (Andrei)
2727
* NOT binary safe:
28-
strcspn()
2928
strtok()
3029
basename()
3130
dirname()

ext/standard/php_string.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ extern PHPAPI void php_char_to_str(char *str, uint len, char from, char *to, int
102102

103103
extern PHPAPI void php_implode(pval *delim, pval *arr, pval *return_value);
104104
extern PHPAPI void php_explode(pval *delim, pval *str, pval *return_value);
105-
PHPAPI inline char *php_memnstr(char *haystack, char *needle, int needle_len, char *end);
105+
extern PHPAPI inline char *php_memnstr(char *haystack, char *needle, int needle_len, char *end);
106+
extern PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end);
107+
extern PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end);
106108

107109
#endif /* _PHPSTRING_H */

ext/standard/string.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,16 @@ PHP_FUNCTION(bin2hex)
8686
Find length of initial segment consisting entirely of characters found in mask */
8787
PHP_FUNCTION(strspn)
8888
{
89-
pval **s1,**s2;
89+
zval **s1,**s2;
9090

9191
if (ARG_COUNT(ht)!=2 || getParametersEx(2, &s1, &s2) == FAILURE) {
9292
WRONG_PARAM_COUNT;
9393
}
9494
convert_to_string_ex(s1);
9595
convert_to_string_ex(s2);
96-
RETURN_LONG(strspn((*s1)->value.str.val,(*s2)->value.str.val));
96+
RETURN_LONG(php_strspn((*s1)->value.str.val, (*s2)->value.str.val,
97+
(*s1)->value.str.val + (*s1)->value.str.len,
98+
(*s2)->value.str.val + (*s2)->value.str.len));
9799
}
98100
/* }}} */
99101

@@ -108,7 +110,9 @@ PHP_FUNCTION(strcspn)
108110
}
109111
convert_to_string_ex(s1);
110112
convert_to_string_ex(s2);
111-
RETURN_LONG(strcspn((*s1)->value.str.val,(*s2)->value.str.val));
113+
RETURN_LONG(php_strcspn((*s1)->value.str.val, (*s2)->value.str.val,
114+
(*s1)->value.str.val + (*s1)->value.str.len,
115+
(*s2)->value.str.val + (*s2)->value.str.len));
112116
}
113117
/* }}} */
114118

@@ -532,6 +536,36 @@ PHPAPI char *php_stristr(unsigned char *s, unsigned char *t,
532536
return php_memnstr(s, t, t_len, s + s_len);
533537
}
534538

539+
PHPAPI size_t php_strspn(char *s1, char *s2, char *s1_end, char *s2_end)
540+
{
541+
register const char *p = s1, *spanp;
542+
register char c = *p;
543+
544+
cont:
545+
for (spanp = s2; p != s1_end && spanp != s2_end;)
546+
if (*spanp++ == c) {
547+
c = *(++p);
548+
goto cont;
549+
}
550+
return (p - s1);
551+
}
552+
553+
PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end)
554+
{
555+
register const char *p, *spanp;
556+
register char c = *s1;
557+
558+
for (p = s1;;) {
559+
spanp = s2;
560+
do {
561+
if (*spanp == c || p == s1_end)
562+
return (p - s1);
563+
} while (spanp++ < s2_end);
564+
c = *(++p);
565+
}
566+
/* NOTREACHED */
567+
}
568+
535569
/* {{{ proto string stristr(string haystack, string needle)
536570
Find first occurrence of a string within another, case insensitive */
537571
PHP_FUNCTION(stristr)

0 commit comments

Comments
 (0)