Oti's Jython Blog

Wednesday, February 9, 2011

No more Java Double Trouble

Lately there has been quite of rumour in the Java community about the endless loop caused by a certain range of values. Any java application parsing floating point values was vulnerable, especially dynamic languages.

Now the good news is that Oracle has fixed the issue!


Disclaimer

Only read on if your application needs to run on older, unpatched Java versions.


Analysis

Charles Oliver Nutter made the first trial of a workaround. The hot points in Java are:
  • new Double(String)
  • Double.valueOf(String)
  • Double.parseDouble(String)
  • new Float(String)
  • Float.parseFloat(String)
  • Float.valueOf(String)
  • BigDecimal.doubleValue()
  • BigDecimal.floatValue()
These calls are only blocking for a small interval [2.2250738585072011e-308, 2.2250738585072013e-308] of String input values. In fact the interval is even smaller.


Solution

There is a very pragmatic workaround to this problem:
On parsing, use a quite fast String analysis to find out if the input is suspicious. A suspicious value contains the digit sequence "22250738585072". In this case, use the slower BigDecimal parsing to determine if the value really is inside the dangerous interval. Dangerous values are rounded to the most nearby border of the interval, which is a safe value. For neither suspicious nor dangerous values, the standard Java floating decimal parsing is used.
The code looks like:
final protected static Double decimalValueOf(String s) {
Double result = null;
if (s != null) {
if (isSuspicious(s)) {
// take the slow path
result = parseSafely(s);
} else {
result = Double.valueOf(s);
}
}
return result;
}

final private static Double parseSafely(String s) {
Double result;
BigDecimal bd = new BigDecimal(s);
if (bd.compareTo(UPPER) <> 0) {
if (bd.compareTo(MIDDLE) >= 0) {
result = UPPER_DOUBLE;
} else {
result = LOWER_DOUBLE;
}
} else {
result = Double.valueOf(s);
}
return result;
}
For the BigDecimal.doubleValue() case, we need to make sure that we do not feed dangerous values into the standard Java floating decimal parsing:
final protected static double decimalValue(BigDecimal bigDecimal) {
double result = 0.0;
if (bigDecimal != null) {
if (bigDecimal.compareTo(UPPER) <> 0) {
result = decimalValueOf(bigDecimal.toString()).doubleValue();
} else {
result = bigDecimal.doubleValue();
}
}
return result;
}
What you see here is the heart of the SafeDecimalParser class. For real usage, there are two convenience classes: SafeDoubleParser and SafeFloatParser. The following table lists the original calls, and how you would replace them:

String s; BigDecimal bd;
new Double(s)
-> SafeDoubleParser.valueOf(s)
Double.parseDouble(s)
-> SafeDoubleParser.parseDouble(s)
Double.valueOf(s)
-> SafeDoubleParser.valueOf(s)
new Float(s)
-> SafeFloatParser.valueOf(s)
Float.parseFloat(s)
-> SafeFloatParser.parseFloat(s)
Float.valueOf(s)
-> SafeFloatParser.valueOf(s)
bd.doubleValue()
-> SafeDoubleParser.doubleValue(bd)
bd.floatValue()
-> SafeFloatParser.floatValue(bd)

The DoubleTroubleTestSuite.jar contains all the sources for the safe parsers. Running java -jar DoubleTroubleTestSuite.jar executes all the junit tests on your favourite platform. I successfully tested it on:
  • Mac OS X 10.5.8
  • Windows 7
  • Ubuntu 10.4
  • Ubuntu 10.10
  • Open Solaris

Downsides
  • The small performance impact for the detection of suspicious values
  • Some values are not exact, however the maximum error is less than 6.2e-325

Nevertheless, this hopefully might be useful.

You find the code inside the .jar file, besides the .class files in the org.python.util package.
It is under the Python Software Foundation License, which means you can freely use and redistribute it.
Happy coding!

Monday, January 10, 2011

Jython 2.5.2 rc3 released!

On behalf of the Jython developers, I am happy to announce the availability of Jython 2.5.2 rc3.

I'd like to thank all the testers, contributors, developers and documenters who helped to make this happen - thank you very much!

We believe that this is very, very close to the Jython 2.5.2 final release.

The latest bug fixes are:
  • [ 1674 ] PDB crashes under the JSR-223 scripting engine
  • [ 1680 ] jython -c option is not parsed right
  • [ 1681 ] JSR-223, Jython 2.5.2 and implementing Java Interfaces from Python
  • [ 1675 ] Jython exits prematurely when executing a file, thus killing Swing windows
  • [ 1682 ] exit code of 0 on unhandled exception
  • [ 1668 ] strptime('','') works on cpython but not on jython
  • [ 1693 ] Unicode sys.path elements cause UnicodeErrors on import

Download:

Since this is brand new, please give us a day or two to update the website...
Happy jythoning!

Wednesday, July 14, 2010

Update rate of the #jython IRC logs

The log bot is now much more stable, and the logs of the #jython IRC channel are updated about every 10 minutes.

Monday, June 28, 2010

Jython 2.5.2 Beta 1 is out!

On behalf of the Jython development team, I'm pleased to announce that Jython 2.5.2 Beta 1 is available for download. See the installation instructions.

This release fixes a number of bugs, including some Java integration problems, several modjy bugs, a number of Python compatibility bugs, and more.
See the NEWS file for more details.

Please try it out and report any bugs in the bug tracker.

Labels:

Tuesday, April 27, 2010

This blog has moved


This blog is now located at http://extremestjython.blogspot.com/.
You will be automatically redirected in 30 seconds, or you may click here.

For feed subscribers, please update your feed subscriptions to
http://extremestjython.blogspot.com/feeds/posts/default.

Friday, October 26, 2007

Code completion on imported Java classes in pydev

Recently on #jython IRC there was a question/discussion about code completion on imported java classes in the pydev Eclipse plugin. Maybe the following blog entry from Fabio clarifies this a bit. As I understand it, Fabio is working on JDT integration.

Wednesday, August 22, 2007

Jython 2.2 released

The Jython 2.2 final release is available - spread the word !
For more details, please refer to the Jython homepage.

BIG thanks to all who made this happen !