From db718eedcd144a799fa519d45055456852d1b97b Mon Sep 17 00:00:00 2001 From: Jonathan Lamothe Date: Sun, 24 Oct 2021 14:28:41 -0400 Subject: [PATCH] properly encode non-ASCII characters with encodeString --- src/Network/GemServ.hs | 25 ++++++++++++++----------- test/Network/GemServSpec.hs | 1 + 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/Network/GemServ.hs b/src/Network/GemServ.hs index 9dcf8d5..0980419 100644 --- a/src/Network/GemServ.hs +++ b/src/Network/GemServ.hs @@ -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 -> - if ch `elem` unescaped - then [ch] - else '%' : toHex ch +escapeString = concatMap + ( \n -> let ch = chr $ fromIntegral n in + if ch `elem` unescaped + then [ch] + else '%' : toHex n + ) . BSL.unpack . toLazyByteString . stringUtf8 where unescaped = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z'] ++ "~-_." - toHex ch = let - n = ord ch - high = n `div` 16 - low = n `mod` 16 - in [hexDigits !! high, hexDigits !! low] + 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 diff --git a/test/Network/GemServSpec.hs b/test/Network/GemServSpec.hs index b58c21f..0c6807a 100644 --- a/test/Network/GemServSpec.hs +++ b/test/Network/GemServSpec.hs @@ -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