diff options
author | Christian A. Weber | 2017-12-07 17:20:51 +0100 |
---|---|---|
committer | Christian A. Weber | 2017-12-07 17:20:51 +0100 |
commit | 2ed5008463d434e943247a357a2f66ac8fa8a17a (patch) | |
tree | 8801b32925772e8894794b66a40ec16c49f50680 | |
parent | 6c9029219c6611e5f2c7739fe67931ef2d1408f5 (diff) | |
download | itools-2ed5008463d434e943247a357a2f66ac8fa8a17a.tar.gz itools-2ed5008463d434e943247a357a2f66ac8fa8a17a.tar.bz2 itools-2ed5008463d434e943247a357a2f66ac8fa8a17a.zip |
if no key => value params are supplied, don't kill query params without value such as foo or foo=
-rw-r--r-- | it_html.class | 32 | ||||
-rw-r--r-- | tests/U_tests.json | 10 |
2 files changed, 22 insertions, 20 deletions
diff --git a/it_html.class b/it_html.class index 670054c..1f705fb 100644 --- a/it_html.class +++ b/it_html.class @@ -538,7 +538,6 @@ static function U(/* ... */) if (!($u = @parse_url($base))) list($u['path'], $u['query']) = explode("?", $base, 2); - $u['params'] = it_url::parse_str($u['query']); $u['host'] = preg_match('/[^-_.0-9a-z]/i', $u['host']) && function_exists('idn_to_ascii') && ($idnahost = idn_to_ascii($GLOBALS['it_html']->p['charset'] == "iso-8859-1" ? utf8_encode($u['host']) : $u['host'])) ? $idnahost : $u['host']; # Punycode hostname to include into webpage $u['host'] = preg_replace_callback('/[^-_.0-9a-z\x80-\xff]/i', function($m) { return rawurlencode($m[0]); }, $u['host']); # Encode garbage chars in host @@ -551,26 +550,29 @@ static function U(/* ... */) $schemepart = $hostpart ? ($u['scheme'] ? $u['scheme'] . ":" : "") . "//$hostpart" : ($u['scheme'] == "mailto" ? $u['scheme'] . ":" : ""); - - # if params replace url parameters that are present in base, replace them but keep their order - foreach ($u['params'] as $key => $dummy) - if (isset($params[$key])) - $u['params'][$key] = $params[$key]; - + # sanitize path and fragment $u['path'] = preg_replace('|\\\\|', '/', $u['path']); # turn \ to / - foreach (['path', 'fragment'] as $key) - $u[$key] = preg_replace_callback( - '/[^-a-z0-9_.+!*(),:?@&=\/~$%#]|%(?![0-9a-f]{2})/i', - function($m) { return rawurlencode($m[0]); }, - $u[$key] - ); + foreach (['path', 'query', 'fragment'] as $key) + $u[$key] = preg_replace_callback('/[^-a-z0-9_.+!*(),:?@&=\/~$%#]|%(?![0-9a-f]{2})/i', function($m) { return rawurlencode($m[0]); }, $u[$key]); + # convert empty http url path to / if (!$u['path'] && $hostpart && preg_match('/^(https?)?$/', $u['scheme'])) $u['path'] = '/'; - $queryparams = it_url::params($u['params'] + $params); + # if we supplied params, add/replace them in the existing url, removing empty existing params such as foo=&bar + if ($params) + { + $u['params'] = it_url::parse_str($u['query']); + + # if params replace url parameters that are present in base, replace them but keep their order + foreach ($u['params'] as $key => $dummy) + if (isset($params[$key])) + $u['params'][$key] = $params[$key]; + + $u['query'] = it_url::params($u['params'] + $params); + } - return $schemepart . $u['path'] . ($queryparams ? "?" . $queryparams : "") . ($u['fragment'] ? "#" . $u['fragment'] : "");; + return $schemepart . $u['path'] . ($u['query'] ? "?" . $u['query'] : "") . ($u['fragment'] ? "#" . $u['fragment'] : ""); } diff --git a/tests/U_tests.json b/tests/U_tests.json index 5614cbb..a8ad63d 100644 --- a/tests/U_tests.json +++ b/tests/U_tests.json @@ -43,14 +43,14 @@ { "args": ["/foo.html?bar="], - "exp": "/foo.html", - "name": "U() empty parameter in base removed (1)" + "exp": "/foo.html?bar=", + "name": "U() empty parameter with = in base must stay" }, { - "args": ["/foo.html?bar"], - "exp": "/foo.html", - "name": "U() empty parameter in base removed (2)" + "args": ["/foo.html?foo=bar&qux"], + "exp": "/foo.html?foo=bar&qux", + "name": "U() empty parameter in base without = must stay" }, { |