[Haskell-cafe] Re: ANN: diagrams 0.2

Gwern Branwen gwern0 at gmail.com
Wed Feb 4 10:56:42 EST 2009


On Sun, Feb 1, 2009 at 1:37 AM, John MacFarlane <jgm at berkeley.edu> wrote:
> Not too hard, I think.  Here's code for something similar (for graphviz
> diagrams), derived from plugins/DotPlugin.hs in SVN pandoc.
>
>    transform :: Block -> IO Block
>    transform (CodeBlock (id, classes, namevals) contents) | "dot" `elem` classes = do
>      let (name, outfile) =  case lookup "name" namevals of
>                                    Just fn   -> ([Str fn], fn ++ ".png")
>                                    Nothing   -> ([], uniqueName contents ++ ".png")
>      result <- readProcess "dot" ["-Tpng"] contents
>      writeFile outfile result
>      return $ Para [Image name (outfile, "")]
>    transform x = return x
>
>    -- | Generate a unique filename given the file's contents.
>    uniqueName :: String -> String
>    uniqueName = showDigest . sha1 . fromString
>
> The 'transform' function will transform delimited code blocks such
> as
>
>    ~~~ {.dot name="diagram1"}
>    digraph G {Hello->World}
>    ~~~
>
> into images generated by running the contents through graphviz's dot. To
> lift this into a transformation of Pandoc documents, you can use syb:
>
>    convertGraphviz :: Pandoc -> IO Pandoc
>    convertGraphviz = everywhereM (mkM transform)
>
> With minimal modifications, the same technique should work for
> diagrams...
>
> Best,
> John

This certainly does seem reasonable, but I don't think the
sandboxing/interpretation question is addressed.

In your GraphViz example, you dump out to the 'dot' executable and it
does things which you read back. But with Diagrams, we're interested
in running arbitrary Haskell code - that's what makes Diagrams so
useful, that we can exploit the full power of Haskell in our
expressions.

Now, to implement it, I would probably say to myself, "well, we'll
create a temporary file, we'll write some basic imports into it, then
we'll write the user's expression into it as the definition of a
function 'foo', and main will be defined as 'main = renderFile foo'.
Then we use 'runhaskell' on the temporary file to create the picture,
delete the temp file, and bob's your uncle."

Except of course there's nothing to prevent DoS attacks or other
exploits in the arbitrary code. So do we accept this and say that this
is a plugin one uses at one's own risk?

-- 
gwern


More information about the Haskell-Cafe mailing list