@@ -21,7 +21,7 @@ import Prelude ()
2121import Prelude.Compat
2222
2323import Control.Applicative (Const(..))
24−import Control.Monad (forM)
24+import Control.Monad (forM, forM_)
2525import Data.Aeson ((.=), (.:), (.:?), (.:!), FromJSON(..), FromJSONKeyFunction(..), FromJSONKey(..), ToJSON1(..), decode, eitherDecode, encode, genericParseJSON, genericToEncoding, genericToJSON, object, withObject)
2626import Data.Aeson.Internal (JSONPathElement(..), formatError)
2727import Data.Aeson.TH (deriveJSON, deriveToJSON, deriveToJSON1)
@@ -50,8 +50,10 @@ import Instances ()
5050import Test.Framework (Test, testGroup)
5151import Test.Framework.Providers.HUnit (testCase)
5252import Test.HUnit (Assertion, assertFailure, assertEqual)
53+import Text.Printf (printf)
5354import Types (Approx(..), Compose3, Compose3', I)
5455import UnitTests.NullaryConstructors (nullaryConstructors)
56+import qualified Data.ByteString.Base16.Lazy as LBase16
5557import qualified Data.ByteString.Lazy.Char8 as L
5658import qualified Data.DList as DList
5759import qualified Data.HashMap.Strict as HM
@@ -104,6 +106,7 @@ tests = testGroup "unit" [
104106 , testGroup "Nullary constructors" $ fmap (testCase "-") nullaryConstructors
105107 , testGroup "FromJSONKey" $ fmap (testCase "-") fromJSONKeyAssertions
106108 , testCase "PR #455" pr455
109+ , testCase "Unescape string (PR #477)" unescapeString
107110 ]
108111
109112roundTripCamel :: String -> Assertion
@@ -574,6 +577,25 @@ data MyRecord2 = MyRecord2 {_field3 :: Maybe Int, _field4 :: Maybe Bool}
574577instance ToJSON MyRecord2
575578instance FromJSON MyRecord2
576579
580+-- A regression test for: https://github.com/bos/aeson/pull/477
581+unescapeString :: Assertion
582+unescapeString = do
583+ assertEqual "Basic escaping"
584+ (Right ("\" / \\ \b \f \n \r \t" :: String))
585+ (eitherDecode "\"\\\" \\/ \\\\ \\b \\f \\n \\r \\t\"")
586+
587+ forM_ [minBound .. maxBound :: Char] $ \ c ->
588+ let s = LT.pack [c] in
589+ assertEqual (printf "UTF-16 encoded '\\x%X'" c)
590+ (Right s) (eitherDecode $ utf16Char s)
591+ where
592+ utf16Char = formatString . LBase16.encode . LT.encodeUtf16BE
593+ formatString s
594+ | L.length s == 4 = L.concat ["\"\\u", s, "\""]
595+ | L.length s == 8 =
596+ L.concat ["\"\\u", L.take 4 s, "\\u", L.drop 4 s, "\""]
597+ | otherwise = error "unescapeString: can't happen"
598+
577599-- A regression test for: https://github.com/bos/aeson/pull/455
578600data Foo a = FooNil | FooCons (Foo Int)
579601