From 5b896bc1a962568bddbd62b760ef41d0574af248 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Wed, 14 May 2025 09:26:04 +0200 Subject: Lua: allow to pass files to the `pandoc.read` sandbox The sandbox is now enabled if the fourth parameter is a list of files. The files are read and then made available in the sandbox via a mock file system. --- .../src/Text/Pandoc/Lua/Module/Pandoc.hs | 30 +++++++++------------- pandoc-lua-engine/test/lua/module/pandoc.lua | 23 ++++++++--------- 2 files changed, 23 insertions(+), 30 deletions(-) (limited to 'pandoc-lua-engine') diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Pandoc.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Pandoc.hs index 522871a73..a9ad78d67 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Pandoc.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Pandoc.hs @@ -238,7 +238,6 @@ functions = , defun "read" ### (\content mformatspec mreaderOptions mreadEnv -> do let readerOpts = fromMaybe def mreaderOptions - readEnv = fromMaybe "global" mreadEnv readAction :: PandocMonad m => FlavoredFormat -> m Pandoc readAction flvrd = getReader flvrd >>= \case @@ -256,11 +255,9 @@ functions = handle (failLua . show @UnicodeException) . unPandocLua $ do flvrd <- maybe (parseFlavoredFormat "markdown") pure mformatspec - case readEnv of - "global" -> readAction flvrd - "sandbox" -> sandbox [] (readAction flvrd) - x -> throwError $ PandocLuaError - ("unknown read environment: " <> x)) + case mreadEnv of + Nothing -> readAction flvrd + Just files -> sandbox files (readAction flvrd)) <#> parameter (\idx -> (Left <$> peekByteString idx) <|> (Right <$> peekSources idx)) "string|Sources" "content" "text to parse" @@ -268,18 +265,11 @@ functions = "formatspec" "format and extensions") <#> opt (parameter peekReaderOptions "ReaderOptions" "reader_options" "reader options") - <#> opt (parameter peekText "string" "read_env" $ mconcat - [ "which environment the reader operates in: Possible values" - , "are:" - , "" - , "- 'io' is the default and gives the behavior described above." - , "- 'global' uses the same environment that was used to read" - , " the input files; the parser has full access to the" - , " file-system and the mediabag." - , "- 'sandbox' works like 'global' and give the parser access to" - , " the mediabag, but prohibits file-system access." - , "" - , "Defaults to `'io'`. (string)" + <#> opt (parameter peekReadEnv "table" "read_env" $ mconcat + [ "If the value is not given or `nil`, then the global environment " + , "is used. Passing a list of filenames causes the reader to be " + , "run in a sandbox. The given files are read from the file " + , "system and provided to the sandbox in a ersatz file system." ]) =#> functionResult pushPandoc "Pandoc" "result document" @@ -411,3 +401,7 @@ pushPipeError pipeErr = do , if output == mempty then BSL.pack "" else output ] return (NumResults 1) + +-- | Peek the environment in which the `read` function operates. +peekReadEnv :: LuaError e => Peeker e [FilePath] +peekReadEnv = peekList peekString diff --git a/pandoc-lua-engine/test/lua/module/pandoc.lua b/pandoc-lua-engine/test/lua/module/pandoc.lua index 3db58c0f8..b196d143c 100644 --- a/pandoc-lua-engine/test/lua/module/pandoc.lua +++ b/pandoc-lua-engine/test/lua/module/pandoc.lua @@ -297,22 +297,16 @@ return { test('images are added to the mediabag', function () local epub = io.open('lua/module/sample.epub', 'rb'):read('a') local _ = pandoc.read(epub, 'epub') - assert.are_equal( - #pandoc.mediabag.list(), - 1 - ) + assert.are_equal(#pandoc.mediabag.list(), 1) end), test('images from EPUB are added when using the sandbox', function () local epub = io.open('lua/module/sample.epub', 'rb'):read('a') - local _ = pandoc.read(epub, 'epub', nil, 'sandbox') - assert.are_equal( - #pandoc.mediabag.list(), - 1 - ) + local _ = pandoc.read(epub, 'epub', nil, {}) + assert.are_equal(#pandoc.mediabag.list(), 1) end), test('includes work in global env', function () local tex = '\\include{lua/module/include.tex}' - local doc = pandoc.read(tex, 'latex', nil, 'global') + local doc = pandoc.read(tex, 'latex') assert.are_equal( doc.blocks, pandoc.Blocks{pandoc.Para 'included'} @@ -320,10 +314,15 @@ return { end), test('sandbox disallows access to the filesystem', function () local tex = '\\include{lua/module/include.tex}' - local doc = pandoc.read(tex, 'latex', nil, 'sandbox') + local doc = pandoc.read(tex, 'latex', nil, {}) + assert.are_equal(doc.blocks, pandoc.Blocks{}) + end), + test('files can be added to the sandbox', function () + local tex = '\\include{lua/module/include.tex}' + local doc = pandoc.read(tex, 'latex', nil, {'lua/module/include.tex'}) assert.are_equal( doc.blocks, - pandoc.Blocks{} + pandoc.Blocks{pandoc.Para 'included'} ) end), }, -- cgit v1.2.3