Skip to content

Commit

Permalink
Url: optimized unescape() performance
Browse files Browse the repository at this point in the history
  • Loading branch information
JanTvrdik committed Dec 18, 2014
1 parent 88784b1 commit cab8785
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
18 changes: 10 additions & 8 deletions src/Http/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ public function __toString()


/**
* Similar to rawurldecode, but preserve reserved chars encoded.
* Similar to rawurldecode, but preserves reserved chars encoded.
* @param string to decode
* @param string reserved characters
* @return string
Expand All @@ -461,14 +461,16 @@ public static function unescape($s, $reserved = '%;/?:@&=+$,')
// reserved (@see RFC 2396) = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
// within a path segment, the characters "/", ";", "=", "?" are reserved
// within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", "$" are reserved.
preg_match_all('#(?<=%)[a-f0-9][a-f0-9]#i', $s, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
foreach (array_reverse($matches) as $match) {
$ch = chr(hexdec($match[0][0]));
if (strpos($reserved, $ch) === FALSE) {
$s = substr_replace($s, $ch, $match[0][1] - 1, 3);
}
if ($reserved === '') {
return rawurldecode($s);
}
$pattern = '#((?:%(?:' . implode('|', str_split(bin2hex($reserved), 2)) . '))++)#i';
$parts = preg_split($pattern, $s, -1, PREG_SPLIT_DELIM_CAPTURE);
$count = count($parts);
for ($i = 0; $i < $count; $i++) {
$parts[$i] = ($i & 1) ? strtoupper($parts[$i]) : rawurldecode($parts[$i]);
}
return $s;
return implode('', $parts);
}

}
21 changes: 21 additions & 0 deletions tests/Http/Url.unescape.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/**
* Test: Nette\Http\Url unescape.
*/

use Nette\Http\Url,
Tester\Assert;


require __DIR__ . '/../bootstrap.php';


Assert::same( 'foo + bar', Url::unescape('foo + bar') );
Assert::same( 'foo + bar', Url::unescape('foo + bar', '') );
Assert::same( 'foo', Url::unescape('%66%6F%6F', '') );
Assert::same( 'f%6F%6F', Url::unescape('%66%6F%6F', 'o') );
Assert::same( '%66oo', Url::unescape('%66%6F%6F', 'f') );
Assert::same( '%66%6F%6F', Url::unescape('%66%6F%6F', 'fo') );
Assert::same( '%66%6F%6F', Url::unescape('%66%6f%6f', 'fo') );
Assert::same( "%00\x01%02", Url::unescape('%00%01%02', "\x00\x02") );

0 comments on commit cab8785

Please sign in to comment.