git.iko.soy/typeable/pandoc
on master help sign in
Shared: fetchItem improvements.

* More consistent logic: absolute URIs are fetched from the net; other things are treated as relative URIs if sourceURL is a Just, otherwise as file paths. * We escape characters that are not allowed in URIs before trying to parse them (e.g. '|', which often occurs in the wild). * When treating relative paths as local file paths, we drop any fragment or query. This is useful e.g. when you've downloaded web fonts locally, but your source still contains the original relative URLs. Together with the previous commit, this should close #1477.

commit1d137fbed69a61e751e94539b51a2aad0618026d authorJohn MacFarlane <fiddlosopher@gmail.com> dateSat 2 Aug 2014, 16:09 (12 years ago) parentce89224
1 file changed+12−11
src/Text/Pandoc/Shared.hs+12−11
src/Text/Pandoc/Shared.hs+12−11
@@ -101,7 +101,7 @@ import Data.Char ( toLower, isLower, isUpper, isAlpha,
101101import Data.List ( find, isPrefixOf, intercalate )
102102import qualified Data.Map as M
103103import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,
104− unEscapeString, parseURIReference )
104+ unEscapeString, parseURIReference, isAllowedInURI )
105105import qualified Data.Set as Set
106106import System.Directory
107107import Text.Pandoc.MIME (getMimeType)
@@ -766,21 +766,22 @@ readDataFileUTF8 userDir fname =
766766-- Returns raw content and maybe mime type.
767767fetchItem :: Maybe String -> String
768768 -> IO (Either E.SomeException (BS.ByteString, Maybe String))
769−fetchItem sourceURL s
770− | isURI s = openURL s
771− | otherwise =
772− case sourceURL >>= parseURIReference of
773− Just u -> case parseURIReference s of
774− Just s' -> openURL $ show $
775− s' `nonStrictRelativeTo` u
776− Nothing -> openURL $ show u ++ "/" ++ s
777− Nothing -> E.try readLocalFile
769+fetchItem sourceURL s =
770+ case (sourceURL >>= parseURIReference . ensureEscaped, ensureEscaped s) of
771+ (_, s') | isURI s' -> openURL s'
772+ (Just u, s') -> -- try fetching from relative path at source
773+ case parseURIReference s' of
774+ Just u' -> openURL $ show $ u' `nonStrictRelativeTo` u
775+ Nothing -> openURL s' -- will throw error
776+ (Nothing, _) -> E.try readLocalFile -- get from local file system
778777 where readLocalFile = do
779778 let mime = case takeExtension s of
780779 ".gz" -> getMimeType $ dropExtension s
781780 x -> getMimeType x
782− cont <- BS.readFile $ unEscapeString s
781+ cont <- BS.readFile $ unEscapeString $ dropFragmentAndQuery s
783782 return (cont, mime)
783+ dropFragmentAndQuery = takeWhile (\c -> c /= '?' && c /= '#')
784+ ensureEscaped = escapeURIString isAllowedInURI
784785
785786-- | Like 'fetchItem', but also looks for items in a 'MediaBag'.
786787fetchItem' :: MediaBag -> Maybe String -> String