Commits

basvandijk  committed 01c184c

Use floor on Scientifics again

scientific-0.3 provides a DoS safe floor.

  • Participants
  • Parent commits ba52e4d

Comments (0)

Files changed (1)

File Data/Aeson/Types/Instances.hs

   --   c = Scientific.coefficient s
 
 parseIntegral :: Integral a => String -> Value -> Parser a
-parseIntegral expected = withScientific expected $ pure . scientificToIntegral
+parseIntegral expected = withScientific expected $ pure . floor
 {-# INLINE parseIntegral #-}
-
--- | Safely convert an /untrusted/ scientific value to an integral.
---
--- This function is safe in the sense that the amount of space used is
--- bounded by the size of the target type.
-scientificToIntegral :: Integral a => Scientific -> a
-scientificToIntegral s
-    -- When the exponent is positive (we're dealing with an integer)
-    -- we convert the coefficient to the desired integral type and
-    -- multiply it by the magnitude (10^e). Note that the magnitude is
-    -- also represented in the target type which means that the space
-    -- usage is bounded by the size of that type (8/16/32/64
-    -- bits). Computing the magnitude could take a long time but it's
-    -- easy to protect against that by using a timeout.
-    | e >= 0 = fromInteger c * 10 ^ e
-
-    -- When the exponent is negative we divide the Integer coefficient
-    -- by the magnitude (10^(-e)) and convert the resulting Integer to
-    -- the target integral type.
-    --
-    -- Do note that the magnitude (which is an Integer) will consume
-    -- lots of space if the exponent is a big negative number. If left
-    -- unguarded this allows an attacker to supply a scientific number
-    -- with a big negative exponent like 1e-1000000000 and crash the
-    -- target system by filling up all memory.
-    --
-    -- We guard against this by only computing the magnitude when the
-    -- exponent is between -limit and 0 (in which case the magnitude
-    -- doesn't consume much space). If the exponent is smaller than
-    -- -limit we return 0 but only when it's smaller than
-    -- -nrOfCoefficientDigits (the number of decimal digits in the
-    -- coefficient).
-    --
-    -- Note that this still allows an attacker to trigger the unsafe
-    -- magnitude computation. However, he can only trigger it by
-    -- supplying a coefficient consisting of more decimal digits than
-    -- 10^(-e). It's easy to protect against this by limiting the
-    -- amount of bytes read from an untrusted source.
-    --
-    -- Also note that nrOfCoefficientDigits is only computed when the
-    -- exponent is smaller than -limit.
-    | e < (-limit) && e < (-nrOfCoefficientDigits) = 0
-
-    | otherwise = fromInteger (c `div` (10^(-e)))
-  where
-    e = Scientific.base10Exponent s
-    c = Scientific.coefficient s
-
-    limit = 20
-
-    -- The number of decimal digits of the coefficient.
-    nrOfCoefficientDigits = integerLogBase 10 (abs c)
-
--- | Calculate the integer logarithm for an arbitrary base.
---   The base must be greater than 1, the second argument, the number
---   whose logarithm is sought, should be positive, otherwise the
---   result is meaningless.
---
--- > base ^ integerLogBase base m <= m < base ^ (integerLogBase base m + 1)
---
--- for @base > 1@ and @m > 0@.
---
--- TODO: Use integerLogBase# from integer-gmp which is probably more efficient!
-integerLogBase :: Integer -> Integer -> Int
-integerLogBase b m = case step b of (_, e) -> e
-  where
-    step pw | m < pw    = (m, 0)
-            | q < pw    = (q, 2 * e)
-            | otherwise = (q `quot` pw, 2 * e + 1)
-      where
-        (q, e) = step (pw * pw)