From fe9f150912d9e8048a73173f4550c7ddfc42e396 Mon Sep 17 00:00:00 2001 From: Islam Israfilov Date: Sat, 11 Jan 2020 10:34:05 +0000 Subject: [PATCH 1/3] ticket-78385 an empty string in parse_url() return when question mark is the last --- ext/standard/tests/url/bug78385.phpt | 21 ++++++++++++ .../tests/url/parse_url_basic_001.phpt | 32 ++++++++++++++----- .../tests/url/parse_url_basic_008.phpt | 16 +++++----- ext/standard/url.c | 2 ++ 4 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 ext/standard/tests/url/bug78385.phpt diff --git a/ext/standard/tests/url/bug78385.phpt b/ext/standard/tests/url/bug78385.phpt new file mode 100644 index 0000000000000..348364fe7488f --- /dev/null +++ b/ext/standard/tests/url/bug78385.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #78385 parse_url() does not include 'query' when question mark is the last char +--FILE-- + +--EXPECT-- +array(4) { + ["scheme"]=> + string(4) "http" + ["host"]=> + string(11) "example.com" + ["path"]=> + string(4) "/foo" + ["query"]=> + string(0) "" +} +string(0) "" diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt index d59f080fbf018..b8f793b0d41d8 100644 --- a/ext/standard/tests/url/parse_url_basic_001.phpt +++ b/ext/standard/tests/url/parse_url_basic_001.phpt @@ -144,30 +144,36 @@ echo "Done"; string(10) "/index.php" } ---> www.php.net/?: array(1) { +--> www.php.net/?: array(2) { ["path"]=> string(12) "www.php.net/" + ["query"]=> + string(0) "" } ---> www.php.net:80/?: array(3) { +--> www.php.net:80/?: array(4) { ["host"]=> string(11) "www.php.net" ["port"]=> int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net/?: array(3) { +--> http://www.php.net/?: array(4) { ["scheme"]=> string(4) "http" ["host"]=> string(11) "www.php.net" ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net:80/?: array(4) { +--> http://www.php.net:80/?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -176,6 +182,8 @@ echo "Done"; int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/index.php: array(4) { @@ -290,7 +298,7 @@ echo "Done"; string(10) "/index.php" } ---> http://www.php.net:80/index.php?: array(4) { +--> http://www.php.net:80/index.php?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -299,6 +307,8 @@ echo "Done"; int(80) ["path"]=> string(10) "/index.php" + ["query"]=> + string(0) "" } --> http://www.php.net:80/#foo: array(5) { @@ -314,7 +324,7 @@ echo "Done"; string(3) "foo" } ---> http://www.php.net:80/?#: array(4) { +--> http://www.php.net:80/?#: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -323,6 +333,8 @@ echo "Done"; int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { @@ -731,11 +743,13 @@ echo "Done"; string(4) "/:80" } ---> http://x:?: array(2) { +--> http://x:?: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) "x" + ["query"]=> + string(0) "" } --> x:blah.com: array(2) { @@ -754,11 +768,13 @@ echo "Done"; --> x://::abc/?: bool(false) ---> http://::?: array(2) { +--> http://::?: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) ":" + ["query"]=> + string(0) "" } --> http://::#: array(2) { diff --git a/ext/standard/tests/url/parse_url_basic_008.phpt b/ext/standard/tests/url/parse_url_basic_008.phpt index 761eb61179e75..142da3d561801 100644 --- a/ext/standard/tests/url/parse_url_basic_008.phpt +++ b/ext/standard/tests/url/parse_url_basic_008.phpt @@ -38,10 +38,10 @@ echo "Done"; --> http://www.php.net:80 : NULL --> http://www.php.net:80/ : NULL --> http://www.php.net/index.php : NULL ---> www.php.net/? : NULL ---> www.php.net:80/? : NULL ---> http://www.php.net/? : NULL ---> http://www.php.net:80/? : NULL +--> www.php.net/? : string(0) "" +--> www.php.net:80/? : string(0) "" +--> http://www.php.net/? : string(0) "" +--> http://www.php.net:80/? : string(0) "" --> http://www.php.net:80/index.php : NULL --> http://www.php.net:80/foo/bar/index.php : NULL --> http://www.php.net:80/this/is/a/very/deep/directory/structure/and/file.php : NULL @@ -52,9 +52,9 @@ echo "Done"; --> http://www.php.net:80/this/../a/../deep/directory/ : NULL --> http://www.php.net:80/this/is/a/very/deep/directory/../file.php : NULL --> http://www.php.net:80/index.php : NULL ---> http://www.php.net:80/index.php? : NULL +--> http://www.php.net:80/index.php? : string(0) "" --> http://www.php.net:80/#foo : NULL ---> http://www.php.net:80/?# : NULL +--> http://www.php.net:80/?# : string(0) "" --> http://www.php.net:80/?test=1 : string(6) "test=1" --> http://www.php.net/?test=1& : string(7) "test=1&" --> http://www.php.net:80/?& : string(1) "&" @@ -91,11 +91,11 @@ echo "Done"; --> gg:9130731 : NULL --> http://user:@pass@host/path?argument?value#etc : string(14) "argument?value" --> http://10.10.10.10/:80 : NULL ---> http://x:? : NULL +--> http://x:? : string(0) "" --> x:blah.com : NULL --> x:/blah.com : NULL --> x://::abc/? : bool(false) ---> http://::? : NULL +--> http://::? : string(0) "" --> http://::# : NULL --> x://::6.5 : NULL --> http://?:/ : bool(false) diff --git a/ext/standard/url.c b/ext/standard/url.c index c2d9340e1c16e..4a59eebed10f4 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -301,6 +301,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p < e) { ret->query = zend_string_init(p, (e - p), 0); php_replace_controlchars_ex(ZSTR_VAL(ret->query), ZSTR_LEN(ret->query)); + } else { + ret->query = ZSTR_EMPTY_ALLOC(); } e = p-1; } From 286c6e7ca8fe538ab06074deae220bb127233eda Mon Sep 17 00:00:00 2001 From: Islam Israfilov Date: Sat, 11 Jan 2020 13:43:56 +0000 Subject: [PATCH 2/3] missed test files updates --- ext/standard/tests/strings/url_t.phpt | 24 ++++++++++---- .../tests/url/parse_url_unterminated.phpt | 32 ++++++++++++++----- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt index 79ff3bc4a8e3d..4cb54aaa030c5 100644 --- a/ext/standard/tests/strings/url_t.phpt +++ b/ext/standard/tests/strings/url_t.phpt @@ -213,30 +213,36 @@ $sample_urls = array ( string(10) "/index.php" } ---> www.php.net/?: array(1) { +--> www.php.net/?: array(2) { ["path"]=> string(12) "www.php.net/" + ["query"]=> + string(0) "" } ---> www.php.net:80/?: array(3) { +--> www.php.net:80/?: array(4) { ["host"]=> string(11) "www.php.net" ["port"]=> int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net/?: array(3) { +--> http://www.php.net/?: array(4) { ["scheme"]=> string(4) "http" ["host"]=> string(11) "www.php.net" ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net:80/?: array(4) { +--> http://www.php.net:80/?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -245,6 +251,8 @@ $sample_urls = array ( int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/index.php: array(4) { @@ -359,7 +367,7 @@ $sample_urls = array ( string(10) "/index.php" } ---> http://www.php.net:80/index.php?: array(4) { +--> http://www.php.net:80/index.php?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -368,6 +376,8 @@ $sample_urls = array ( int(80) ["path"]=> string(10) "/index.php" + ["query"]=> + string(0) "" } --> http://www.php.net:80/#foo: array(5) { @@ -383,7 +393,7 @@ $sample_urls = array ( string(3) "foo" } ---> http://www.php.net:80/?#: array(4) { +--> http://www.php.net:80/?#: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -392,6 +402,8 @@ $sample_urls = array ( int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt index 94975ee8891fd..a159ee88f4a22 100644 --- a/ext/standard/tests/url/parse_url_unterminated.phpt +++ b/ext/standard/tests/url/parse_url_unterminated.phpt @@ -146,30 +146,36 @@ echo "Done"; string(10) "/index.php" } ---> www.php.net/?: array(1) { +--> www.php.net/?: array(2) { ["path"]=> string(12) "www.php.net/" + ["query"]=> + string(0) "" } ---> www.php.net:80/?: array(3) { +--> www.php.net:80/?: array(4) { ["host"]=> string(11) "www.php.net" ["port"]=> int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net/?: array(3) { +--> http://www.php.net/?: array(4) { ["scheme"]=> string(4) "http" ["host"]=> string(11) "www.php.net" ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } ---> http://www.php.net:80/?: array(4) { +--> http://www.php.net:80/?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -178,6 +184,8 @@ echo "Done"; int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/index.php: array(4) { @@ -292,7 +300,7 @@ echo "Done"; string(10) "/index.php" } ---> http://www.php.net:80/index.php?: array(4) { +--> http://www.php.net:80/index.php?: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -301,6 +309,8 @@ echo "Done"; int(80) ["path"]=> string(10) "/index.php" + ["query"]=> + string(0) "" } --> http://www.php.net:80/#foo: array(5) { @@ -316,7 +326,7 @@ echo "Done"; string(3) "foo" } ---> http://www.php.net:80/?#: array(4) { +--> http://www.php.net:80/?#: array(5) { ["scheme"]=> string(4) "http" ["host"]=> @@ -325,6 +335,8 @@ echo "Done"; int(80) ["path"]=> string(1) "/" + ["query"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { @@ -733,11 +745,13 @@ echo "Done"; string(4) "/:80" } ---> http://x:?: array(2) { +--> http://x:?: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) "x" + ["query"]=> + string(0) "" } --> x:blah.com: array(2) { @@ -756,11 +770,13 @@ echo "Done"; --> x://::abc/?: bool(false) ---> http://::?: array(2) { +--> http://::?: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) ":" + ["query"]=> + string(0) "" } --> http://::#: array(2) { From 90a83e23271093258a6e819cd16117d91ff4259f Mon Sep 17 00:00:00 2001 From: Islam Israfilov Date: Sat, 11 Jan 2020 18:38:01 +0000 Subject: [PATCH 3/3] an empty string for fragment when there are no any chars after # --- ext/standard/tests/strings/url_t.phpt | 4 +++- ext/standard/tests/url/bug78385.phpt | 21 ------------------- .../tests/url/parse_url_basic_001.phpt | 8 +++++-- .../tests/url/parse_url_basic_009.phpt | 4 ++-- .../tests/url/parse_url_unterminated.phpt | 8 +++++-- ext/standard/url.c | 2 ++ 6 files changed, 19 insertions(+), 28 deletions(-) delete mode 100644 ext/standard/tests/url/bug78385.phpt diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt index 4cb54aaa030c5..1ff7baff90e36 100644 --- a/ext/standard/tests/strings/url_t.phpt +++ b/ext/standard/tests/strings/url_t.phpt @@ -393,7 +393,7 @@ $sample_urls = array ( string(3) "foo" } ---> http://www.php.net:80/?#: array(5) { +--> http://www.php.net:80/?#: array(6) { ["scheme"]=> string(4) "http" ["host"]=> @@ -404,6 +404,8 @@ $sample_urls = array ( string(1) "/" ["query"]=> string(0) "" + ["fragment"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { diff --git a/ext/standard/tests/url/bug78385.phpt b/ext/standard/tests/url/bug78385.phpt deleted file mode 100644 index 348364fe7488f..0000000000000 --- a/ext/standard/tests/url/bug78385.phpt +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Bug #78385 parse_url() does not include 'query' when question mark is the last char ---FILE-- - ---EXPECT-- -array(4) { - ["scheme"]=> - string(4) "http" - ["host"]=> - string(11) "example.com" - ["path"]=> - string(4) "/foo" - ["query"]=> - string(0) "" -} -string(0) "" diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt index b8f793b0d41d8..3977a3fc2e5c9 100644 --- a/ext/standard/tests/url/parse_url_basic_001.phpt +++ b/ext/standard/tests/url/parse_url_basic_001.phpt @@ -324,7 +324,7 @@ echo "Done"; string(3) "foo" } ---> http://www.php.net:80/?#: array(5) { +--> http://www.php.net:80/?#: array(6) { ["scheme"]=> string(4) "http" ["host"]=> @@ -335,6 +335,8 @@ echo "Done"; string(1) "/" ["query"]=> string(0) "" + ["fragment"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { @@ -777,11 +779,13 @@ echo "Done"; string(0) "" } ---> http://::#: array(2) { +--> http://::#: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) ":" + ["fragment"]=> + string(0) "" } --> x://::6.5: array(3) { diff --git a/ext/standard/tests/url/parse_url_basic_009.phpt b/ext/standard/tests/url/parse_url_basic_009.phpt index f08787761d897..3634046de26c4 100644 --- a/ext/standard/tests/url/parse_url_basic_009.phpt +++ b/ext/standard/tests/url/parse_url_basic_009.phpt @@ -54,7 +54,7 @@ echo "Done"; --> http://www.php.net:80/index.php : NULL --> http://www.php.net:80/index.php? : NULL --> http://www.php.net:80/#foo : string(3) "foo" ---> http://www.php.net:80/?# : NULL +--> http://www.php.net:80/?# : string(0) "" --> http://www.php.net:80/?test=1 : NULL --> http://www.php.net/?test=1& : NULL --> http://www.php.net:80/?& : NULL @@ -96,7 +96,7 @@ echo "Done"; --> x:/blah.com : NULL --> x://::abc/? : bool(false) --> http://::? : NULL ---> http://::# : NULL +--> http://::# : string(0) "" --> x://::6.5 : NULL --> http://?:/ : bool(false) --> http://@?:/ : bool(false) diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt index a159ee88f4a22..7a0cba8ada986 100644 --- a/ext/standard/tests/url/parse_url_unterminated.phpt +++ b/ext/standard/tests/url/parse_url_unterminated.phpt @@ -326,7 +326,7 @@ echo "Done"; string(3) "foo" } ---> http://www.php.net:80/?#: array(5) { +--> http://www.php.net:80/?#: array(6) { ["scheme"]=> string(4) "http" ["host"]=> @@ -337,6 +337,8 @@ echo "Done"; string(1) "/" ["query"]=> string(0) "" + ["fragment"]=> + string(0) "" } --> http://www.php.net:80/?test=1: array(5) { @@ -779,11 +781,13 @@ echo "Done"; string(0) "" } ---> http://::#: array(2) { +--> http://::#: array(3) { ["scheme"]=> string(4) "http" ["host"]=> string(1) ":" + ["fragment"]=> + string(0) "" } --> x://::6.5: array(3) { diff --git a/ext/standard/url.c b/ext/standard/url.c index 4a59eebed10f4..c73818f08e1c9 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -291,6 +291,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) if (p < e) { ret->fragment = zend_string_init(p, (e - p), 0); php_replace_controlchars_ex(ZSTR_VAL(ret->fragment), ZSTR_LEN(ret->fragment)); + } else { + ret->fragment = ZSTR_EMPTY_ALLOC(); } e = p-1; }