summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Brenden <evenbrenden@gmail.com>2022-01-27 23:59:20 +0100
committerJohn MacFarlane <jgm@berkeley.edu>2022-01-28 08:51:27 -0800
commitd36a16a4df5ed54b80dfc1579c339bad24ba6b0c (patch)
treed07ed9859f4f9664552316d2f499eb7c55a37b8a
parente1f8c4b396354f8bf29c3b9f04e9b3f980c70d31 (diff)
Don't read files outside of user data directory
If a file path does not exist relative to the working directory, but it does exist relative to the user data directory, and it exists outside of the user data directory, do not read it. This applies to readDataFile and readMetadataFile in PandocMonad and, by extension, any module that uses these by passing them relative paths.
-rw-r--r--pandoc.cabal2
-rw-r--r--src/Text/Pandoc/Class/PandocMonad.hs22
-rw-r--r--test/command/7861.md7
-rw-r--r--test/command/7861.yaml0
-rw-r--r--test/command/7861/metadata/placeholder0
5 files changed, 27 insertions, 4 deletions
diff --git a/pandoc.cabal b/pandoc.cabal
index 851df99d9..ba54dee31 100644
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -254,6 +254,8 @@ extra-source-files:
test/command/5876.yaml
test/command/5876/metadata/5876.yaml
test/command/5876/metadata/command/5876.yaml
+ test/command/7861.yaml
+ test/command/7861/metadata/placeholder
test/docbook-chapter.docbook
test/docbook-reader.docbook
test/docbook-xref.docbook
diff --git a/src/Text/Pandoc/Class/PandocMonad.hs b/src/Text/Pandoc/Class/PandocMonad.hs
index 05cc156d0..235e10e40 100644
--- a/src/Text/Pandoc/Class/PandocMonad.hs
+++ b/src/Text/Pandoc/Class/PandocMonad.hs
@@ -574,11 +574,25 @@ getDefaultReferencePptx = do
Nothing -> foldr addEntryToArchive emptyArchive <$>
mapM pathToEntry paths
--- | Read file from user data directory or,
--- if not found there, from the default data files.
+-- | Checks if the file path is relative to a parent directory.
+isRelativeToParentDir :: FilePath -> Bool
+isRelativeToParentDir fname =
+ let canonical = makeCanonical fname
+ in length canonical >= 2 && take 2 canonical == ".."
+
+-- | Returns possible user data directory if the file path refers to a file or
+-- subdirectory within it.
+checkUserDataDir :: PandocMonad m => FilePath -> m (Maybe FilePath)
+checkUserDataDir fname =
+ if isRelative fname && not (isRelativeToParentDir fname)
+ then getUserDataDir
+ else return Nothing
+
+--- | Read file from user data directory or,
+--- if not found there, from the default data files.
readDataFile :: PandocMonad m => FilePath -> m B.ByteString
readDataFile fname = do
- datadir <- getUserDataDir
+ datadir <- checkUserDataDir fname
case datadir of
Nothing -> readDefaultDataFile fname
Just userDir -> do
@@ -595,7 +609,7 @@ readMetadataFile fname = do
if existsInWorkingDir
then readFileStrict fname
else do
- dataDir <- getUserDataDir
+ dataDir <- checkUserDataDir fname
case dataDir of
Nothing ->
throwError $ PandocCouldNotFindMetadataFileError $ T.pack fname
diff --git a/test/command/7861.md b/test/command/7861.md
new file mode 100644
index 000000000..a5b68de6f
--- /dev/null
+++ b/test/command/7861.md
@@ -0,0 +1,7 @@
+```
+% pandoc -s -t native --data-dir=command/7861 --metadata-file=../../7861.yaml
+Hello
+^D
+2> Could not find metadata file ../../7861.yaml
+=> 98
+```
diff --git a/test/command/7861.yaml b/test/command/7861.yaml
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/command/7861.yaml
diff --git a/test/command/7861/metadata/placeholder b/test/command/7861/metadata/placeholder
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/command/7861/metadata/placeholder