@@ -812,76 +812,5 @@ scientificToFractional s = realToFrac s
812812 -- c = Scientific.coefficient s
813813
814814parseIntegral :: Integral a => String -> Value -> Parser a
815−parseIntegral expected = withScientific expected $ pure . scientificToIntegral
815+parseIntegral expected = withScientific expected $ pure . floor
816816{-# INLINE parseIntegral #-}
817−
818−-- | Safely convert an /untrusted/ scientific value to an integral.
819−--
820−-- This function is safe in the sense that the amount of space used is
821−-- bounded by the size of the target type.
822−scientificToIntegral :: Integral a => Scientific -> a
823−scientificToIntegral s
824− -- When the exponent is positive (we're dealing with an integer)
825− -- we convert the coefficient to the desired integral type and
826− -- multiply it by the magnitude (10^e). Note that the magnitude is
827− -- also represented in the target type which means that the space
828− -- usage is bounded by the size of that type (8/16/32/64
829− -- bits). Computing the magnitude could take a long time but it's
830− -- easy to protect against that by using a timeout.
831− | e >= 0 = fromInteger c * 10 ^ e
832−
833− -- When the exponent is negative we divide the Integer coefficient
834− -- by the magnitude (10^(-e)) and convert the resulting Integer to
835− -- the target integral type.
836− --
837− -- Do note that the magnitude (which is an Integer) will consume
838− -- lots of space if the exponent is a big negative number. If left
839− -- unguarded this allows an attacker to supply a scientific number
840− -- with a big negative exponent like 1e-1000000000 and crash the
841− -- target system by filling up all memory.
842− --
843− -- We guard against this by only computing the magnitude when the
844− -- exponent is between -limit and 0 (in which case the magnitude
845− -- doesn't consume much space). If the exponent is smaller than
846− -- -limit we return 0 but only when it's smaller than
847− -- -nrOfCoefficientDigits (the number of decimal digits in the
848− -- coefficient).
849− --
850− -- Note that this still allows an attacker to trigger the unsafe
851− -- magnitude computation. However, he can only trigger it by
852− -- supplying a coefficient consisting of more decimal digits than
853− -- 10^(-e). It's easy to protect against this by limiting the
854− -- amount of bytes read from an untrusted source.
855− --
856− -- Also note that nrOfCoefficientDigits is only computed when the
857− -- exponent is smaller than -limit.
858− | e < (-limit) && e < (-nrOfCoefficientDigits) = 0
859−
860− | otherwise = fromInteger (c `div` (10^(-e)))
861− where
862− e = Scientific.base10Exponent s
863− c = Scientific.coefficient s
864−
865− limit = 20
866−
867− -- The number of decimal digits of the coefficient.
868− nrOfCoefficientDigits = integerLogBase 10 (abs c)
869−
870−-- | Calculate the integer logarithm for an arbitrary base.
871−-- The base must be greater than 1, the second argument, the number
872−-- whose logarithm is sought, should be positive, otherwise the
873−-- result is meaningless.
874−--
875−-- > base ^ integerLogBase base m <= m < base ^ (integerLogBase base m + 1)
876−--
877−-- for @base > 1@ and @m > 0@.
878−--
879−-- TODO: Use integerLogBase# from integer-gmp which is probably more efficient!
880−integerLogBase :: Integer -> Integer -> Int
881−integerLogBase b m = case step b of (_, e) -> e
882− where
883− step pw | m < pw = (m, 0)
884− | q < pw = (q, 2 * e)
885− | otherwise = (q `quot` pw, 2 * e + 1)
886− where
887− (q, e) = step (pw * pw)