Fix parsing of RealFloat with huge exponents (#7034).
authorPaolo Capriotti <p.capriotti@gmail.com>
Mon, 2 Jul 2012 11:54:57 +0000 (12:54 +0100)
committerPaolo Capriotti <p.capriotti@gmail.com>
Mon, 2 Jul 2012 11:54:57 +0000 (12:54 +0100)
Ensure numberToRangedRational returns Nothing immediately if the
exponent is outside Int range, so that we avoid an integer overflow
later.

Text/Read/Lex.hs
tests/T7034.hs [new file with mode: 0644]
tests/T7034.stdout [new file with mode: 0644]
tests/all.T

index 1a163ee..7c99f0c 100644 (file)
@@ -44,7 +44,7 @@ import {-# SOURCE #-} GHC.Unicode ( isSpace, isAlpha, isAlphaNum )
 import GHC.Real( Integral, Rational, (%), fromIntegral,
                  toInteger, (^) )
 import GHC.List
-import GHC.Enum( maxBound )
+import GHC.Enum( minBound, maxBound )
 #else
 import Prelude hiding ( lex )
 import Data.Char( chr, ord, isSpace, isAlpha, isAlphaNum )
@@ -96,6 +96,12 @@ numberToInteger _ = Nothing
 numberToRangedRational :: (Int, Int) -> Number
                        -> Maybe Rational -- Nothing = Inf
 numberToRangedRational (neg, pos) n@(MkDecimal iPart mFPart (Just exp))
+    -- if exp is out of integer bounds,
+    -- then the number is definitely out of range
+    | exp > fromIntegral (maxBound :: Int) ||
+      exp < fromIntegral (minBound :: Int)
+    = Nothing
+    | otherwise
     = let mFirstDigit = case dropWhile (0 ==) iPart of
                         iPart'@(_ : _) -> Just (length iPart')
                         [] -> case mFPart of
diff --git a/tests/T7034.hs b/tests/T7034.hs
new file mode 100644 (file)
index 0000000..b862bd8
--- /dev/null
@@ -0,0 +1,11 @@
+main :: IO ()
+main = do
+  print $ r "1E100000"
+  print $ r "1E100000000"
+  print $ r "1E100000000000"
+  print $ r "1E100000000000000"
+  print $ r "1E100000000000000000"
+  print $ r "1E100000000000000000000"
+
+r :: String -> Double
+r = read
diff --git a/tests/T7034.stdout b/tests/T7034.stdout
new file mode 100644 (file)
index 0000000..2675153
--- /dev/null
@@ -0,0 +1,6 @@
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
+Infinity
index aaa476c..b7a1629 100644 (file)
@@ -118,4 +118,4 @@ test('4006', if_msys(expect_fail), compile_and_run, [''])
 
 test('5943', normal, compile_and_run, [''])
 test('T5962', normal, compile_and_run, [''])
-
+test('T7034', normal, compile_and_run, [''])