Skip to content

Commit 0bc2657

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix binary-safety of parse_url
2 parents 0d157cf + 81811db commit 0bc2657

12 files changed

+33
-13
lines changed

ext/standard/tests/url/parse_url_basic_001.phpt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,11 @@ echo "Done";
868868
string(19) "filter={"id":"123"}"
869869
}
870870

871+
--> %:x: array(1) {
872+
["path"]=>
873+
string(3) "%:x"
874+
}
875+
871876
--> http:///blah.com: bool(false)
872877

873878
--> http://:80: bool(false)

ext/standard/tests/url/parse_url_basic_002.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ echo "Done";
106106
--> : NULL
107107
--> / : NULL
108108
--> /rest/Users?filter={"id":"123"} : NULL
109+
--> %:x : NULL
109110
--> http:///blah.com : bool(false)
110111
--> http://:80 : bool(false)
111112
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_003.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : NULL
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_004.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : NULL
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_005.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : NULL
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_006.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : NULL
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_007.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : string(0) ""
106106
--> / : string(1) "/"
107107
--> /rest/Users?filter={"id":"123"} : string(11) "/rest/Users"
108+
--> %:x : string(3) "%:x"
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_008.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : string(19) "filter={"id":"123"}"
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_basic_009.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ echo "Done";
105105
--> : NULL
106106
--> / : NULL
107107
--> /rest/Users?filter={"id":"123"} : NULL
108+
--> %:x : NULL
108109
--> http:///blah.com : bool(false)
109110
--> http://:80 : bool(false)
110111
--> http://user@:80 : bool(false)

ext/standard/tests/url/parse_url_unterminated.phpt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,11 @@ echo "Done";
876876
string(19) "filter={"id":"123"}"
877877
}
878878

879+
--> %:x: array(1) {
880+
["path"]=>
881+
string(3) "%:x"
882+
}
883+
879884
--> http:///blah.com: bool(false)
880885

881886
--> http://:80: bool(false)

ext/standard/tests/url/urls.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ $urls = array(
9191
'',
9292
'/',
9393
'/rest/Users?filter={"id":"123"}',
94+
'%:x',
9495

9596
// Severely malformed URLs that do not parse:
9697
'http:///blah.com',

ext/standard/url.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ PHPAPI php_url *php_url_parse(char const *str)
8181
return php_url_parse_ex(str, strlen(str));
8282
}
8383

84+
static const char *binary_strcspn(const char *s, const char *e, const char *chars) {
85+
while (*chars) {
86+
const char *p = memchr(s, *chars, e - s);
87+
if (p) {
88+
e = p;
89+
}
90+
chars++;
91+
}
92+
return e;
93+
}
94+
8495
/* {{{ php_url_parse */
8596
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
8697
{
@@ -98,7 +109,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
98109
while (p < e) {
99110
/* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
100111
if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') {
101-
if (e + 1 < ue && e < s + strcspn(s, "?#")) {
112+
if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) {
102113
goto parse_port;
103114
} else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
104115
s += 2;
@@ -198,18 +209,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
198209
goto just_path;
199210
}
200211

201-
parse_host:
202-
/* Binary-safe strcspn(s, "/?#") */
203-
e = ue;
204-
if ((p = memchr(s, '/', e - s))) {
205-
e = p;
206-
}
207-
if ((p = memchr(s, '?', e - s))) {
208-
e = p;
209-
}
210-
if ((p = memchr(s, '#', e - s))) {
211-
e = p;
212-
}
212+
parse_host:
213+
e = binary_strcspn(s, ue, "/?#");
213214

214215
/* check for login and password */
215216
if ((p = zend_memrchr(s, '@', (e-s)))) {

0 commit comments

Comments
 (0)