summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-09-02 16:45:57 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-09-02 16:45:57 +0200
commit81811dbbfba4f52c68fd9a08c3a0979de57f530f (patch)
treeff6f381eef924f123a3d9e5aad1ae9badbc01eed
parentc6fd37cee32965b905e57dfd1abbd066b1e87317 (diff)
parent54dbd3eccc867f456f257ce11556b50fcbee2ccf (diff)
downloadphp-git-81811dbbfba4f52c68fd9a08c3a0979de57f530f.tar.gz
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3: Fix binary-safety of parse_url
-rw-r--r--ext/standard/tests/url/parse_url_basic_001.phpt5
-rw-r--r--ext/standard/tests/url/parse_url_basic_002.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_003.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_004.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_005.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_006.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_007.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_008.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_basic_009.phpt1
-rw-r--r--ext/standard/tests/url/parse_url_unterminated.phpt5
-rw-r--r--ext/standard/tests/url/urls.inc1
-rw-r--r--ext/standard/url.c27
12 files changed, 33 insertions, 13 deletions
diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt
index d59f080fbf..7f702aeddf 100644
--- a/ext/standard/tests/url/parse_url_basic_001.phpt
+++ b/ext/standard/tests/url/parse_url_basic_001.phpt
@@ -854,6 +854,11 @@ echo "Done";
string(19) "filter={"id":"123"}"
}
+--> %:x: array(1) {
+ ["path"]=>
+ string(3) "%:x"
+}
+
--> http:///blah.com: bool(false)
--> http://:80: bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_002.phpt b/ext/standard/tests/url/parse_url_basic_002.phpt
index c8b94dec1c..9390f02624 100644
--- a/ext/standard/tests/url/parse_url_basic_002.phpt
+++ b/ext/standard/tests/url/parse_url_basic_002.phpt
@@ -112,6 +112,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt
index f917b77b97..0c1ab71df6 100644
--- a/ext/standard/tests/url/parse_url_basic_003.phpt
+++ b/ext/standard/tests/url/parse_url_basic_003.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_004.phpt b/ext/standard/tests/url/parse_url_basic_004.phpt
index 29d4655243..7c169ebf32 100644
--- a/ext/standard/tests/url/parse_url_basic_004.phpt
+++ b/ext/standard/tests/url/parse_url_basic_004.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt
index 716d8d1dfa..ed676b1813 100644
--- a/ext/standard/tests/url/parse_url_basic_005.phpt
+++ b/ext/standard/tests/url/parse_url_basic_005.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_006.phpt b/ext/standard/tests/url/parse_url_basic_006.phpt
index 3ae94ca626..abe0726939 100644
--- a/ext/standard/tests/url/parse_url_basic_006.phpt
+++ b/ext/standard/tests/url/parse_url_basic_006.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_007.phpt b/ext/standard/tests/url/parse_url_basic_007.phpt
index 8cad27e958..6422a194c4 100644
--- a/ext/standard/tests/url/parse_url_basic_007.phpt
+++ b/ext/standard/tests/url/parse_url_basic_007.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : string(0) ""
--> / : string(1) "/"
--> /rest/Users?filter={"id":"123"} : string(11) "/rest/Users"
+--> %:x : string(3) "%:x"
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_008.phpt b/ext/standard/tests/url/parse_url_basic_008.phpt
index 761eb61179..f6f05666fe 100644
--- a/ext/standard/tests/url/parse_url_basic_008.phpt
+++ b/ext/standard/tests/url/parse_url_basic_008.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : string(19) "filter={"id":"123"}"
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_basic_009.phpt b/ext/standard/tests/url/parse_url_basic_009.phpt
index f08787761d..458a57436a 100644
--- a/ext/standard/tests/url/parse_url_basic_009.phpt
+++ b/ext/standard/tests/url/parse_url_basic_009.phpt
@@ -111,6 +111,7 @@ echo "Done";
--> : NULL
--> / : NULL
--> /rest/Users?filter={"id":"123"} : NULL
+--> %:x : NULL
--> http:///blah.com : bool(false)
--> http://:80 : bool(false)
--> http://user@:80 : bool(false)
diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt
index 94975ee889..2c07c9d4ee 100644
--- a/ext/standard/tests/url/parse_url_unterminated.phpt
+++ b/ext/standard/tests/url/parse_url_unterminated.phpt
@@ -856,6 +856,11 @@ echo "Done";
string(19) "filter={"id":"123"}"
}
+--> %:x: array(1) {
+ ["path"]=>
+ string(3) "%:x"
+}
+
--> http:///blah.com: bool(false)
--> http://:80: bool(false)
diff --git a/ext/standard/tests/url/urls.inc b/ext/standard/tests/url/urls.inc
index b60af2205e..199f22caea 100644
--- a/ext/standard/tests/url/urls.inc
+++ b/ext/standard/tests/url/urls.inc
@@ -91,6 +91,7 @@ $urls = array(
'',
'/',
'/rest/Users?filter={"id":"123"}',
+'%:x',
// Severely malformed URLs that do not parse:
'http:///blah.com',
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 62ce107f77..3b12e3171f 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -87,6 +87,17 @@ PHPAPI php_url *php_url_parse(char const *str)
return php_url_parse_ex(str, strlen(str));
}
+static const char *binary_strcspn(const char *s, const char *e, const char *chars) {
+ while (*chars) {
+ const char *p = memchr(s, *chars, e - s);
+ if (p) {
+ e = p;
+ }
+ chars++;
+ }
+ return e;
+}
+
/* {{{ php_url_parse
*/
PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
@@ -105,7 +116,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
while (p < e) {
/* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */
if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') {
- if (e + 1 < ue && e < s + strcspn(s, "?#")) {
+ if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) {
goto parse_port;
} else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */
s += 2;
@@ -205,18 +216,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
goto just_path;
}
- parse_host:
- /* Binary-safe strcspn(s, "/?#") */
- e = ue;
- if ((p = memchr(s, '/', e - s))) {
- e = p;
- }
- if ((p = memchr(s, '?', e - s))) {
- e = p;
- }
- if ((p = memchr(s, '#', e - s))) {
- e = p;
- }
+parse_host:
+ e = binary_strcspn(s, ue, "/?#");
/* check for login and password */
if ((p = zend_memrchr(s, '@', (e-s)))) {