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.
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...), but using strictfp as a modifier to the method should cause the usage of strict IEEE 64-bit floating point.
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.
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...) 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.
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.
I just reported a problem last week and got a response inside 12 hours. I was amazed. Certainly faster than I've ever gotten a response from Sun.
Average over the last 3 issues is about 48 hours - if accepted as a bug. But if you provide source code that demonstrates the problem turnaround is usually very fast, and that seems to be the case here.
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.
Yup. A comment on the original webpage reported that this value appears to hang/time-out Google Spreadsheet. I tested and it indeed was the case. So there are going to be lots of places one can fool around on the input side only to send the server thread into a loop. That's bad.
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."
I tried to dig up a list of websites with a java-backend but my google-fu is not strong enough. I don't think that there are actually many big sites running on java.
This is precisely why "q" is defined only to accept three digits after the decimal. It's actually not a floating point number, and anyone who parses it as such is just being lazy.
"q" is more properly represented natively as an integer between 0 and 1000.
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?
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.
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.
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.
As the article "The PHP strtod() denial of service bug" (http://blog.andreas.org/display?id=9 ; linked by pilif in another comment) states, it looks like the code for the conversion is used in a few prominent libraries (e.g. Apple's libc, Android libc, GCC libio etc.). Therefore, it could've been quite possible that the mentioned code has been adopted by Microsoft, too; leppie just confirmed that everything works fine over there.
I guess because only a couple of weeks ago a similar issue has surfaced in PHP so it is not entirely unreasonable to check whether other runtimes have similar problems?
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.
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?
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.
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.
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?
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.
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?
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.