You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ye...@apache.org on 2010/08/10 20:49:21 UTC

svn commit: r984161 - in /poi/trunk/src: documentation/content/xdocs/status.xml java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java

Author: yegor
Date: Tue Aug 10 18:49:21 2010
New Revision: 984161

URL: http://svn.apache.org/viewvc?rev=984161&view=rev
Log:
fixed OperandResolver to correctly handle inputs with leading decimal place, see Bug #49723

Added:
    poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java
Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=984161&r1=984160&r2=984161&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Tue Aug 10 18:49:21 2010
@@ -34,6 +34,8 @@
 
     <changes>
         <release version="3.7-beta3" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="fix">49725 - avoid exception in OperandResolver.parseDouble when input is minus ("-")</action>
+           <action dev="POI-DEVELOPERS" type="fix">49723 - fixed OperandResolver to correctly handle inputs with leading decimal place</action>
            <action dev="POI-DEVELOPERS" type="add">initial support for Excel autofilter</action>
         </release>
         <release version="3.7-beta2" date="2010-08-09">

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java?rev=984161&r1=984160&r2=984161&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/eval/OperandResolver.java Tue Aug 10 18:49:21 2010
@@ -17,13 +17,28 @@
 
 package org.apache.poi.hssf.record.formula.eval;
 
+import java.util.regex.Pattern;
+
 /**
  * Provides functionality for evaluating arguments to functions and operators.
  *
  * @author Josh Micich
+ * @author Brendan Nolan
  */
 public final class OperandResolver {
 
+	// Based on regular expression defined in JavaDoc at {@link java.lang.Double#valueOf}
+	// modified to remove support for NaN, Infinity, Hexadecimal support and floating type suffixes
+    private static final String Digits	= "(\\p{Digit}+)";
+    private static final String Exp	= "[eE][+-]?"+Digits;
+    private static final String fpRegex	=
+        	    ("[\\x00-\\x20]*" +	
+        	     "[+-]?(" +	
+          	     "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+        
+        	     "(\\.("+Digits+")("+Exp+")?))))"+       
+        	     "[\\x00-\\x20]*"); 
+    	    
+	
 	private OperandResolver() {
 		// no instances of this class
 	}
@@ -214,11 +229,15 @@ public final class OperandResolver {
 
 	/**
 	 * Converts a string to a double using standard rules that Excel would use.<br/>
-	 * Tolerates currency prefixes, commas, leading and trailing spaces.<p/>
+	 * Tolerates leading and trailing spaces, <p/>
+	 * 
+	 * Doesn't support currency prefixes, commas, percentage signs or arithmetic operations strings.  
 	 *
 	 *  Some examples:<br/>
 	 *  " 123 " -&gt; 123.0<br/>
 	 *  ".123" -&gt; 0.123<br/>
+	 *  "1E4" -&gt; 1000<br/>
+	 *  "-123" -&gt; -123.0<br/>
 	 *  These not supported yet:<br/>
 	 *  " $ 1,000.00 " -&gt; 1000.0<br/>
 	 *  "$1.25E4" -&gt; 12500.0<br/>
@@ -228,29 +247,17 @@ public final class OperandResolver {
 	 * @return <code>null</code> if the specified text cannot be parsed as a number
 	 */
 	public static Double parseDouble(String pText) {
-		String text = pText.trim();
-		if(text.length() < 1) {
-			return null;
-		}
-		boolean isPositive = true;
-		if(text.charAt(0) == '-') {
-			isPositive = false;
-			text= text.substring(1).trim();
-		}
-
-		if(!Character.isDigit(text.charAt(0))) {
-			// avoid using NumberFormatException to tell when string is not a number
-			return null;
-		}
-		// TODO - support notation like '1E3' (==1000)
-
-		double val;
-		try {
-			val = Double.parseDouble(text);
-		} catch (NumberFormatException e) {
-			return null;
-		}
-		return new Double(isPositive ? +val : -val);
+		
+	    if (Pattern.matches(fpRegex, pText))
+			try {
+				return Double.parseDouble(pText);
+			} catch (NumberFormatException e) {
+				return null;
+			}
+	    else {
+	        return null;
+	    }
+		
 	}
 
 	/**

Added: poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java?rev=984161&view=auto
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java (added)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/record/formula/eval/TestOperandResolver.java Tue Aug 10 18:49:21 2010
@@ -0,0 +1,89 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.hssf.record.formula.eval;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+ * Tests for <tt>OperandResolver</tt>
+ *
+ * @author Brendan Nolan
+ */
+public final class TestOperandResolver extends TestCase {
+
+	public void testParseDouble_bug48472() {
+		
+		String value = "-";
+		
+		Double resolvedValue = null;
+		
+		try {
+			resolvedValue = OperandResolver.parseDouble(value);
+		} catch (StringIndexOutOfBoundsException e) { 
+			throw new AssertionFailedError("Identified bug 48472");
+		}
+		
+		assertEquals(null, resolvedValue);
+		
+	}
+	
+	public void testParseDouble_bug49723() {
+		
+		String value = ".1";
+		
+		Double resolvedValue = null;
+		
+		resolvedValue = OperandResolver.parseDouble(value);
+		
+		assertNotNull("Identified bug 49723", resolvedValue);
+		
+	}
+	
+	/**
+	 * 
+	 * Tests that a list of valid strings all return a non null value from {@link OperandResolver#parseDouble(String)}
+	 * 
+	 */
+	public void testParseDoubleValidStrings() {
+				
+		String[] values = new String[]{".19", "0.19", "1.9", "1E4", "-.19", "-0.19", "8.5","-1E4", ".5E6","+1.5","+1E5", "  +1E5  "};
+		
+		for (String value : values) {
+			assertTrue(OperandResolver.parseDouble(value) != null);
+			assertEquals(OperandResolver.parseDouble(value), Double.parseDouble(value));
+		}
+
+	}
+	
+	/**
+	 * 
+	 * Tests that a list of invalid strings all return null from {@link OperandResolver#parseDouble(String)}
+	 * 
+	 */
+	public void testParseDoubleInvalidStrings() {
+		
+		String[] values = new String[]{"-", "ABC", "-X", "1E5a", "Infinity", "NaN", ".5F", "1,000"};
+		
+		for (String value : values) {
+			assertEquals(null, OperandResolver.parseDouble(value));
+		}
+
+	}
+	
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org