IsPrefixOf decides containment by comparing normalized path strings segment by segment. That is correct as long as neither path begins with a .. reference — but .. moves up, so a string prefix stops implying containment:
new LocalPath("..").IsPrefixOf(new LocalPath("foo")); // false, though foo is CWD/foo, which is under ..
new LocalPath("..").IsPrefixOf(new LocalPath("../..")); // true, though ../.. is above .., not under it
Answering these correctly means modelling how far above the current directory a path starts — the number of leading .. references — and comparing that together with the remaining segments, rather than comparing strings.
This affects AbsolutePath too: /.. survives normalization, so new AbsolutePath("/..") is a constructible value.
Both behaviors predate #223. A closely related case was fixed there: the empty path (the current directory) was reported as a prefix of ../evil.
IsPrefixOfdecides containment by comparing normalized path strings segment by segment. That is correct as long as neither path begins with a..reference — but..moves up, so a string prefix stops implying containment:Answering these correctly means modelling how far above the current directory a path starts — the number of leading
..references — and comparing that together with the remaining segments, rather than comparing strings.This affects
AbsolutePathtoo:/..survives normalization, sonew AbsolutePath("/..")is a constructible value.Both behaviors predate #223. A closely related case was fixed there: the empty path (the current directory) was reported as a prefix of
../evil.