aeson 0.7.0.4 → 0.7.0.5
raw patch · 4 files changed
+47/−35 lines, 4 filesdep ~attoparsecdep ~scientificPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: attoparsec, scientific
API changes (from Hackage documentation)
Files
- Data/Aeson/Encode.hs +2/−1
- Data/Aeson/Encode/ByteString.hs +3/−2
- Data/Aeson/Types/Instances.hs +39/−29
- aeson.cabal +3/−3
Data/Aeson/Encode.hs view
@@ -34,9 +34,10 @@ import Data.Aeson.Types (Value(..)) import Data.Monoid (mappend)-import Data.Scientific (Scientific, coefficient, base10Exponent, scientificBuilder)+import Data.Scientific (Scientific, coefficient, base10Exponent) import Data.Text.Lazy.Builder import Data.Text.Lazy.Builder.Int (decimal)+import Data.Text.Lazy.Builder.Scientific (scientificBuilder) import Numeric (showHex) import qualified Data.HashMap.Strict as H import qualified Data.Text as T
Data/Aeson/Encode/ByteString.hs view
@@ -19,11 +19,12 @@ import Prelude hiding (null) import Data.Aeson.Types (ToJSON(..), Value(..)) import Data.Char (ord)-import Data.Scientific (Scientific, coefficient, base10Exponent, formatScientific, FPFormat(Generic))+import Data.Scientific (Scientific, coefficient, base10Exponent) import Data.Word (Word8) import Data.Monoid (mappend) import Data.ByteString.Builder as B import Data.ByteString.Builder.Prim as BP+import Data.ByteString.Builder.Scientific (scientificBuilder) import qualified Data.ByteString.Lazy as L import qualified Data.HashMap.Strict as HMS import qualified Data.Text as T@@ -95,7 +96,7 @@ number :: Scientific -> Builder number s- | e < 0 = B.string8 $ formatScientific Generic Nothing s+ | e < 0 = scientificBuilder s | otherwise = B.integerDec (coefficient s * 10 ^ e) where e = base10Exponent s
Data/Aeson/Types/Instances.hs view
@@ -56,7 +56,7 @@ import Data.Aeson.Types.Class import Data.Aeson.Types.Internal import Data.Scientific (Scientific)-import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits)+import qualified Data.Scientific as Scientific (coefficient, base10Exponent, fromFloatDigits, toRealFloat) import Data.Attoparsec.Number (Number(..)) import Data.Fixed import Data.Hashable (Hashable(..))@@ -167,16 +167,8 @@ toJSON = realFloatToJSON {-# INLINE toJSON #-} -realFloatToJSON :: RealFloat a => a -> Value-realFloatToJSON d- | isNaN d || isInfinite d = Null- | otherwise = Number $ Scientific.fromFloatDigits d-{-# INLINE realFloatToJSON #-}- instance FromJSON Double where- parseJSON (Number s) = pure $ realToFrac s- parseJSON Null = pure (0/0)- parseJSON v = typeMismatch "Double" v+ parseJSON = parseRealFloat "Double" {-# INLINE parseJSON #-} instance ToJSON Number where@@ -195,9 +187,7 @@ {-# INLINE toJSON #-} instance FromJSON Float where- parseJSON (Number s) = pure $ realToFrac s- parseJSON Null = pure (0/0)- parseJSON v = typeMismatch "Float" v+ parseJSON = parseRealFloat "Float" {-# INLINE parseJSON #-} instance ToJSON (Ratio Integer) where@@ -216,6 +206,10 @@ toJSON = Number . realToFrac {-# INLINE toJSON #-} +-- | /WARNING:/ Only parse fixed-precision numbers from trusted input+-- since an attacker could easily fill up the memory of the target+-- system by specifying a scientific number with a big exponent like+-- @1e1000000000@. instance HasResolution a => FromJSON (Fixed a) where parseJSON = withScientific "Fixed" $ pure . realToFrac {-# INLINE parseJSON #-}@@ -225,19 +219,19 @@ {-# INLINE toJSON #-} instance FromJSON Int where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Int" {-# INLINE parseJSON #-} -parseIntegral :: Integral a => Value -> Parser a-parseIntegral = withScientific "Integral" $ pure . floor-{-# INLINE parseIntegral #-}- instance ToJSON Integer where toJSON = Number . fromInteger {-# INLINE toJSON #-} +-- | /WARNING:/ Only parse Integers from trusted input since an+-- attacker could easily fill up the memory of the target system by+-- specifying a scientific number with a big exponent like+-- @1e1000000000@. instance FromJSON Integer where- parseJSON = parseIntegral+ parseJSON = withScientific "Integral" $ pure . floor {-# INLINE parseJSON #-} instance ToJSON Int8 where@@ -245,7 +239,7 @@ {-# INLINE toJSON #-} instance FromJSON Int8 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Int8" {-# INLINE parseJSON #-} instance ToJSON Int16 where@@ -253,7 +247,7 @@ {-# INLINE toJSON #-} instance FromJSON Int16 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Int16" {-# INLINE parseJSON #-} instance ToJSON Int32 where@@ -261,7 +255,7 @@ {-# INLINE toJSON #-} instance FromJSON Int32 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Int32" {-# INLINE parseJSON #-} instance ToJSON Int64 where@@ -269,7 +263,7 @@ {-# INLINE toJSON #-} instance FromJSON Int64 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Int64" {-# INLINE parseJSON #-} instance ToJSON Word where@@ -277,7 +271,7 @@ {-# INLINE toJSON #-} instance FromJSON Word where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Word" {-# INLINE parseJSON #-} instance ToJSON Word8 where@@ -285,7 +279,7 @@ {-# INLINE toJSON #-} instance FromJSON Word8 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Word8" {-# INLINE parseJSON #-} instance ToJSON Word16 where@@ -293,7 +287,7 @@ {-# INLINE toJSON #-} instance FromJSON Word16 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Word16" {-# INLINE parseJSON #-} instance ToJSON Word32 where@@ -301,7 +295,7 @@ {-# INLINE toJSON #-} instance FromJSON Word32 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Word32" {-# INLINE parseJSON #-} instance ToJSON Word64 where@@ -309,7 +303,7 @@ {-# INLINE toJSON #-} instance FromJSON Word64 where- parseJSON = parseIntegral+ parseJSON = parseIntegral "Word64" {-# INLINE parseJSON #-} instance ToJSON Text where@@ -788,11 +782,27 @@ Bool _ -> "Boolean" Null -> "Null" +realFloatToJSON :: RealFloat a => a -> Value+realFloatToJSON d+ | isNaN d || isInfinite d = Null+ | otherwise = Number $ Scientific.fromFloatDigits d+{-# INLINE realFloatToJSON #-}+ scientificToNumber :: Scientific -> Number scientificToNumber s- | e < 0 = D $ realToFrac s+ | e < 0 = D $ Scientific.toRealFloat s | otherwise = I $ c * 10 ^ e where e = Scientific.base10Exponent s c = Scientific.coefficient s {-# INLINE scientificToNumber #-}++parseRealFloat :: RealFloat a => String -> Value -> Parser a+parseRealFloat _ (Number s) = pure $ Scientific.toRealFloat s+parseRealFloat _ Null = pure (0/0)+parseRealFloat expected v = typeMismatch expected v+{-# INLINE parseRealFloat #-}++parseIntegral :: Integral a => String -> Value -> Parser a+parseIntegral expected = withScientific expected $ pure . floor+{-# INLINE parseIntegral #-}
aeson.cabal view
@@ -1,5 +1,5 @@ name: aeson-version: 0.7.0.4+version: 0.7.0.5 license: BSD3 license-file: LICENSE category: Text, Web, JSON@@ -112,14 +112,14 @@ Data.Aeson.Types.Generic build-depends:- attoparsec >= 0.10.2.1,+ attoparsec >= 0.11.3.4, base == 4.*, containers, deepseq, hashable >= 1.1.2.0, mtl, old-locale,- scientific >= 0.2 && < 0.3,+ scientific >= 0.3.1 && < 0.4, syb, template-haskell >= 2.4, time,