Ticket #5688 (closed bug: fixed)

Opened 6 months ago

Last modified 2 months ago

instance Read Integer/Rational/Double readsPrec out of memory and crash due to exponential notation

Reported by: gracjan Owned by: igloo
Priority: highest Milestone: 7.4.2
Component: libraries/base Version: 6.12.3
Keywords: Cc: gale@…, iustin@…, anton.nik@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime crash Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by igloo) (diff)

 GHCi, version 6.12.3: http://www.haskell.org/ghc/ 
 Loading package ghc-prim ... linking ... done.
 Loading package integer-gmp ... linking ... done.
 Loading package base ... linking ... done.
 Loading package ffi-1.0 ... linking ... done.
 120000000000
 Prelude> read "12e1000000000000" :: Integer
 Segmentation fault

Sometimes it fails with Bus error.

According to Haskell'98 and Haskell'00 Reports Integers should not parse exponential notation at all.

 http://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-190002.5

This is security issue in web frameworks as parsing HTTP headers, URLs, JSON and other may involve parsing integers.

Attachments

Change History

Changed 6 months ago by gracjan

  Changed 6 months ago by gracjan

Attached patch fixes the immediate out of memory issue and report incompatibility.

  Changed 6 months ago by gracjan

Report violation presented:

GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> read "12e12" :: Integer
12000000000000
Prelude> 

Should not parse at all.

  Changed 6 months ago by gracjan

  • status changed from new to patch

The second patch is a bit more invasive. It adds new constructor to Text.Read.Lex.Lexeme

Exp Integer Integer

that represents exponential notation directly.

When parsing integral types Exp is considered parse failure. When parsing RealFloat? then encodeFloat is used (and exponent clamped to Int).

Report consistency is fixed. No more out of memory errors when parsing numbers.

Downside is additional constructor in Lexeme.

If you happen to know better how to fix this issue I'm eager to help.

  Changed 6 months ago by gracjan

  • summary changed from instance Read Integer readsPrec out of memory due to exponential notation to instance Read Integer/Rational/Double readsPrec out of memory and crash due to exponential notation

  Changed 6 months ago by FSalad

No segfault on my system (Linux 3.1.1, GHC 7.2.1), just goes into a memory-consuming, C-resistant loop (presumably due to the huge size the representation of read "12e1000000000000" :: Integer would have)

  Changed 6 months ago by FSalad

That was supposed to be "^C-resistant"

  Changed 6 months ago by YitzGale

  • cc gale@… added

  Changed 6 months ago by maeder

A fix should also support fixing #3897.

follow-up: ↓ 11   Changed 6 months ago by maeder

Is it not better to use "**" from the Floating class, rather than encodeFloat (from RealFloat?) and this arbitrary "clampToInt" in convertFrac of your patch?

follow-up: ↓ 19   Changed 6 months ago by simonmar

  • priority changed from normal to highest
  • difficulty set to Unknown
  • milestone set to 7.4.1

I'm in favour of getting a fix for this into 7.4.1, given that it has security/DOS implications.

in reply to: ↑ 9   Changed 6 months ago by gracjan

You are right, Float is base class for RealFrac? so it will be better to use (**).

  Changed 6 months ago by maeder

How do you intent to store fractional numbers (like "10.01") without the Rat constructor?

10.01 = Exp 1001 (-2)

can this be converted to a Rational, when e-Notation is no longer supported for rationals?

  Changed 6 months ago by gracjan

maeder, I do not understand your question. Lex.Lexeme is used to parse Integer, Float and Double only. Rationals are parsed as three lexemes: 'Int' '%' 'Int'. They are in completely different place.

Where do you need the conversion?

  Changed 6 months ago by maeder

Ah, I believed "10.01" could be read as Rational, but I was wrong.

I did not expect "10e10" to work with Integer and I'm surprised now that it does not work for Rational since I considered Rational to be a "more" than Integer.

But maybe it is still a good idea to separate the fractional part from the exponent for proper "Fractional" numbers.

 http://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1360006.4.1 does not clarify the connection of numeric literals to number types, but only reflects the bad connection of floats via Rational.

So the report needs to be changed, too.

  Changed 6 months ago by maeder

While read fails, 10.10 is a legal Rational Haskell value

*Main> 10.10 :: Rational
101 % 10
*Main> read "10.10" :: Rational
*** Exception: Prelude.read: no parse

and

main = print (1E100000000000 :: Rational)

crashes the compiler as happens without type annotation currently.

  Changed 6 months ago by maeder

I think, read should behave like the haskell scanner and "10.01e10 :: Rational" should be rejected with "No instance for (Floating Rational)" as "10.01 :: Integer" is with:

Prelude> 10.10 :: Integer

<interactive>:1:1:
    No instance for (Fractional Integer)
      arising from the literal `10.1'
...

Another question is, if leading or trailing zeros should be preserved for messages.

  Changed 6 months ago by gracjan

I've created separate ticket for report change and source code compile:

 http://hackage.haskell.org/trac/ghc/ticket/5692

Also to document 6.12.3 behavior:

GHCi, version 6.12.3: http://www.haskell.org/ghc/
Prelude> read "123e10" :: Integer
1230000000000
Prelude> read "123e10" :: Double
1.23e12
Prelude> read "123e10" :: Rational
*** Exception: Prelude.read: no parse

Prelude> 123e10 :: Integer

<interactive>:1:0:
    No instance for (Fractional Integer)
      arising from the literal `1.23e12' at <interactive>:1:0-5
    Possible fix: add an instance declaration for (Fractional Integer)
    In the expression: 1.23e12 :: Integer
    In the definition of `it': it = 1.23e12 :: Integer
Prelude> 123e10 :: Double
1.23e12
Prelude> 123e10 :: Rational
1230000000000 % 1

So source code compile of Integer and Rational is not compatible with Read instances.

  Changed 6 months ago by maeder

The conversion from 123e10 to 1.23e12 in the message is also not nice.

in reply to: ↑ 10   Changed 6 months ago by iustin

Replying to simonmar:

I'm in favour of getting a fix for this into 7.4.1, given that it has security/DOS implications.

Hi,

Since this can be a security issue, I'd recommend also issuing patches that apply to older compilers, so that distributions can apply them/make a security advisory/etc. No need for a full release of (e.g.) ghc 6.12, but a "blessed" patch for it would be welcome. I'm picking on 6.12 mostly as Debian stable and Ubuntu Lucid (LTS) ship it.

thanks!

  Changed 6 months ago by iustin

  • cc iustin@… added

follow-up: ↓ 22   Changed 6 months ago by maeder

Before you call read for Integer you can/should check if your string has at least one and only digits. Calling read is currently just as risky as calling "^" yourself.

in reply to: ↑ 21   Changed 6 months ago by iustin

Replying to maeder:

Before you call read for Integer you can/should check if your string has at least one and only digits. Calling read is currently just as risky as calling "^" yourself.

I'm sorry, unless I misunderstood what you meant, this is not an acceptable workaround except in trivial programs. This breaks any complex data structure that has Int/Integer/Rational fields, and it also breaks any libraries which assume that converting a string to an int is safe. For example, it also affects Text.JSON:

Prelude Text.JSON> decode "12e1000000000000" :: Result Int
… hangs …

or the Aeson library:

Prelude Data.Aeson> decode "[12e1000000000000]" :: Maybe [Int]
… hangs too …

So no, telling people that suddenly "read" is no longer safe and you have to do manual checks on its input depending on intended result type is not acceptable; this needs to be fixed at compiler level and also, IMHO, the fix backported to previous versions.

  Changed 6 months ago by gracjan

To chime in: parsing Float and Double also kills programs because this goes through Rational.

Text.JSON is self guilty. Here is the relevant snippet from json-0.5. File Text/JSON/String.hs:189

   exponent' n (c:cs)
    | c == 'e' || c == 'E' = (n*) <$> exp_num cs
   exponent' n cs = setInput cs >> return n

   exp_num          :: String -> GetJSON Rational
   exp_num ('+':cs)  = exp_digs cs
   exp_num ('-':cs)  = recip <$> exp_digs cs
   exp_num cs        = exp_digs cs

   exp_digs :: String -> GetJSON Rational
   exp_digs cs = case readDec cs of
       [(a,ds)] -> do setInput ds
                      return (fromIntegral ((10::Integer) ^ (a::Integer)))
       _        -> fail $ "Unable to parse JSON exponential: " ++ context cs

Same with aeson because of attoparsec: Data.Attoparsec.Text:

number :: Parser Number
number = floaty $ \real frac fracDenom ->
         if frac == 0 && fracDenom == 0
         then I real
         else D (asDouble real frac fracDenom)

...
  let n = if fracDigits == 0
          then if power == 0
               then fromIntegral real
               else fromIntegral real * (10 ^^ power)
          else if power == 0
               then f real fraction (10 ^ fracDigits)
               else f real fraction (10 ^ fracDigits) * (10 ^^ power)

  Changed 5 months ago by igloo

  • description modified (diff)

  Changed 5 months ago by simonmar

  • owner set to igloo

Ian, could you get this patch into 7.4.1 please? (note this also closed #3897)

  Changed 5 months ago by igloo

I assume the patch we want is 0001-Added-new-Exp-constructor-to-Text.Read.Lex.Lexeme-so.patch?

There were a few warnings, most notably in the "a" variables here:

  valueFracExp a (Just fs) mExp                         -- 4.3[e2]
    = let (a,e) = fracExp (fromMaybe 0 mExp) a fs in Exp a e

which I assume was intended to be:

  valueFracExp a (Just fs) mExp                         -- 4.3[e2]
    = let (a', e) = fracExp (fromMaybe 0 mExp) a fs
      in Exp a' e

num008 then finds a number of differences, for example:

import Numeric

main :: IO ()
main = mapM_ (putStrLn . f) ["4.2000000e2", "1.8217369e0", "1.8217369e-300"]

f :: String -> String
f str = let d :: Double
            d = read str
        in str ++ replicate (15 - length str) ' ' ++ show d

Before the patch:

$ ghc --make q
[1 of 1] Compiling Main             ( q.hs, q.o )
Linking q ...
$ ./q
4.2000000e2    420.0
1.8217369e0    1.8217369
1.8217369e-300 1.8217369e-300

After the patch:

$ ghc --make q
[1 of 1] Compiling Main             ( q.hs, q.o )
Linking q ...
$ ./q
4.2000000e2    420.00000000000006
1.8217369e0    1.8217368999999999
1.8217369e-300 1.8217368999999997e-300

Are we happy with that?

  Changed 5 months ago by simonmar

I was under the impression it wouldn't change anything, that looks suspicious to me.

  Changed 5 months ago by maeder

I'm not happy, too. Representing all fractionals via Exp has some drawbacks. What does your patched q give for "420.00000"?

Prelude> 4.2000000 * 10 ** 2
420.0
Prelude> 42000000 * 10 ** (-5)
420.00000000000006

I more liked Daniel's proposal: replacing the Rat Rational constructor with e.g. RatExp Rational (Maybe Integer).

Another point is, how such a literal is displayed in error messages by the patched ghc?

Prelude> 10.0 :: Integer

  Changed 5 months ago by maeder

I think, eventually we want to reject "e-Notation" for rationals "at the prompt" (which is harder if already fractionals are represented via Exp).

(And the read instance for rationals should accept the decimal point only.)

follow-up: ↓ 33   Changed 5 months ago by igloo

  • owner igloo deleted
  • status changed from patch to new
  • milestone changed from 7.4.1 to 7.6.1

This isn't a regression, so let's punt it to 7.6.

  Changed 5 months ago by maeder

Looking at the patch, it seems that the old Rat constructor is unused and fractionals are treated as if "e0" had been appended, causing the (unfortunate) exponent change.

in reply to: ↑ 31 ; follow-up: ↓ 34   Changed 5 months ago by iustin

Replying to igloo:

This isn't a regression, so let's punt it to 7.6.

It's not a regression, but IMHO it's a security bug. As such, it should be fixed even in lower versions, not only in a future one!

I might overreact (sorry) but dragging the feet on such issues make it hard to promote the use of Haskell…

in reply to: ↑ 33 ; follow-up: ↓ 36   Changed 5 months ago by igloo

Replying to iustin:

Replying to igloo:

This isn't a regression, so let's punt it to 7.6.

It's not a regression, but IMHO it's a security bug.

I don't think a DoS is as bad a problem as the phrase "security bug" implies.

As such, it should be fixed even in lower versions, not only in a future one!

We're not set up to be able to make releases on old branches.

I might overreact (sorry) but dragging the feet on such issues make it hard to promote the use of Haskell…

Well, pragmatically speaking, currently we're past the feature freeze and into the RC phase (so ideally wouldn't be changing the definition of Read Integer etc), the release is already long overdue, and we don't have a good fix yet.

  Changed 5 months ago by simonmar

  • milestone changed from 7.6.1 to 7.4.2

We don't have to wait until 7.6.1 to fix this, if the fix can be made with minimal disruption.

in reply to: ↑ 34   Changed 5 months ago by iustin

Replying to igloo:

Replying to iustin:

Replying to igloo:

This isn't a regression, so let's punt it to 7.6.

It's not a regression, but IMHO it's a security bug.

I don't think a DoS is as bad a problem as the phrase "security bug" implies.

True. Can it be confirmed that a most this does is a crash of the runtime, with no other "bad" behaviours?

As such, it should be fixed even in lower versions, not only in a future one!

We're not set up to be able to make releases on old branches.

As I wrote in a previous comment, you don't need to make a full release, but for long-term distributions it would be very helpful if you release an "official" patch against older versions, that can be applied.

I might overreact (sorry) but dragging the feet on such issues make it hard to promote the use of Haskell…

Well, pragmatically speaking, currently we're past the feature freeze and into the RC phase (so ideally wouldn't be changing the definition of Read Integer etc), the release is already long overdue, and we don't have a good fix yet.

Again, I don't propose to delay the release. What I'm interested in is to know for production environments that still run an older GHC release (6.12 as that is in current Debian stable and Ubuntu LTS and 7.0/7.2), they can apply a "blessed" patch to their build systems in order to safeguard against this (once a good solution is found; I expect the fix to probably apply without issues to older versions too). That's all - the update of Milestone to 7.6 worried me that all older versions are left out in the cold.

thanks again, iustin

  Changed 5 months ago by maeder

A fix should be easy. If the Rat constructor is not changed or removed it should be at least filled with the fractionals that are given without "e" (to allow some user code to go through, although with reduced functionality).

The Exp constructor should store the fractional part as Rational rather than shifting it to an Integer an decreasing the exponent.

A combination of the Rat and Exp constructores is then essential Daniels suggestion "| RatExp Rational (Maybe Integer)".

An advantage of removing Rat would be to better detect code that uses it.

  Changed 5 months ago by maeder

Another advantage of removing Rat is, that code duplication to treat the Rational within Rat and Exp(i.e. the conversion to Double) is avoided.

  Changed 3 months ago by iustin

Hi all,

Any updates on this? Any way in which someone (not familiar with internals) could help?

  Changed 3 months ago by simonpj

  • owner set to igloo

follow-up: ↓ 43   Changed 3 months ago by igloo

OK, in the Read Double/Float instances, we now have access to the integer part, the fractional part, and the exponent. The remaining part of the problem is how to convert these into a Double/Float.

One approach that doesn't work well is converting the x.y part and then multiplying by (10 ^ z). For example, given 4.2e-1 we would like to get this Double:

Prelude> 0.42 :: Double
0.42

but we would actually get this Double:

Prelude> (4.2 :: Double) * (10 ** (-1))
0.42000000000000004

Something else that works with the current code, is:

Prelude> read (show (10 ^ 1000) ++ "e-1000") :: Double
1.0

despite this:

Prelude> read (show (10 ^ 1000)) :: Double
Infinity

and similarly

Prelude> read ("0." ++ replicate 1000 '0' ++ "1e1001") :: Double
1.0

despite:

Prelude> read ("0." ++ replicate 1000 '0' ++ "1") :: Double
0.0

So my thoughts are that the first example should be supported (i.e. give us 0.42), but the second and third should break (I'm not sure what they should return. Whichever of Infinity, -Infinity, NaN and 0.0 best fits the implementation, I guess).

What do people think?

  Changed 3 months ago by igloo

If we're merging, then below are the patches so far.

Note that this means making a few visible changes, though:

  • The behaviour of Read Integer has changed
  • The Text.Read.Lex.Lexeme type has changed
  • There are a couple of new functions in Text.Read.Lex
commit afcddc5ce033de84ab88e73657a2f753aaee785a
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 01:26:06 2012 +0000

    Refactor number lexing; part of #5688
    
    This doesn't change the behaviour yet, but I think it's a step in the
    right direction.

commit 480b755a8397e75b6d58992664ab42c8ff0e1907
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:42:25 2012 +0000

    Rename lexNum test to lex001, and expand it

commit 54ce8383cc610977b50f571782f35d1322283a79
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:57:54 2012 +0000

    Add a test for reading Doubles

commit 35ff29d8fdf916c79a01103f0bb40ee6d3b50453
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:58:18 2012 +0000

    Change how NaN and Infinity are read by lex

commit f3c88bed6c742982992ac4edc8b294c3445a157d
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 14:03:31 2012 +0000

    Add a readInteger001 test

commit bed3d7937bea1619f7cf05af8babd8dd4385f348
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 14:05:36 2012 +0000

    Make "100e12" not parse as an Integer; part of #5688

in reply to: ↑ 41 ; follow-up: ↓ 45   Changed 3 months ago by igloo

Replying to igloo:

but the second and third should break (I'm not sure what they should return. Whichever of Infinity, -Infinity, NaN and 0.0 best fits the implementation, I guess).

Or perhaps if the exponent is > FLT_MAX_EXP, < FLT_MIN_EXP, > DBL_MAX_EXP or < DBL_MIN_EXP then read should fail?

  Changed 3 months ago by gracjan

Anecdotal evidence from Ruby:

~/devel$ ruby -e 'puts Float( (10 ^ 1000).to_s + "e-1000")'
-e:1: warning: Float 994e-1000 out of range
0.0

~/devel$ ruby -e 'puts Float( "0." + "0"*1000 + "1e1001" )'
1.0

in reply to: ↑ 43 ; follow-up: ↓ 46   Changed 3 months ago by maeder

Replying to igloo:

Replying to igloo:

but the second and third should break (I'm not sure what they should return. Whichever of Infinity, -Infinity, NaN and 0.0 best fits the implementation, I guess).

Or perhaps if the exponent is > FLT_MAX_EXP, < FLT_MIN_EXP, > DBL_MAX_EXP or < DBL_MIN_EXP then read should fail?

It seems the "e"-Notation is really (exponentially expanding) syntactic sugar for a plain decimal number (without e), i.e. the bits of the internal floats are not set directly.

In this case, just checking the exponent against MAX_EXP and MIN_EXP is not enough. The length of the leading fractional needs to be considered, too, i.e. for extreme examples like "1000000000000000000e-1022" or "0.00000000000000000000001e1023".

I vote for that reading should not fail, but return +/- (sign preserving) Infinity or 0.0. (What case should return NaN? I think, no case.)

Reading long integers as int does not fail, too!

in reply to: ↑ 45   Changed 3 months ago by maeder

Replying to maeder:

In this case, just checking the exponent against MAX_EXP and MIN_EXP is not enough. The length of the leading fractional needs to be considered, too, i.e. for extreme examples like "1000000000000000000e-1022" or "0.00000000000000000000001e1023".

This means checking the exponent size after normalizing the fraction (starting with 1).

follow-up: ↓ 49   Changed 3 months ago by maeder

The precise number given by the input string needs to be converted to the nearest representable number (by the round-to-nearest rule of IEEE 754 floating-point arithmetic).

If we assume that fromRational does this correctly, it is enough to roughly estimate when the value will definitely be +/- Infinity/Zero (in order to avoid computing an overly large Rational value causing this ticket).

Roughly estimating makes failing inconsistent (at least not precise).

It remains to check, if fromRational does the right thing. I assume it replaces "%" by "/" and converts the two arguments from Integer to Double/Float first. (Where is the code for this?)

  Changed 3 months ago by igloo

ruby does seem to have a limit, although I'm not quite sure what it corresponds to:

$ ruby -e 'puts Float( "0." + "0"*20321 + "1e20321" )'
9.88131291682493e-324
$ ruby -e 'puts Float( "0." + "0"*20322 + "1e20322" )'
-e:1: warning: Float 0.000000000000000000... out of range
0.0

in reply to: ↑ 47 ; follow-up: ↓ 52   Changed 3 months ago by igloo

Replying to maeder:

The precise number given by the input string needs to be converted to the nearest representable number (by the round-to-nearest rule of IEEE 754 floating-point arithmetic).

Well, I think the only things we're required to accept are what "show" can produce, which won't have an exponent outside of MIN_EXP .. MAX_EXP.

If we assume that fromRational does this correctly, it is enough to roughly estimate when the value will definitely be +/- Infinity/Zero (in order to avoid computing an overly large Rational value causing this ticket).

So what's the actual algorithm? Can it handle all cases correctly?

It remains to check, if fromRational does the right thing. I assume it replaces "%" by "/" and converts the two arguments from Integer to Double/Float first. (Where is the code for this?)

fracExp in libraries/base/Text/Read/Lex.hs makes the Rational, and fromRational in libraries/base/GHC/Float.lhs converts the Rational to a Double/Float.

  Changed 3 months ago by maeder

something like:

convert :: RealFloat a => Rational -> Integer -> a
convert frac expo =
  let d = fromRational (frac * 10 ^^ expo)
  in if abs expo + abs (fromIntegral (length (show $ numerator frac)
              - length (show $ denominator frac)))
        < fromIntegral (uncurry max $ floatRange d) then d
    else case (frac < 0, expo < 0) of
     (True, True) -> -0
     (True, False) -> -1/0
     (False, True) -> 0
     (False, False) -> 1/0

floatRange returns 1024 for Double (that's the maximal size of the binary exponent). The size of the rational does almost not matter.

  Changed 3 months ago by maeder

in reply to: ↑ 49   Changed 3 months ago by maeder

Replying to igloo:

fracExp in libraries/base/Text/Read/Lex.hs makes the Rational, and fromRational in libraries/base/GHC/Float.lhs converts the Rational to a Double/Float.

Computing the possibly big Rational when reading is wrong in my eyes. The Lexeme must store the fraction and (optional) exponent separately! Only when converting to a floating point type you know how many digits in the exponent may make sense. (Float.lhs is incomprehensible for me, but it may do the right thing.)

(An alternative is to set a fixed limit of 6 digits in the exponent, because more cannot be handled.)

Going via Rational is bad for bigger floating point numbers. The right thing would be to compute the arguments for encodeFloat during conversion.

  Changed 3 months ago by maeder

I think there was code to compute the exponent offset by the given fractional part and the maximal exponent for a floating point type can be computed by floatRange and floatDigits.

logBase 10 2 * fromIntegral (floatDigits 0) + logBase 10 2 * fromIntegral (snd (floatRange 0))

  Changed 3 months ago by maeder

or shorter: logBase 10 2 * fromIntegral (floatDigits 0 + snd (floatRange 0))

  Changed 3 months ago by lelf

  • cc anton.nik@… added

follow-up: ↓ 59   Changed 3 months ago by igloo

  • status changed from new to merge

Now fixed. This should be the complete patch list:

commit afcddc5ce033de84ab88e73657a2f753aaee785a
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 01:26:06 2012 +0000

    Refactor number lexing; part of #5688
    
    This doesn't change the behaviour yet, but I think it's a step in the
    right direction.

commit 480b755a8397e75b6d58992664ab42c8ff0e1907
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:42:25 2012 +0000

    Rename lexNum test to lex001, and expand it

commit 54ce8383cc610977b50f571782f35d1322283a79
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:57:54 2012 +0000

    Add a test for reading Doubles

commit 35ff29d8fdf916c79a01103f0bb40ee6d3b50453
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 13:58:18 2012 +0000

    Change how NaN and Infinity are read by lex

commit f3c88bed6c742982992ac4edc8b294c3445a157d
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 14:03:31 2012 +0000

    Add a readInteger001 test

commit bed3d7937bea1619f7cf05af8babd8dd4385f348
Author: Ian Lynagh <igloo@earth.li>
Date:   Thu Mar 1 14:05:36 2012 +0000

    Make "100e12" not parse as an Integer; part of #5688

commit 4d849e6729d25ac4561d597b203c2af8757e6275
Author: Ian Lynagh <igloo@earth.li>
Date:   Sun Mar 11 12:31:25 2012 +0000

    Avoid making huge Rational's when reading Double/Float; fixes #5688

We need to decide if we want to merge for 7.4.2. The arguments against doing so are:

  • Breaks the library interface policy, e.g. because the behaviour of read "12e34" :: Integer changes
  • Would mean we should bump base's version number to 4.6, which will mean lots of packages need updating.

follow-up: ↓ 58   Changed 3 months ago by maeder

I wonder, where I can look up these committed changes easily.

in reply to: ↑ 57 ; follow-up: ↓ 60   Changed 3 months ago by simonmar

Replying to maeder:

I wonder, where I can look up these committed changes easily.

pasting the hash into Google is usually the best way :-)

in reply to: ↑ 56   Changed 3 months ago by simonmar

Replying to igloo:

We need to decide if we want to merge for 7.4.2. The arguments against doing so are: * Breaks the library interface policy, e.g. because the behaviour of read "12e34" :: Integer changes * Would mean we should bump base's version number to 4.6, which will mean lots of packages need updating.

We could consider it a bug that read "12e34" worked before. If we can reasonably claim that the other interface changes are in "internal" modules, then we could avoid bumping the base version (I don't know whether that's true or not though).

in reply to: ↑ 58   Changed 3 months ago by maeder

Replying to simonmar:

pasting the hash into Google is usually the best way :-)

Your search - 4d849e6729d25ac4561d597b203c2af8757e6275 - did not match any documents. 

Which patches go to gmane.comp.lang.haskell.cvs.ghc? Why not these here?

  Changed 3 months ago by igloo

  Changed 3 months ago by maeder

I suppose, the change of "data Lexeme" in "Text.Read.Lex" is a more severe interface change.

  Changed 3 months ago by maeder

Yet, I would vote to merge it into 7.4.2 (with or without bumping the base version).

  Changed 2 months ago by igloo

  • status changed from merge to closed
  • resolution set to fixed

Backported as:

commit 6cb84cb399c42a764a80b8b34cf67e9f0e9a3ed4
Author: Ian Lynagh <igloo@earth.li>
Date:   Wed Mar 28 16:11:34 2012 +0100

    Backport the Read Integer/Double/Float change for "123e456"

    For the 7.4 branch, I've fixed this in a less pleaseant way, in order
    to avoid changing the library interfaces.
Note: See TracTickets for help on using tickets.