posix-escape-0.1: System/Posix/Escape/Unicode.hs
{- | Quote Unicode arguments to be passed through the Unix shell.
If you are escaping ASCII-only strings, use @System.Posix.Escape@ as a safer
alternative.
If you are escaping untrusted input, you must guarantee that the Unicode
characters of the escaped @String@ will be serialized using the character
encoding expected by @\/bin\/sh@.
Some software incorrectly interprets characters as bytes, and will use only the
low 8 bits of each Unicode code point. This includes version 1.0 of the
Haskell @process@ package, which is bundled with GHC 7.0. Under such
circumstances this module /will not/ prevent malicious input from escaping the
quotation.
This bug was fixed in @process-1.1@, which ships with GHC 7.2:
* <http://hackage.haskell.org/trac/ghc/ticket/4006>
* <http://hackage.haskell.org/trac/ghc/ticket/1414>
To repeat: Escaping untrusted input using this module and passing it to the
@process@ package in GHC 7.0 is NOT SAFE and can allow MALICIOUS CODE
EXECUTION. Use @System.Posix.Escape@ as a safer alternative.
-}
module System.Posix.Escape.Unicode
( escape
, escapeMany
) where
-- | Wrap a @String@ so it can be used within a Unix shell command line, and
-- end up as a single argument to the program invoked.
escape :: String -> String
escape xs = "'" ++ concatMap f xs ++ "'" where
f '\0' = ""
f '\'' = "'\"'\"'"
f x = [x]
-- | Wrap some @String@s as separate arguments, by inserting spaces before and
-- after each. This will break if, for example, prefixed with a backslash.
escapeMany :: [String] -> String
escapeMany xs = " " ++ unwords (map escape xs) ++ " "