JDK-4705734 : {Float, Double}.valueOf use broken test for whitespace characters
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.2
  • Priority: P5
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2002-06-20
  • Updated: 2003-04-10
  • Resolved: 2003-04-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 tigerFixed
Related Reports
Relates :  
Relates :  
Description
The specification for the methods {Float, Double}.valueOf (which convert strings into floating-point values) states "Leading and trailing whitespace characters in s are ignored."  However, what characters are considered whitespace is not defined.  The methods indirectly calls trim on the string.  The trim method discards ASCII control characters but not the many other characters considered whitespace in unicode or Java.  So the current implementation both accepts strings that should not be accepted (those with control characters) and rejects strings that should be accepted (those with non-ASCII whitespace).

This should be fixed.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b05
14-06-2004

SUGGESTED FIX Use regex to screen for actual white space characters (use 6 character posix white space definition, which differs from other white space definitions from java.lang.Character). For file, src/share/classes/java/lang/FloatingDecimal.java: 8a9 > import java.util.regex.*; 64a66,69 > // Regex used by readJavaFormatString to delete leading and > // trailing white space > static Pattern leadingTrailingWhitespace = > Pattern.compile("(^\\p{Space}+)|(\\p{Space}+$)"); 984,985c989,992 < in = in.trim(); // don't fool around with white space. < // throws NullPointerException if null --- > // don't fool around with white space. > // throws NullPointerException if null > in = leadingTrailingWhitespace.matcher(in).replaceAll(""); > 1198c1205 < * If there are leftovers, then this is not good input! --- > * If there are leftovers, then this might not be good input! For spec changes in file, src/share/classes/java/lang/Float.java (includes text for 4707389): 158a159 > * <dd>SignedInteger 161,163c162,165 < * where <i>Sign</i> and <i>FloatingPointLiteral</i> are as < * defined in <a href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> < * of the <a href="http://java.sun.com/docs/books/jls/html/">Java --- > * where <i>Sign</i>, <i>FloatingPointLiteral</i>, and > * <i>SignedInteger</i> are as defined in <a > * href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> > * of the <a href="http://java.sun.com/docs/books/jls/html/">Java 175,176c177,178 < * <p> < * To interpret localized string representations of a --- > * > * <p>To interpret localized string representations of a 197a200,204 > * <p>To avoid calling this method on a invalid string and having > * a <code>NumberFormatException</code> be thrown, the documentation > * for {@link Double#valueOf Double.valueOf} lists a regular > * expression which can be used to screen the input. > * For spec changes in file, src/share/classes/java/lang/Double.java (includes text for 4707389): 154a155 > * <dd>SignedInteger 157,173c158,174 < * where <i>Sign</i> and <i>FloatingPointLiteral</i> are as < * defined in < * <a href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> < * of the <a href="http://java.sun.com/docs/books/jls/html/">Java < * Language Specification</a>. If <code>s</code> does not have the < * form of a <i>FloatValue</i>, then a <code>NumberFormatException</code> < * is thrown. Otherwise, <code>s</code> is regarded as < * representing an exact decimal value in the usual "computerized < * scientific notation"; this exact decimal value is then < * conceptually converted to an "infinitely precise" binary value < * that is then rounded to type <code>double</code> by the usual < * round-to-nearest rule of IEEE 754 floating-point arithmetic, < * which includes preserving the sign of a zero value. Finally, a < * <code>Double</code> object representing this < * <code>double</code> value is returned. < * <p> < * To interpret localized string representations of a --- > * where <i>Sign</i>, <i>FloatingPointLiteral</i>, and > * <i>SignedInteger</i> are as defined in <a > * href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> > * of the <a href="http://java.sun.com/docs/books/jls/html/">Java > * Language Specification</a>. If <code>s</code> does not have the > * form of a <i>FloatValue</i>, then a > * <code>NumberFormatException</code> is thrown. Otherwise, > * <code>s</code> is regarded as representing an exact decimal > * value in the usual "computerized scientific notation"; this > * exact decimal value is then conceptually converted to an > * "infinitely precise" binary value that is then rounded to type > * <code>double</code> by the usual round-to-nearest rule of IEEE > * 754 floating-point arithmetic, which includes preserving the > * sign of a zero value. Finally, a <code>Double</code> object > * representing this <code>double</code> value is returned. > * > * <p>To interpret localized string representations of a 194a196,238 > * <p>To avoid calling this method on a invalid string and having > * a <code>NumberFormatException</code> be thrown, the regular > * expression below can be used to screen the input string: > * > * <code> > * <pre> > * final String Digits = "(\\p{Digit}+)"; > * // an exponent is 'e' or 'E' followed by an optionally > * // signed decimal integer. > * final String Exp = "[eE][+-]?"+Digits; > * final String fpRegex = > * ("\\p{Space}*" + // Optional leading whitespace > * "[+-]?(" + // Optional sign character > * "NaN|" + // "NaN" string > * "Infinity|" + // "Infinity" string > * > * // A floating-point string representing a finite positive > * // number has at most five basic pieces: > * // Digits . Digits ExponentPart FloatTypeSuffix > * // > * // Since this method allows integer-only strings as input > * // in addition to strings of floating-point literals, the > * // two sub-patterns below are simplifications of the grammar > * // productions from the Java Language Specification, 2nd > * // edition, section 3.10.1. > * > * // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt > * "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+ > * > * // . Digits ExponentPart_opt FloatTypeSuffix_opt > * "(\\.("+Digits+")("+Exp+")?))"+ > * "[fFdD]?))" + > * "\\p{Space}*"); // Optional trailing whitespace > * > * Pattern fpPattern = Pattern.compile(fpRegex); > * if (fpPattern.match(myString)) > * Double.valueOf(myString); // Will not throw NumberFormatException > * else { > * // Perform suitable alternative action > * } > * </pre> > * </code> > * After ccc input, the fix is to change the specification, not the implementation new spec for Float.valueOf below; changes in Double.valueOf for this problem are analagous: ------- Float.java ------- 146,152c146,156 < * <p> < * If <code>s</code> is <code>null</code>, then a < * <code>NullPointerException</code> is thrown. < * <p> < * Leading and trailing whitespace characters in <code>s</code> < * are ignored. The rest of <code>s</code> should constitute a < * <i>FloatValue</i> as described by the lexical syntax rules: --- > * > * <p>If <code>s</code> is <code>null</code>, then a > * <code>NullPointerException</code> is thrown. > * > * <p>Leading and trailing whitespace characters in <code>s</code> > * are ignored. Whitespace is removed as if by the {@link > * String#trim} method; that is, both ASCII space and control > * characters are removed. The rest of <code>s</code> should > * constitute a <i>FloatValue</i> as described by the lexical > * syntax rules: > * 158a163 > * <dd>SignedInteger 161,163c166,170 < * where <i>Sign</i> and <i>FloatingPointLiteral</i> are as < * defined in <a href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> < * of the <a href="http://java.sun.com/docs/books/jls/html/">Java --- > * > * where <i>Sign</i>, <i>FloatingPointLiteral</i>, and > * <i>SignedInteger</i> are as defined in <a > * href="http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#230798">&sect;3.10.2</a> > * of the <a href="http://java.sun.com/docs/books/jls/html/">Java 175,176c182,183 < * <p> < * To interpret localized string representations of a --- > * > * <p>To interpret localized string representations of a 197a205,209 > * <p>To avoid calling this method on a invalid string and having > * a <code>NumberFormatException</code> be thrown, the documentation > * for {@link Double#valueOf Double.valueOf} lists a regular > * expression which can be used to screen the input. > * ###@###.### 2003-02-13
13-02-2003

EVALUATION Should be fixed. ###@###.### 2002-06-20 Specification was changed to match implementation; behavior of String.trim now required. ###@###.### 2003-02-13
20-06-2002