pup::path roots a UNC path on its two leading separators rather than on its authority, so .. can pop the host and share:
\\host\share\..\..\x normalizes to //x
//x is not a real UNC path. A share is not a directory you can ascend out of, so //host/share should be un-poppable the way C:/ already is.
Why this is confined, and why it is not urgent
Verified on the #388 branch, both by the implementer and independently:
- The path stays rooted, so containment still refuses it —
normalize's absolute arm drops any further .., and the build-root check only asks whether a path resolves inside the build root. There is no escape here and no security consequence.
- The wrongness is therefore confined to the spelling of an already-refused path.
Why it was not fixed in #388
The obvious fix — a share-aware root, //host/share un-poppable like C:/ — was built first and refuted by the module's own property test, path::normalize obeys its laws:
input //a/. -> "." becomes the share
output //a/./ -> not in normal form; the law breaks
Reconciling an un-poppable authority with dot-segment normal form is a design question rather than a patch, so #388 took the two-separator root and declared the consequence in a one-line comment at the site.
Sketch for whoever takes it
Roughly eight lines in root_length: after recognising the two leading separators, scan forward past the authority and the share, and return that longer prefix as the root. Plus a dot-segment guard, because the naive version is what the laws test refuted.
The constraint the next person must satisfy is that input, exactly: //a/. must not end up treating . as the share, and the output must be in normal form. Any candidate fix should be run against path::normalize obeys its laws before anything else.
Follow-up to the path-law work in #388.
pup::pathroots a UNC path on its two leading separators rather than on its authority, so..can pop the host and share://xis not a real UNC path. A share is not a directory you can ascend out of, so//host/shareshould be un-poppable the wayC:/already is.Why this is confined, and why it is not urgent
Verified on the #388 branch, both by the implementer and independently:
normalize's absolute arm drops any further.., and the build-root check only asks whether a path resolves inside the build root. There is no escape here and no security consequence.Why it was not fixed in #388
The obvious fix — a share-aware root,
//host/shareun-poppable likeC:/— was built first and refuted by the module's own property test,path::normalize obeys its laws:Reconciling an un-poppable authority with dot-segment normal form is a design question rather than a patch, so #388 took the two-separator root and declared the consequence in a one-line comment at the site.
Sketch for whoever takes it
Roughly eight lines in
root_length: after recognising the two leading separators, scan forward past the authority and the share, and return that longer prefix as the root. Plus a dot-segment guard, because the naive version is what the laws test refuted.The constraint the next person must satisfy is that input, exactly:
//a/.must not end up treating.as the share, and the output must be in normal form. Any candidate fix should be run againstpath::normalize obeys its lawsbefore anything else.Follow-up to the path-law work in #388.