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]

Reply via email to