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

View File

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