@@ -101,7 +101,7 @@ import Data.Char ( toLower, isLower, isUpper, isAlpha,
101import Data.List ( find, isPrefixOf, intercalate )
101import Data.List ( find, isPrefixOf, intercalate )
102import qualified Data.Map as M
102import qualified Data.Map as M
103import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,
103import Network.URI ( escapeURIString, isURI, nonStrictRelativeTo,
104− unEscapeString, parseURIReference )
104+ unEscapeString, parseURIReference, isAllowedInURI )
105import qualified Data.Set as Set
105import qualified Data.Set as Set
106import System.Directory
106import System.Directory
107import Text.Pandoc.MIME (getMimeType)
107import Text.Pandoc.MIME (getMimeType)
@@ -766,21 +766,22 @@ readDataFileUTF8 userDir fname =
766-- Returns raw content and maybe mime type.
766-- Returns raw content and maybe mime type.
767fetchItem :: Maybe String -> String
767fetchItem :: Maybe String -> String
768 -> IO (Either E.SomeException (BS.ByteString, Maybe String))
768 -> IO (Either E.SomeException (BS.ByteString, Maybe String))
769−fetchItem sourceURL s
769+fetchItem sourceURL s =
770+ case (sourceURL >>= parseURIReference . ensureEscaped, ensureEscaped s) of
770− | isURI s = openURL s
771+ (_, s') | isURI s' -> openURL s'
771− | otherwise =
772+ (Just u, s') -> -- try fetching from relative path at source
772− case sourceURL >>= parseURIReference of
773− Just u -> case parseURIReference s of
773+ case parseURIReference s' of
774− Just s' -> openURL $ show $
775− s' `nonStrictRelativeTo` u
774+ Just u' -> openURL $ show $ u' `nonStrictRelativeTo` u
776− Nothing -> openURL $ show u ++ "/" ++ s
775+ Nothing -> openURL s' -- will throw error
777− Nothing -> E.try readLocalFile
776+ (Nothing, _) -> E.try readLocalFile -- get from local file system
778 where readLocalFile = do
777 where readLocalFile = do
779 let mime = case takeExtension s of
778 let mime = case takeExtension s of
780 ".gz" -> getMimeType $ dropExtension s
779 ".gz" -> getMimeType $ dropExtension s
781 x -> getMimeType x
780 x -> getMimeType x
782− cont <- BS.readFile $ unEscapeString s
781+ cont <- BS.readFile $ unEscapeString $ dropFragmentAndQuery s
783 return (cont, mime)
782 return (cont, mime)
783+ dropFragmentAndQuery = takeWhile (\c -> c /= '?' && c /= '#')
784+ ensureEscaped = escapeURIString isAllowedInURI
785-- | Like 'fetchItem', but also looks for items in a 'MediaBag'.
786-- | Like 'fetchItem', but also looks for items in a 'MediaBag'.
786fetchItem' :: MediaBag -> Maybe String -> String
787fetchItem' :: MediaBag -> Maybe String -> String