

Java Hangs When Converting 2.2250738585072012e-308 - pietrofmaggi
http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/

======
pilif
I remember when everyone was bashing PHP
(<http://news.ycombinator.com/item?id=2066084>) when they were bitten by the
same issue. Then there were articles about this being maybe a GCC bug or at
least design issue but people were still saying that it's PHP's duty to take
care of this.

I was always afraid that this might bite other environments too as the code
that caused the issue in PHP was apparently taken from elsewhere (see
<http://blog.andreas.org/display?id=9> for a detailed analysis of the
problem). Now this is turning out to be true.

~~~
SingAlong
Rasmus just tweeted about it:

 _Java's turn to deal with the x87 register issue. Here's a hint Oracle,
"volatile"_

<http://twitter.com/rasmus/status/32365768603602944>

~~~
eonwe
Rasmussen's hint would work were the number parsing in Oracle's JDK
implemented in in C.

Volatile keyword in Java does not guarantee writing to memory and reading it
back
([http://java.sun.com/docs/books/jls/third_edition/html/classe...](http://java.sun.com/docs/books/jls/third_edition/html/classes.html#36930)),
but using strictfp as a modifier to the method should cause the usage of
strict IEEE 64-bit floating point.

~~~
rll
Well, the underlying JVM is written in C (C++ actually) along with a bunch of
assembly. I figured this needs to be fixed at the JVM level and as such the
fix might very well be a single "volatile" addition like it was for PHP.

~~~
eonwe
Yeah, the JVM is written in C++ but the problem is in Oracle's JDK written in
Java. More specifically, line 1596 in FloatingDecimal.java
([http://www.docjar.com/html/api/sun/misc/FloatingDecimal.java...](http://www.docjar.com/html/api/sun/misc/FloatingDecimal.java.html#1591))
is the only place in the correctionLoop that can cause infinite looping. I do
not purport to understand what the ulp-function does but clearly it does
produce the denormal number we would want.

The interesting value here (dValue) is double but the method is without
strictfp-qualifier and thus allowed to use not-quite IEEE-754 doubles.

Were the problem at JVM level, I would think that many numeric libraries
written in Java would not work either and the problem would've been spotted
earlier.

Edit: Thought Markdown syntax for links was in use here.

~~~
rll
So a Java double by default allows extended precision beyond the actual double
precision the type implies? I can see why it is useful for certain apps to
have this capability, and it makes the problem for Java much like the problem
for gcc. Most people don't know about it and can be bitten by it, as we have
seen, but there are also apps that make use of this extra precision. And yes,
I don't know much about Java internals.

------
mjw
Ouch.

This affects JRuby, and potentially anyone with a JSON-based API running on
the JVM with a JSON parser using the java stdlib to parse JSON floats:

    
    
        jruby-1.5.2 > JSON.parse('{"float": 2.2250738585072012e-308}')  
        ^C^C^C^C^C^C
        ^C^C^C
    

(not the most recent JRuby I know, but seems this is a JVM problem...)

------
praptak
_"Konstantin reported this problem to Oracle three weeks ago, but is still
waiting for a reply."_

This speaks volumes about Oracle as the Java's steward.

~~~
andrew1
So they're not falling over themselves to fix a bug which no one has noticed
for 10+ years, and which hardly anyone is going to hit in actual use. Maybe
they're spending their time fixing problems which are actually affecting
developers.

~~~
mhansen
Any public-facing Java server affected by this bug that accepts floating point
numbers from the user as a string can be hung by this bug.

This is going to be a big problem.

~~~
sigzero
And yet...in 10+ years...it hasn't been a problem? Certainly the need to fix
it but saying it is going to be a "big problem" is a bit theatrical.

~~~
steveklabnik
Well, yeah. Nobody _accidentally_ hit upon this number, but now that it's a
known way to commit a denial of service attack, people are going to take
advantage of it.

Imagine your response, but about a kernel privilege escalation bug:

"And yet...in 10+ years...it hasn't been a problem? Certainly the need to fix
it but saying it is going to be a "big problem" is a bit theatrical."

------
rll
I have a feeling we will see this come up in more places. When we fixed the
code for PHP we saw very similar code in a lot of other projects.

~~~
wladimir
Yes, every project should check its strtod function. If it has a potentially
infinite loop, be very worried :)

------
snewman
If I'm not mistaken, this is _bad_ : it enables a trivial DOS attack against
any web service that accepts floating-point input. (For instance, one of the
commenters on the OP noted that Google Spreadsheets backends are vulnerable.)
This includes, as a special case, any service that accepts JSON input.

I expect a lot of teams will have to rush out a patch. I feel for them...

Incidentally, I haven't seen a simple workaround posted anywhere. Has anyone
seen a regexp or code snippet that can identify strings which would trigger
this bug?

~~~
djacobs
Maybe I'm dense, but why does this affect apps that use JSON?

~~~
snewman
Because JSON can include floating-point numbers. If you pass { foo:
2.2250738585072012e-308 } to any JSON service, I'd expect it to invoke
Double.parseDouble(...) as part of its input processing, and trip over the
bug. This would probably occur before any type checking of the input, and thus
would probably work even for a service which does not expect floating-point
inputs.

~~~
woogley
This is not correct. Think about a service which used PHP's json_decode
function. PHP has fixed this bug, so there would be no issue.

The problem has nothing to do with JSON. It only affects JSON parsers that run
on a JVM.

~~~
snewman
Right -- when I said "any service that accepts JSON input", I meant "any JVM-
based service that accepts JSON input". I thought the JVM qualification would
be clear from the context of this thread, apologies if it wasn't.

------
abscondment
The compile-time version will hang a Clojure REPL, too:

user=> (def d 2.2250738585072012e-308)

~~~
paulitex
makes sense, same thing in scala:

Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java
1.6.0_22). Type in expressions to have them evaluated. Type :help for more
information.

scala> 2.2250738585072012e-308

(infinite loop)

------
latch
The compiler one is pretty neat. Hung IntelliJ. Didn't hang VS.NET. Had both
open, had to try.

~~~
leppie
Just to confirm .NET/C# handles this and correctly. So does IronScheme.

~~~
Torn
Why would a Java / JVM issue hang the .NET CLR?

~~~
dagw
Because by all accounts this isn't a Java/JVM issue. It's a flaw in a commonly
used algorithm for handling floating point numbers. Given that php and
possibly gcc use variations on the same algorithm, and have the same flaw,
it's not unreasonable to think that other languages/compilers/runtimes would
also be affected.

~~~
Torn
Thanks for the clarification.

------
ibejoeb
FWIW the Oracle/BEA jrockit compiler does not hang. It does hang on execution,
however.

    
    
       Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
       Oracle JRockit(R) (build R28.0.1-21-133393-1.6.0_20-20100512-2126-linux-ia32, compiled mode)

------
VMG
Link to actual code:
[http://google.com/codesearch/p?hl=en#lM3pwaU8RUc/src/share/c...](http://google.com/codesearch/p?hl=en#lM3pwaU8RUc/src/share/classes/sun/misc/FloatingDecimal.java&q=parseDouble&l=1476)

------
Uchikoma
I assume this hits Clojure, JRuby, etc. harder because it affects all values
which are converted to Strings, but only affects Java when one explicitly
converts to Double?

So when a (Java) website expects an Int as input, it's not affected, but
Clojure,JRuby etc would be?

Am I right, what am I missing?

(see the comment with

user=> (def d 2.2250738585072012e-308)

)

------
r0h4n
Doesnt hang Ruby 1.9 (MRI) and python 2.7 and python 3.1

~~~
speleding
Ruby 1.8.7 appears to be fine too

~~~
rll
This particular value is specific to the Java implementation. Ruby has very
similar code to PHP though, so a slight variation of the value may trigger it.
You also have to be on a platform that actually has an x87, of course.

------
joeyh
So, in summary, we've made counting on computers so complex that we're still
failing to get it right. Similarly to how we've made the alphabet (unicode) on
computers so complex that most programs are still trying to get that right.

------
russell
This seems to be a not rare occurrence around the phase boundaries of
functions. I had a similar problem with the atan2 function in the PL/I -
Fortran library on the CDC 6600. One of my testers was stepping across the
boundary between valid and invalid arguments and there was a single binary
value that blew up. I was the compiler lead so it got fixed. Any of you
remember the 486 floating point problem?

------
VMG
What about android?

~~~
dfox
Android is not i386 based and this is x87 FPU and gcc specific bug in commonly
used atod() implementation, so I assume that this does not happen on Android.

~~~
VMG
The bug is in the JDK code running on a JVM (I posted a link to the source).
Also runhang.java hangs on my 64bit java vm.

------
tytso
Obvious question --- are there any java web services running at Oracle that
take a string input from a form or a URL, and tries to convert said stirng to
a floating point variable?

------
jd0g
I cannot recreate this using Spring TC
(<http://www.springsource.com/products/tcserver>) server.

------
wildmXranat
In that case, this still applies: <http://zenebo.com/cmc/1/>

