Skip to content

Commit e2cbaf9

Browse files
committed
minor enhancements
1 parent 50e7cb2 commit e2cbaf9

1 file changed

Lines changed: 30 additions & 16 deletions

File tree

packages/router-core/src/utils.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -489,25 +489,25 @@ export function findLast<T>(
489489
return undefined
490490
}
491491

492-
const DECODE_IGNORE_LIST = [
493-
'%',
494-
'\\',
495-
'/',
496-
';',
497-
':',
498-
'@',
499-
'&',
500-
'=',
501-
'+',
502-
'$',
503-
',',
504-
].map((c) => encodeURIComponent(c))
492+
const DECODE_IGNORE_LIST = new Map([
493+
['%', '%25'],
494+
['\\', '%5C'],
495+
['/', '%2F'],
496+
[';', '%3B'],
497+
[':', '%3A'],
498+
['@', '%40'],
499+
['&', '%26'],
500+
['=', '%3D'],
501+
['+', '%2B'],
502+
['$', '%24'],
503+
[',', '%2C'],
504+
])
505505

506506
export function decodePathSegment(
507507
part: string,
508-
decodeIgnore: Array<string> = DECODE_IGNORE_LIST,
508+
decodeIgnore: Array<string> = Array.from(DECODE_IGNORE_LIST.values()),
509509
startIndex = 0,
510-
) {
510+
): string {
511511
function decode(part: string) {
512512
try {
513513
return decodeURIComponent(part)
@@ -523,22 +523,36 @@ export function decodePathSegment(
523523
}
524524
}
525525

526-
if (part === '' || !part.match(/%../g)) return part
526+
// if the path segment does not contain any encoded uri components return the path as is
527+
if (part === '' || !part.match(/%[0-9A-Fa-f]{2}/g)) return part
527528

529+
// decode the path / path segment by splitting it into parts defined by the ignore list.
530+
// once these pieces have been decoded, join them back together to form the final decoded path segment with the ignored character in place.
531+
// we walk through the ignore list linearly, breaking the segment up into pieces and decoding each piece individually.
532+
// use index traversal to avoid making unnecessary copies of the array.
528533
for (let i = startIndex; i < decodeIgnore.length; i++) {
529534
const char = decodeIgnore[i]
530535

536+
// check if the part includes the current ignore character
537+
// if it doesn't continue to the next ignore character
531538
if (char && part.includes(char)) {
539+
// split the part into pieces that needs to be checked and decoded
532540
const partsToDecode = part.split(char)
533541
const partsToJoin: Array<string> = []
534542

543+
// now check and decode each piece individually taking into consideration the remaining ignored characters.
544+
// since we are walking through the list linearly, we only need to consider ignore items not yet traversed.
535545
for (const partToDecode of partsToDecode) {
546+
// once we have traversed the entire ignore list, each decoded part is returned.
536547
partsToJoin.push(decodePathSegment(partToDecode, decodeIgnore, i + 1))
537548
}
538549

550+
// and join them back together to form the final decoded path segment with the ignored character in place.
539551
return partsToJoin.join(char)
540552
}
541553
}
542554

555+
// once we have reached the end of the ignore list, we start walking back returning each decoded part.
556+
// should there be no matching characters, the path segment as a whole will be decoded.
543557
return decode(part)
544558
}

0 commit comments

Comments
 (0)