@@ -451,7 +451,7 @@ public function __toString()
451451
452452
453453 /**
454- * Similar to rawurldecode, but preserve reserved chars encoded.
454+ * Similar to rawurldecode, but preserves reserved chars encoded.
455455 * @param string to decode
456456 * @param string reserved characters
457457 * @return string
@@ -461,14 +461,16 @@ public static function unescape($s, $reserved = '%;/?:@&=+$,')
461461 // reserved (@see RFC 2396) = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
462462 // within a path segment, the characters "/", ";", "=", "?" are reserved
463463 // within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", "$" are reserved.
464- preg_match_all ('#(?<=%)[a-f0-9][a-f0-9]#i ' , $ s , $ matches , PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
465- foreach (array_reverse ($ matches ) as $ match ) {
466- $ ch = chr (hexdec ($ match [0 ][0 ]));
467- if (strpos ($ reserved , $ ch ) === FALSE ) {
468- $ s = substr_replace ($ s , $ ch , $ match [0 ][1 ] - 1 , 3 );
469- }
464+ if ($ reserved === '' ) {
465+ return rawurldecode ($ s );
466+ } else {
467+ $ pattern = '#(?:%(?! ' . implode ('| ' , str_split (bin2hex ($ reserved ), 2 )) . ')[0-9a-f]{2})++#i ' ;
468+ return preg_replace_callback (
469+ $ pattern ,
470+ function ($ m ) { return rawurldecode ($ m [0 ]); },
471+ $ s
472+ );
470473 }
471- return $ s ;
472474 }
473475
474476}
0 commit comments