From d36a16a4df5ed54b80dfc1579c339bad24ba6b0c Mon Sep 17 00:00:00 2001 From: Even Brenden Date: Thu, 27 Jan 2022 23:59:20 +0100 Subject: [PATCH] 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. --- pandoc.cabal | 2 ++ src/Text/Pandoc/Class/PandocMonad.hs | 22 ++++++++++++++++++---- test/command/7861.md | 7 +++++++ test/command/7861.yaml | 0 test/command/7861/metadata/placeholder | 0 5 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 test/command/7861.md create mode 100644 test/command/7861.yaml create mode 100644 test/command/7861/metadata/placeholder 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 diff --git a/test/command/7861/metadata/placeholder b/test/command/7861/metadata/placeholder new file mode 100644 index 000000000..e69de29bb