MCPcopy Create free account
hub / github.com/TanStack/router / decodePath

Function decodePath

packages/router-core/src/utils.ts:635–668  ·  view source on GitHub ↗
(path: string)

Source from the content-addressed store, hash-verified

633}
634
635export function decodePath(path: string) {
636 if (!path) return { path, handledProtocolRelativeURL: false }
637
638 // Fast path: most paths are already decoded and safe.
639 // Only fall back to the slower scan/regex path when we see a '%' (encoded),
640 // a backslash (explicitly handled), a control character, or a protocol-relative
641 // prefix which needs collapsing.
642 // eslint-disable-next-line no-control-regex
643 if (!/[%\\\x00-\x1f\x7f]/.test(path) && !path.startsWith('//')) {
644 return { path, handledProtocolRelativeURL: false }
645 }
646
647 const re = /%25|%5C/gi
648 let cursor = 0
649 let result = ''
650 let match
651 while (null !== (match = re.exec(path))) {
652 result += decodeSegment(path.slice(cursor, match.index)) + match[0]
653 cursor = re.lastIndex
654 }
655 result = result + decodeSegment(cursor ? path.slice(cursor) : path)
656
657 // Prevent open redirect via protocol-relative URLs (e.g. "//evil.com")
658 // This is defense-in-depth: since control characters are no longer decoded,
659 // paths like "/%0d/evil.com" can no longer become "//evil.com". But we keep
660 // this check to guard against other edge cases.
661 let handledProtocolRelativeURL = false
662 if (result.startsWith('//')) {
663 handledProtocolRelativeURL = true
664 result = '/' + result.replace(/^\/+/, '')
665 }
666
667 return { path: result, handledProtocolRelativeURL }
668}
669
670/**
671 * Encodes a path the same way `new URL()` would, but without the overhead of full URL parsing.

Callers 4

parseMethod · 0.90
buildMethod · 0.90
getNormalizedURLFunction · 0.90
utils.test.tsFile · 0.90

Calls 3

decodeSegmentFunction · 0.85
execMethod · 0.65
replaceMethod · 0.65

Tested by

no test coverage detected