diff --git a/ext/standard/tests/url/gh12703.phpt b/ext/standard/tests/url/gh12703.phpt new file mode 100644 index 0000000000000..c8e57c5246389 --- /dev/null +++ b/ext/standard/tests/url/gh12703.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-12703 parse_url() return false on absolute path containing ':' and no query string. +--FILE-- + +--EXPECT-- +array(1) { + ["path"]=> + string(7) "/page:1" +} +NULL +array(2) { + ["path"]=> + string(7) "/page:1" + ["query"]=> + string(7) "foo=bar" +} +array(2) { + ["host"]=> + string(14) "www.examle.com" + ["path"]=> + string(11) "/foo:65535/" +} +array(3) { + ["host"]=> + string(14) "www.examle.com" + ["port"]=> + int(8080) + ["path"]=> + string(11) "/foo:65535/" +} \ No newline at end of file diff --git a/ext/standard/tests/url/url_utf8.phpt b/ext/standard/tests/url/url_utf8.phpt new file mode 100644 index 0000000000000..8e6321a0ddd93 --- /dev/null +++ b/ext/standard/tests/url/url_utf8.phpt @@ -0,0 +1,10 @@ +--TEST-- +Uri: hostnames should be preserved in Unicode form +--FILE-- + +--EXPECT-- +string(24) "ουτοπία.δπθ.gr" diff --git a/ext/standard/url.c b/ext/standard/url.c index d19965fb2081c..47c5e2091901b 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -18,6 +18,12 @@ #include #include #include +#if defined(__APPLE__) +#include +#endif +#if defined(__APPLE__) +#include +#endif #include "php.h" @@ -58,6 +64,23 @@ static void parse_url_free_uri(void *uri) static void php_replace_controlchars(char *str, size_t len) { + #if defined(__APPLE__) + { + ZEND_ASSERT(str != NULL); + wchar_t wbuf[len]; + memset(wbuf, 0, sizeof(wbuf)); + size_t wlen = mbstowcs(wbuf, str, len); + + for (size_t i = 0; i < wlen; i++) { + if (iswcntrl(wbuf[i])) { + wbuf[i] = L'_'; + } + } + + wcstombs(str, wbuf, len); + return; + } + #endif unsigned char *s = (unsigned char *)str; unsigned char *e = (unsigned char *)str + len; @@ -180,8 +203,11 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, bool *has_port parse_port: p = e + 1; pp = p; + + const char *first_slash = memchr(s, '/', ue - s); while (pp < ue && pp - p < 6 && isdigit(*pp)) { + if (first_slash && pp >= first_slash) break; pp++; } @@ -925,4 +951,4 @@ PHP_FUNCTION(get_headers) PHP_MINIT_FUNCTION(url) { return php_uri_handler_register(&parse_url_uri_handler); -} +} \ No newline at end of file