diff --git a/ext/standard/tests/url/bug74780.phpt b/ext/standard/tests/url/bug74780.phpt new file mode 100644 index 0000000000000..ae464d971b084 --- /dev/null +++ b/ext/standard/tests/url/bug74780.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #74780 parse_url() borks when query string contains colon +--FILE-- + +--EXPECT-- +array(3) { + ["host"]=> + string(7) "php.net" + ["path"]=> + string(5) "/path" + ["query"]=> + string(9) "query=1:2" +} +array(3) { + ["host"]=> + string(7) "php.net" + ["path"]=> + string(9) "/path.php" + ["query"]=> + string(9) "query=a:b" +} +array(4) { + ["host"]=> + string(7) "php.net" + ["user"]=> + string(8) "username" + ["path"]=> + string(5) "/path" + ["query"]=> + string(9) "query=1:2" +} \ No newline at end of file diff --git a/ext/standard/url.c b/ext/standard/url.c index 86f8c45563d29..9c42afbdeac72 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -112,6 +112,10 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { if (e + 1 < ue && e < s + strcspn(s, "?#")) { goto parse_port; + } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ + s += 2; + e = 0; + goto parse_host; } else { goto just_path; } @@ -208,6 +212,7 @@ 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))) {