aboutsummaryrefslogtreecommitdiff
path: root/pandoc-lua-engine
diff options
context:
space:
mode:
authorAlbert Krewinkel <[email protected]>2025-05-14 09:26:04 +0200
committerJohn MacFarlane <[email protected]>2025-05-14 09:17:24 -0700
commit5b896bc1a962568bddbd62b760ef41d0574af248 (patch)
tree05c129cdc4ff8e315a4f7ab8cf9553c89b03f317 /pandoc-lua-engine
parentbe9fbb3f6731dc6223816677aab6c64243511c8f (diff)
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.
Diffstat (limited to 'pandoc-lua-engine')
-rw-r--r--pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Pandoc.hs30
-rw-r--r--pandoc-lua-engine/test/lua/module/pandoc.lua23
2 files changed, 23 insertions, 30 deletions
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 "<no output>" 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),
},