diff options
| author | John MacFarlane <jgm@berkeley.edu> | 2023-06-23 09:25:32 -0700 |
|---|---|---|
| committer | John MacFarlane <jgm@berkeley.edu> | 2023-06-23 09:27:04 -0700 |
| commit | df4f13b262f7be5863042f8a5a1c365282c81f07 (patch) | |
| tree | 8a522ae8a58496fe97a9722b3171473921d79691 | |
| parent | 54561e9a6667b36a8452b01d2def9e3642013dd6 (diff) | |
More fixes to 5e381e3.
These changes recognize that parseURI does not unescape the path.
Another change is that the canonical form of the path used as the
MediaBag key retains percent-encoding, if present; we only unescape
the string when writing to a file.
See #8918.
Some tests are needed before the issue can be closed.
| -rw-r--r-- | src/Text/Pandoc/Class/IO.hs | 6 | ||||
| -rw-r--r-- | src/Text/Pandoc/MediaBag.hs | 9 |
2 files changed, 8 insertions, 7 deletions
diff --git a/src/Text/Pandoc/Class/IO.hs b/src/Text/Pandoc/Class/IO.hs index 91e1dc625..86ed83c89 100644 --- a/src/Text/Pandoc/Class/IO.hs +++ b/src/Text/Pandoc/Class/IO.hs @@ -50,7 +50,7 @@ import Network.HTTP.Client.Internal (addProxy) import Network.HTTP.Client.TLS (mkManagerSettings) import Network.HTTP.Types.Header ( hContentType ) import Network.Socket (withSocketsDo) -import Network.URI (URI(..), parseURI) +import Network.URI (URI(..), parseURI, unEscapeString) import System.Directory (createDirectoryIfMissing) import System.Environment (getEnv) import System.FilePath ((</>), takeDirectory, normalise) @@ -124,7 +124,7 @@ openURL :: (PandocMonad m, MonadIO m) => Text -> m (B.ByteString, Maybe MimeType openURL u | Just (URI{ uriScheme = "data:", uriPath = upath }) <- parseURI (T.unpack u) = do - let (mime, rest) = break (== ',') upath + let (mime, rest) = break (== ',') $ unEscapeString upath let contents = UTF8.fromString $ drop 1 rest return (decodeBase64Lenient contents, Just (T.pack mime)) | otherwise = do @@ -224,7 +224,7 @@ writeMedia :: (PandocMonad m, MonadIO m) -> m () writeMedia dir (fp, _mt, bs) = do -- we normalize to get proper path separators for the platform - let fullpath = normalise $ dir </> fp + let fullpath = normalise $ dir </> unEscapeString fp liftIOError (createDirectoryIfMissing True) (takeDirectory fullpath) report $ Extracting (T.pack fullpath) logIOError $ BL.writeFile fullpath bs diff --git a/src/Text/Pandoc/MediaBag.hs b/src/Text/Pandoc/MediaBag.hs index fdec4e954..bb75f4591 100644 --- a/src/Text/Pandoc/MediaBag.hs +++ b/src/Text/Pandoc/MediaBag.hs @@ -37,6 +37,7 @@ import Data.Text (Text) import qualified Data.Text as T import Data.Digest.Pure.SHA (sha1, showDigest) import Network.URI (URI (..), parseURI, isURI) +import Data.List (isInfixOf) data MediaItem = MediaItem @@ -56,11 +57,11 @@ instance Show MediaBag where show bag = "MediaBag " ++ show (mediaDirectory bag) -- | We represent paths with /, in normalized form. Percent-encoding --- is resolved. +-- is not resolved. canonicalize :: FilePath -> Text canonicalize fp | isURI fp = T.pack fp - | otherwise = T.replace "\\" "/" . T.pack . normalise . unEscapeString $ fp + | otherwise = T.replace "\\" "/" . T.pack . normalise $ fp -- | Delete a media item from a 'MediaBag', or do nothing if no item corresponds -- to the given path. @@ -83,12 +84,12 @@ insertMedia fp mbMime contents (MediaBag mediamap) = , mediaContents = contents , mediaMimeType = mt } fp' = canonicalize fp - fp'' = T.unpack fp' + fp'' = unEscapeString $ T.unpack fp' uri = parseURI fp newpath = if Posix.isRelative fp'' && Windows.isRelative fp'' && isNothing uri - && not (".." `T.isInfixOf` fp') + && not (".." `isInfixOf` fp'') then fp'' else showDigest (sha1 contents) <> "." <> ext fallback = case takeExtension fp'' of |
