mirror of
https://github.com/simonmichael/hledger.git
synced 2024-09-19 10:17:35 +03:00
feat: api: quoteForCommandLine: some very shady CLI escaping
This commit is contained in:
parent
d2f0077254
commit
442ef9361c
@ -10,6 +10,7 @@ module Hledger.Utils.String (
|
||||
-- quoting
|
||||
quoteIfNeeded,
|
||||
singleQuoteIfNeeded,
|
||||
quoteForCommandLine,
|
||||
-- quotechars,
|
||||
-- whitespacechars,
|
||||
words',
|
||||
@ -118,15 +119,44 @@ quoteIfNeeded s | any (`elem` s) (quotechars++whitespacechars++redirectchars) =
|
||||
escapeQuotes (c:cs) x = showChar c $ escapeQuotes cs x
|
||||
|
||||
-- | Single-quote this string if it contains whitespace or double-quotes.
|
||||
-- No good for strings containing single quotes.
|
||||
-- Does not work for strings containing single quotes.
|
||||
singleQuoteIfNeeded :: String -> String
|
||||
singleQuoteIfNeeded s | any (`elem` s) (quotechars++whitespacechars) = "'"++s++"'"
|
||||
singleQuoteIfNeeded s | any (`elem` s) (quotechars++whitespacechars) = singleQuote s
|
||||
| otherwise = s
|
||||
|
||||
quotechars, whitespacechars, redirectchars :: [Char]
|
||||
-- | Prepend and append single quotes to a string.
|
||||
singleQuote :: String -> String
|
||||
singleQuote s = "'"++s++"'"
|
||||
|
||||
-- | Try to single- and backslash-quote a string as needed to make it usable
|
||||
-- as an argument on a (sh/bash) shell command line. At least, well enough
|
||||
-- to handle common currency symbols, like $. Probably broken in many ways.
|
||||
--
|
||||
-- >>> quoteForCommandLine "a"
|
||||
-- "a"
|
||||
-- >>> quoteForCommandLine "\""
|
||||
-- "'\"'"
|
||||
-- >>> quoteForCommandLine "$"
|
||||
-- "'\\$'"
|
||||
--
|
||||
quoteForCommandLine :: String -> String
|
||||
quoteForCommandLine s
|
||||
| any (`elem` s) (quotechars++whitespacechars++shellchars) = singleQuote $ quoteShellChars s
|
||||
| otherwise = s
|
||||
|
||||
-- | Try to backslash-quote common shell-significant characters in this string.
|
||||
-- Doesn't handle single quotes, & probably others.
|
||||
quoteShellChars :: String -> String
|
||||
quoteShellChars = concatMap escapeShellChar
|
||||
where
|
||||
escapeShellChar c | c `elem` shellchars = ['\\',c]
|
||||
escapeShellChar c = [c]
|
||||
|
||||
quotechars, whitespacechars, redirectchars, shellchars :: [Char]
|
||||
quotechars = "'\""
|
||||
whitespacechars = " \t\n\r"
|
||||
redirectchars = "<>"
|
||||
shellchars = "<>(){}[]$7?#!~`"
|
||||
|
||||
-- | Quote-aware version of words - don't split on spaces which are inside quotes.
|
||||
-- NB correctly handles "a'b" but not "''a''". Can raise an error if parsing fails.
|
||||
|
Loading…
Reference in New Issue
Block a user