Skip to content

Commit c095d6e

Browse files
committed
[#197] Recover indirections through parent check
1 parent cb6c8ae commit c095d6e

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

src/Xrefcheck/System.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ module Xrefcheck.System
1313
, getDirsBetweenRootAndFile
1414
, getPosixRelativeChild
1515
, getPosixRelativeOrAbsoluteChild
16+
, hasIndirectionThroughParent
1617
, takeDirectory
1718
, takeExtension
1819
, (</)
@@ -129,6 +130,18 @@ getPosixRelativeOrAbsoluteChild :: CanonicalPath -> CanonicalPath -> FilePath
129130
getPosixRelativeOrAbsoluteChild root child =
130131
fromMaybe (unCanonicalPath child) (getPosixRelativeChild root child)
131132

133+
-- | Check if some 'FilePath' passes through its parent while
134+
-- expanding indirections.
135+
hasIndirectionThroughParent :: FilePath -> Bool
136+
hasIndirectionThroughParent = go 0 . FP.splitDirectories
137+
where
138+
go :: Int -> [FilePath] -> Bool
139+
go _ [] = False
140+
go 0 (".." : _) = True
141+
go acc (".." : xs) = go (acc - 1) xs
142+
go acc ("." : xs) = go acc xs
143+
go acc (_ : xs) = go (acc + 1) xs
144+
132145
-- | Extend some 'CanonicalPath' with a given relative 'FilePath'.
133146
--
134147
-- The right-hand side 'FilePath' can use both Posix and Windows

src/Xrefcheck/Verify.hs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,18 @@ verifyReference
533533

534534
isVirtual canonicalRoot = matchesGlobPatterns canonicalRoot (ecIgnoreLocalRefsTo cExclusions)
535535

536-
-- Checks a local file reference. The `shownFilepath` argument is intended
537-
-- to be shown in the error report when the `referredFile` path is not
538-
-- a child of `canonicalRoot`, so it allows indirections and should be
539-
-- suitable for being shown to the user.
536+
-- Checks a local file reference.
537+
--
538+
-- The `shownFilepath` argument is intended to be shown in the error
539+
-- report when the `referredFile` path is not a child of `canonicalRoot`,
540+
-- so it allows indirections and should be suitable for being shown to
541+
-- the user. Also, it will be considered as outside the repository if
542+
-- it is relative and its idirections pass through the repository root.
540543
checkRef mAnchor canonicalRoot referredFile shownFilepath = verifying $
541544
unless (isVirtual canonicalRoot referredFile) do
545+
when (hasIndirectionThroughParent shownFilepath) $
546+
throwError $ LocalFileOutsideRepo shownFilepath
547+
542548
referredFileRelative <-
543549
case getPosixRelativeChild canonicalRoot referredFile of
544550
Just ps -> pure ps

tests/golden/check-local-refs/expected2.gold

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,24 @@
9797
File does not exist:
9898
dir1/dir2/d2f2.md
9999

100+
➥ In file dir2/d2f1.md
101+
bad reference (relative) at src:51:1-42:
102+
- text: "path-through-top-dir"
103+
- link: ../../dir1/d1f1.md
104+
- anchor: -
105+
106+
Link targets a local file outside repository:
107+
dir2/../../dir1/d1f1.md
108+
109+
➥ In file dir2/d2f1.md
110+
bad reference (relative) at src:52:1-75:
111+
- text: "path-through-top-dir-with-anchor"
112+
- link: ../../dir1/d1f1.md
113+
- anchor: existing-anchor-d1f1
114+
115+
Link targets a local file outside repository:
116+
dir2/../../dir1/d1f1.md
117+
100118
➥ In file dir2/d2f1.md
101119
bad reference (relative) at src:53:1-26:
102120
- text: "ref-to-d0"
@@ -124,4 +142,4 @@
124142
Link targets a local file outside repository:
125143
b/../../b.md
126144

127-
Invalid references dumped, 14 in total.
145+
Invalid references dumped, 16 in total.

tests/golden/check-local-refs/expected3.gold

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,22 @@
8888
File does not exist:
8989
dir1/dir2/d2f2.md
9090

91-
Invalid references dumped, 10 in total.
91+
➥ In file dir2/d2f1.md
92+
bad reference (relative) at src:51:1-42:
93+
- text: "path-through-top-dir"
94+
- link: ../../dir1/d1f1.md
95+
- anchor: -
96+
97+
Link targets a local file outside repository:
98+
dir2/../../dir1/d1f1.md
99+
100+
➥ In file dir2/d2f1.md
101+
bad reference (relative) at src:52:1-75:
102+
- text: "path-through-top-dir-with-anchor"
103+
- link: ../../dir1/d1f1.md
104+
- anchor: existing-anchor-d1f1
105+
106+
Link targets a local file outside repository:
107+
dir2/../../dir1/d1f1.md
108+
109+
Invalid references dumped, 12 in total.

0 commit comments

Comments
 (0)