Fix using lookupkey inside a subdirectory

Caused by dirContains ".." "foo" being incorrectly False.

Also added a test of dirContains, which includes all the previous bug fixes
I could find and some obvious cases.

Reversion in version 8.20211011

Sponsored-by: Brett Eisenberg on Patreon
This commit is contained in:
Joey Hess 2021-10-26 14:58:44 -04:00
parent 91eb393df4
commit b2c48fb86b
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 43 additions and 3 deletions

View file

@ -97,6 +97,7 @@ dirContains a b = a == b
|| a' == b'
|| (a'' `B.isPrefixOf` b' && avoiddotdotb)
|| a' == "." && normalise ("." </> b') == b' && nodotdot b'
|| dotdotcontains
where
a' = norm a
a'' = addTrailingPathSeparator a'
@ -115,9 +116,27 @@ dirContains a b = a == b
-}
avoiddotdotb = nodotdot $ B.drop (B.length a'') b'
nodotdot p = all
(\s -> dropTrailingPathSeparator s /= "..")
(splitPath p)
nodotdot p = all (not . isdotdot) (splitPath p)
isdotdot s = dropTrailingPathSeparator s == ".."
{- This handles the case where a is ".." or "../.." etc,
- and b is "foo" or "../foo" etc. The rule is that when
- a is entirely ".." components, b is under it when it starts
- with fewer ".." components.
-
- Due to the use of norm, cases like "../../foo/../../" get
- converted to eg "../../../" and so do not need to be handled
- specially here.
-}
dotdotcontains
| isAbsolute b' = False
| otherwise =
let aps = splitPath a'
bps = splitPath b'
in if all isdotdot aps
then length (takeWhile isdotdot bps) < length aps
else False
{- Given an original list of paths, and an expanded list derived from it,
- which may be arbitrarily reordered, generates a list of lists, where