Incorrect parsing URL with decoded semicolon
smesny opened this issue · 1 comments
Version: 3.0.3
Bug Description
With commit Url::parseQuery() accepts separator ;, there is different behavirour PHP vs NETTE regarding parsing URL variables with decoded semicolon. IMHO it wasn't correct even before this commit, because Url::parseQuery() completely ignores php.ini directive "arg_separator.input".
Steps To Reproduce
PHP with default settings (arg_separator.input="&"), these two blocks of code return two different results:
const TEST_URL = 'https://www.example.com/?example=1;2';
//PHP
$values = [];
$url = parse_url(TEST_URL);
parse_str($url['query'], $values);
print_r($values);
//NETTE
$url = new \Nette\Http\Url(TEST_URL);
$query = $url->getQuery();
$values = \Nette\Http\Url::parseQuery($query);
print_r($values);
Expected Behavior
They should both return this:
Array ( [example] => 1;2 )
Possible Solution
Like in eg. \Nette\Routing\Route::constructUrl(), we should apply here "arg_separator.input":
public static function parseQuery(string $s): array
{
$sep = ini_get('arg_separator.input');
if (!$sep) $sep = '&';
$s = str_replace(['%5B', '%5b'], '[', $s);
$s = preg_replace('#(['. $sep .'])([^['. $sep .'=]+)([^'. $sep .']*)#', $sep[0] . '0[$2]$3', $sep[0] . $s);
parse_str($s, $res);
return $res[0] ?? [];
}