use safeOutput when quoting UnquotedString
authorJoey Hess <joeyh@joeyh.name>
Mon, 10 Apr 2023 18:43:17 +0000 (14:43 -0400)
committerJoey Hess <joeyh@joeyh.name>
Mon, 10 Apr 2023 18:46:17 +0000 (14:46 -0400)
UnquotedString does not need to be quoted, but still it's possible
it contains something attacker-controlled, which could have an
escape sequence or control character in it. This is a convenient
place to filter out such things, since quoting alrready handles
those in filenames.

Sponsored-by: Luke Shumaker on Patreon
Git/Filename.hs

index a37ca28a32257e4ae186611b486414e7f5680bb4..f515a68ef33468d73196cbef21c6e66ccb9d120f 100644 (file)
@@ -11,6 +11,7 @@
 module Git.Filename (
        unquote,
        quote,
+       noquote,
        QuotePath(..),
        StringContainingQuotedPath(..),
        quotedPaths,
@@ -20,6 +21,7 @@ module Git.Filename (
 import Common
 import Utility.Format (decode_c, encode_c, encode_c', isUtf8Byte)
 import Utility.QuickCheck
+import Utility.SafeOutput
 
 import Data.Char
 import Data.Word
@@ -55,6 +57,8 @@ class Quoteable t where
        -- double quotes and encodes when git would
        quote :: QuotePath -> t -> S.ByteString
 
+       noquote :: t -> S.ByteString
+
 instance Quoteable RawFilePath where
        quote (QuotePath qp) s = case encode_c' needencode s of
                Nothing -> s
@@ -65,6 +69,8 @@ instance Quoteable RawFilePath where
                        | qp = isUtf8Byte c
                        | otherwise = False
 
+       noquote = id
+
 -- Allows building up a string that contains paths, which will get quoted.
 -- With OverloadedStrings, strings are passed through without quoting.
 -- Eg: QuotedPath f <> ": not found"
@@ -81,10 +87,14 @@ quotedPaths (p:ps) = QuotedPath p <> if null ps
        else " " <> quotedPaths ps
 
 instance Quoteable StringContainingQuotedPath where
-       quote _ (UnquotedString s) = encodeBS s
+       quote _ (UnquotedString s) = safeOutput (encodeBS s)
        quote qp (QuotedPath p) = quote qp p
        quote qp (a :+: b) = quote qp a <> quote qp b
 
+       noquote (UnquotedString s) = encodeBS s
+       noquote (QuotedPath p) = p
+       noquote (a :+: b) = noquote a <> noquote b
+
 instance IsString StringContainingQuotedPath where
        fromString = UnquotedString