posix-escape (empty) → 0.1
raw patch · 7 files changed
+185/−0 lines, 7 filesdep +basesetup-changed
Dependencies added: base
Files
- LICENSE +26/−0
- README +11/−0
- Setup.hs +4/−0
- System/Posix/Escape.hs +21/−0
- System/Posix/Escape/Unicode.hs +44/−0
- posix-escape.cabal +37/−0
- test/test.hs +42/−0
+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) Keegan McAllister 2011++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README view
@@ -0,0 +1,11 @@+posix-escape provides functions to 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.++Documentation is hosted at http://hackage.haskell.org/package/posix-escape++To build the documentation yourself, run++ $ cabal configure && cabal haddock --hyperlink-source++This will produce HTML documentation under dist/doc/html/posix-escape.
+ Setup.hs view
@@ -0,0 +1,4 @@+#! /usr/bin/runhaskell++import Distribution.Simple+main = defaultMain
+ System/Posix/Escape.hs view
@@ -0,0 +1,21 @@+-- | Quote ASCII arguments to be passed through the Unix shell.+--+-- For safety, these functions drop all non-ASCII characters.+module System.Posix.Escape+ ( escape+ , escapeMany+ ) where++import qualified System.Posix.Escape.Unicode as U++import Data.Char++-- | 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 = U.escape . filter isAscii++-- | 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 = U.escapeMany . map (filter isAscii)
+ System/Posix/Escape/Unicode.hs view
@@ -0,0 +1,44 @@+{- | 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) ++ " "
+ posix-escape.cabal view
@@ -0,0 +1,37 @@+name: posix-escape+version: 0.1+license: BSD3+license-file: LICENSE+synopsis: Quote arguments to be passed through the Unix shell+category: System+author: Keegan McAllister <mcallister.keegan@gmail.com>+maintainer: Keegan McAllister <mcallister.keegan@gmail.com>+build-type: Simple+cabal-version: >=1.6+description:+ This library provides functions to 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.+ .+ The module @System.Posix.Escape@ is the safer option. The module+ @System.Posix.Escape.Unicode@ has extra caveats which are documented+ with that module.+ .+ There is a similar function within the @process@ package as+ @System.Process.Internals.translate@.++extra-source-files:+ README+ , test/test.hs++library+ exposed-modules:+ System.Posix.Escape+ , System.Posix.Escape.Unicode+ ghc-options: -Wall+ build-depends:+ base >= 3 && < 5++source-repository head+ type: git+ location: git://github.com/kmcallister/posix-escape.git
+ test/test.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE+ CPP #-}++module Main(main) where++import Test.QuickCheck+import Test.QuickCheck.Monadic+import System.Process+import System.IO+import Control.Exception ( evaluate )++#ifdef UNICODE+import System.Posix.Escape.Unicode+#else+import System.Posix.Escape+#endif++echo :: String -> IO String+echo xs = do+ (_, Just hOut, _, hProc) <- createProcess $+ (shell ("/bin/echo -n " ++ xs)) { std_out = CreatePipe }+ out <- hGetContents hOut+ _ <- evaluate (length out)+ hClose hOut+ _ <- waitForProcess hProc+ return out++mangled :: String -> String+#ifdef UNICODE+mangled = id+#else+mangled = filter ((< 0x80) . fromEnum)+#endif++prop_escaped :: String -> Property+prop_escaped xs = monadicIO $ do+ pre (all (/= '\0') xs)+ ys <- run $ echo (escape xs)+ assert (mangled xs == ys)++main :: IO ()+main = quickCheck prop_escaped