properly encode non-ASCII characters with encodeString

This commit is contained in:
Jonathan Lamothe 2021-10-24 14:28:41 -04:00
parent a61806f8e4
commit db718eedcd
2 changed files with 15 additions and 11 deletions

View File

@ -33,9 +33,9 @@ module Network.GemServ (
) where ) where
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import Data.ByteString.Builder (charUtf8, toLazyByteString) import Data.ByteString.Builder (charUtf8, stringUtf8, toLazyByteString)
import qualified Data.ByteString.Lazy as BSL import qualified Data.ByteString.Lazy as BSL
import Data.Char (ord, toLower) import Data.Char (chr, ord, toLower)
import Data.List (find, intercalate) import Data.List (find, intercalate)
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import qualified Data.Text as T import qualified Data.Text as T
@ -58,17 +58,20 @@ encodeRequest req =
-- | add required escape sequences to a string -- | add required escape sequences to a string
escapeString :: String -> String escapeString :: String -> String
escapeString = concatMap $ \ch -> escapeString = concatMap
( \n -> let ch = chr $ fromIntegral n in
if ch `elem` unescaped if ch `elem` unescaped
then [ch] then [ch]
else '%' : toHex ch else '%' : toHex n
) . BSL.unpack . toLazyByteString . stringUtf8
where where
unescaped = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] ++ "~-_." unescaped = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] ++ "~-_."
toHex ch = let toHex =
n = ord ch ( \n -> let
high = n `div` 16 high = n `div` 16
low = n `mod` 16 low = n `mod` 16
in [hexDigits !! high, hexDigits !! low] in [hexDigits !! high, hexDigits !! low]
) . fromIntegral
-- | decode an escaped string back to its original value -- | decode an escaped string back to its original value
unescapeString :: String -> Maybe String unescapeString :: String -> Maybe String

View File

@ -75,6 +75,7 @@ escapeStringSpec = describe "escapeString" $ mapM_
-- input, expected -- input, expected
[ ( "~foo-bar_baz.quux", "~foo-bar_baz.quux" ) [ ( "~foo-bar_baz.quux", "~foo-bar_baz.quux" )
, ( "foo:/?=&#%", "foo%3a%2f%3f%3d%26%23%25" ) , ( "foo:/?=&#%", "foo%3a%2f%3f%3d%26%23%25" )
, ( "foo\xe9", "foo%c3%a9" )
] ]
unescapeStringSpec :: Spec unescapeStringSpec :: Spec