jkesselm 02/02/04 09:13:16
Modified: java/src/org/apache/xpath/objects XStringForFSB.java
Log:
Bugzilla 5346: Prevent mantissa overflow when converting string to double.
There is still a possible edge-case, since I detect overflow on decimal digit
bounds rather than on bit bounds; I'm not sure what the IEEE spec calls for.
Revision Changes Path
1.9 +31 -7
xml-xalan/java/src/org/apache/xpath/objects/XStringForFSB.java
Index: XStringForFSB.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XStringForFSB.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- XStringForFSB.java 2 Nov 2001 21:47:15 -0000 1.8
+++ XStringForFSB.java 4 Feb 2002 17:13:16 -0000 1.9
@@ -978,6 +978,8 @@
* the performance of this operation. Does XString.toDouble constitute
* any measurable percentage of our typical runtime? I suspect not!
*
+ * %REVIEW%
+ *
* @return A double value representation of the string, or return
Double.NaN
* if the string can not be converted. */
public double toDouble()
@@ -994,7 +996,7 @@
boolean trailingSpace=false;
int[] digitsFound={0,0}; // intpart,fracpart
int digitType=0; // Index to which kind of digit we're accumulating
- double doubleResult;
+ double doubleResult=0;
// Scan past leading whitespace characters
while(start< end &&
@@ -1040,8 +1042,21 @@
case '7':
case '8':
case '9':
- longResult = longResult * 10 + (c - '0'); // Accumulate as int
- ++digitsFound[digitType]; // Remember scaling
+ // We have a potential overflow issue that we need
+ // to guard against. See Bugzilla 5346.
+ //
+ // %REVIEW% Is it possible that we should be accepting _some_
+ // of the bits of the new digit, but not all of them?
+ long newResult = longResult * 10 + (c - '0');
+ if(newResult>0)
+ {
+ longResult=newResult;
+ ++digitsFound[digitType]; // Remember scaling
+ }
+ else
+ {
+ --digitsFound[1]; // Just scale up by 10, later
+ }
break;
default:
@@ -1059,10 +1074,19 @@
// the same thing.
long scale=1; // AFAIK, java doesn't have an easier 10^n
operation
- for(int i=digitsFound[1];i>0;--i)
- scale*=10;
-
- doubleResult=((double)longResult)/scale;
+
+ if(digitsFound[1]>0) // Normal fractional-part processing
+ {
+ for(int i=digitsFound[1];i>0;--i)
+ scale*=10;
+ doubleResult=((double)longResult)/scale;
+ }
+ else // Case where int-part
overflow exceeds frac-part length
+ {
+ for(int i=digitsFound[1];i<0;++i)
+ scale*=10;
+ doubleResult=((double)longResult)*scale;
+ }
if(isNegative)
doubleResult *= -1;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]