@@ -489,64 +489,63 @@ export function findLast<T>(
489489 return undefined
490490}
491491
492- const DECODE_IGNORE_LIST = Array . from (
493- new Map ( [
494- [ '%' , '%25' ] ,
495- [ '\\' , '%5C' ] ,
496- ] ) . values ( ) ,
497- )
492+ const DECODE_IGNORE_LIST = [
493+ '%25' , // %
494+ '%5C' , // \
495+ ]
498496
499- export function decodePath (
497+ function splitAndDecode (
500498 part : string ,
501- decodeIgnore : Array < string > = DECODE_IGNORE_LIST ,
499+ decodeIgnore : Array < string > ,
500+ startIndex = 0 ,
502501) : string {
503- function splitAndDecode (
504- part : string ,
505- decodeIgnore : Array < string > ,
506- startIndex = 0 ,
507- ) : string {
508- // decode the path / path segment by splitting it into parts defined by the ignore list.
509- // once these pieces have been decoded, join them back together to form the final decoded path segment with the ignored character in place.
510- // we walk through the ignore list linearly, breaking the segment up into pieces and decoding each piece individually.
511- // use index traversal to avoid making unnecessary copies of the array.
512- for ( let i = startIndex ; i < decodeIgnore . length ; i ++ ) {
513- const char = decodeIgnore [ i ] ! . toUpperCase ( )
514-
515- // check if the part includes the current ignore character
516- // if it doesn't continue to the next ignore character
517- if ( part . includes ( char ) ) {
518- // split the part into pieces that needs to be checked and decoded
519- const partsToDecode = part . split ( char )
520- const partsToJoin : Array < string > = [ ]
521-
522- // now check and decode each piece individually taking into consideration the remaining ignored characters.
523- // since we are walking through the list linearly, we only need to consider ignore items not yet traversed.
524- for ( const partToDecode of partsToDecode ) {
525- // once we have traversed the entire ignore list, each decoded part is returned.
526- partsToJoin . push ( splitAndDecode ( partToDecode , decodeIgnore , i + 1 ) )
527- }
528-
529- // and join them back together to form the final decoded path segment with the ignored character in place.
530- return partsToJoin . join ( char )
502+ // decode the path / path segment by splitting it into parts defined by the ignore list.
503+ // once these pieces have been decoded, join them back together to form the final decoded path segment with the ignored character in place.
504+ // we walk through the ignore list linearly, breaking the segment up into pieces and decoding each piece individually.
505+ // use index traversal to avoid making unnecessary copies of the array.
506+ for ( let i = startIndex ; i < decodeIgnore . length ; i ++ ) {
507+ const char = decodeIgnore [ i ] ! . toUpperCase ( )
508+
509+ // check if the part includes the current ignore character
510+ // if it doesn't continue to the next ignore character
511+ if ( part . includes ( char ) ) {
512+ // split the part into pieces that needs to be checked and decoded
513+ const partsToDecode = part . split ( char )
514+ const partsToJoin = new Array < string > ( partsToDecode . length )
515+
516+ // now check and decode each piece individually taking into consideration the remaining ignored characters.
517+ // since we are walking through the list linearly, we only need to consider ignore items not yet traversed.
518+ for ( let j = 0 ; j < partsToDecode . length ; j ++ ) {
519+ const partToDecode = partsToDecode [ j ] !
520+ // once we have traversed the entire ignore list, each decoded part is returned.
521+ partsToJoin [ j ] = splitAndDecode ( partToDecode , decodeIgnore , i + 1 )
531522 }
532- }
533523
534- // once we have reached the end of the ignore list, we start walking back returning each decoded part.
535- // should there be no matching characters, the path segment as a whole will be decoded.
536- try {
537- return decodeURI ( part )
538- } catch {
539- // if the decoding fails, try to decode the various parts leaving the malformed tags in place
540- return part . replaceAll ( / % [ 0 - 9 A - F ] { 2 } / g, ( match ) => {
541- try {
542- return decodeURI ( match )
543- } catch {
544- return match
545- }
546- } )
524+ // and join them back together to form the final decoded path segment with the ignored character in place.
525+ return partsToJoin . join ( char )
547526 }
548527 }
549528
529+ // once we have reached the end of the ignore list, we start walking back returning each decoded part.
530+ // should there be no matching characters, the path segment as a whole will be decoded.
531+ try {
532+ return decodeURI ( part )
533+ } catch {
534+ // if the decoding fails, try to decode the various parts leaving the malformed tags in place
535+ return part . replaceAll ( / % [ 0 - 9 A - F ] { 2 } / g, ( match ) => {
536+ try {
537+ return decodeURI ( match )
538+ } catch {
539+ return match
540+ }
541+ } )
542+ }
543+ }
544+
545+ export function decodePath (
546+ part : string ,
547+ decodeIgnore : Array < string > = DECODE_IGNORE_LIST ,
548+ ) : string {
550549 // if the path segment does not contain any encoded uri components return the path as is
551550 if ( part === '' || ! / % [ 0 - 9 A - F a - f ] { 2 } / g. test ( part ) ) return part
552551
0 commit comments