Author: yegor
Date: Sun Jan 27 06:55:32 2008
New Revision: 615610
URL: http://svn.apache.org/viewvc?rev=615610&view=rev
Log:
fix bug #44297: IntPtg must operate with unsigned short. Reading signed short
results in incorrect formula calculation.
Added:
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/44297.xls
(with props)
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java
(with props)
Modified:
poi/trunk/src/documentation/content/xdocs/changes.xml
poi/trunk/src/documentation/content/xdocs/status.xml
poi/trunk/src/java/org/apache/poi/hssf/record/formula/IntPtg.java
poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
Modified: poi/trunk/src/documentation/content/xdocs/changes.xml
URL:
http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/changes.xml?rev=615610&r1=615609&r2=615610&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/changes.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/changes.xml Sun Jan 27 06:55:32
2008
@@ -36,6 +36,7 @@
<!-- Don't forget to update status.xml too! -->
<release version="3.0.2-FINAL" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">44297 - IntPtg must
operate with unsigned short. Reading signed short results in incorrect formula
calculation</action>
<action dev="POI-DEVELOPERS" type="fix">44296 - Fix for reading
slide background images</action>
<action dev="POI-DEVELOPERS" type="fix">44293 - Avoid swapping
AreaPtgs from relative to absolute</action>
<action dev="POI-DEVELOPERS" type="fix">44292 - Correctly process
the last paragraph in a word file</action>
Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL:
http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=615610&r1=615609&r2=615610&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Sun Jan 27 06:55:32
2008
@@ -33,6 +33,7 @@
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.0.2-FINAL" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="fix">44297 - IntPtg must
operate with unsigned short. Reading signed short results in incorrect formula
calculation</action>
<action dev="POI-DEVELOPERS" type="fix">44296 - Fix for reading
slide background images</action>
<action dev="POI-DEVELOPERS" type="fix">44293 - Avoid swapping
AreaPtgs from relative to absolute</action>
<action dev="POI-DEVELOPERS" type="fix">44292 - Correctly process
the last paragraph in a word file</action>
Modified: poi/trunk/src/java/org/apache/poi/hssf/record/formula/IntPtg.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/formula/IntPtg.java?rev=615610&r1=615609&r2=615610&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/formula/IntPtg.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/formula/IntPtg.java Sun Jan
27 06:55:32 2008
@@ -40,7 +40,7 @@
{
public final static int SIZE = 3;
public final static byte sid = 0x1e;
- private short field_1_value;
+ private int field_1_value;
private IntPtg() {
//Required for clone methods
@@ -48,42 +48,31 @@
public IntPtg(RecordInputStream in)
{
- setValue(in.readShort());
+ setValue(in.readUShort());
}
// IntPtg should be able to create itself, shouldnt have to call setValue
public IntPtg(String formulaToken) {
- setValue(Short.parseShort(formulaToken));
+ setValue(Integer.parseInt(formulaToken));
}
/**
* Sets the wrapped value.
* Normally you should call with a positive int.
*/
- public void setValue(short value)
- {
- field_1_value = value;
- }
-
- /**
- * Sets the unsigned value.
- * (Handles conversion to the internal short value)
- */
public void setValue(int value)
{
- if(value > Short.MAX_VALUE) {
- // Need to wrap
- value -= (Short.MAX_VALUE+1)*2;
- }
- field_1_value = (short)value;
+ if(value < 0 || value > (Short.MAX_VALUE + 1)*2 )
+ throw new IllegalArgumentException("Unsigned short is out of
range: " + value);
+ field_1_value = value;
}
/**
* Returns the value as a short, which may have
* been wrapped into negative numbers
*/
- public short getValue()
+ public int getValue()
{
return field_1_value;
}
@@ -102,7 +91,7 @@
public void writeBytes(byte [] array, int offset)
{
array[ offset + 0 ] = sid;
- LittleEndian.putShort(array, offset + 1, getValue());
+ LittleEndian.putUShort(array, offset + 1, getValue());
}
public int getSize()
Added: poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/44297.xls
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/44297.xls?rev=615610&view=auto
==============================================================================
Binary file - no diff available.
Propchange:
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/44297.xls
------------------------------------------------------------------------------
svn:executable = *
Propchange:
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/data/44297.xls
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added:
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java?rev=615610&view=auto
==============================================================================
---
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java
(added)
+++
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java
Sun Jan 27 06:55:32 2008
@@ -0,0 +1,103 @@
+package org.apache.poi.hssf.usermodel;
+/* ====================================================================
+ 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.
+==================================================================== */
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.File;
+
+/**
+ * Bug 44297: 32767+32768 is evaluated to -1
+ * Fix: IntPtg must operate with unsigned short. Reading signed short results
in incorrect formula calculation
+ * if a formula has values in the interval [Short.MAX_VALUE,
(Short.MAX_VALUE+1)*2]
+ *
+ * @author Yegor Kozlov
+ */
+
+public class TestBug44297 extends TestCase {
+ protected String cwd = System.getProperty("HSSF.testdata.path");
+
+ public void test44297() throws IOException {
+ FileInputStream in = new FileInputStream(new File(cwd, "44297.xls"));
+ HSSFWorkbook wb = new HSSFWorkbook(in);
+ in.close();
+
+ HSSFRow row;
+ HSSFCell cell;
+
+ HSSFSheet sheet = wb.getSheetAt(0);
+
+ HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
+
+ row = (HSSFRow)sheet.getRow(0);
+ cell = row.getCell((short)0);
+ assertEquals("31+46", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(77, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(1);
+ cell = row.getCell((short)0);
+ assertEquals("30+53", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(83, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(2);
+ cell = row.getCell((short)0);
+ assertEquals("SUM(A1:A2)", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(160, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(4);
+ cell = row.getCell((short)0);
+ assertEquals("32767+32768", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(65535, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(7);
+ cell = row.getCell((short)0);
+ assertEquals("32744+42333", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(75077, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(8);
+ cell = row.getCell((short)0);
+ assertEquals("327680.0/32768", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(10, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(9);
+ cell = row.getCell((short)0);
+ assertEquals("32767+32769", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(65536, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(10);
+ cell = row.getCell((short)0);
+ assertEquals("35000+36000", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(71000, eva.evaluate(cell).getNumberValue(), 0);
+
+ row = (HSSFRow)sheet.getRow(11);
+ cell = row.getCell((short)0);
+ assertEquals("-1000000.0-3000000.0", cell.getCellFormula());
+ eva.setCurrentRow(row);
+ assertEquals(-4000000, eva.evaluate(cell).getNumberValue(), 0);
+ }
+
+}
Propchange:
poi/trunk/src/scratchpad/testcases/org/apache/poi/hssf/usermodel/TestBug44297.java
------------------------------------------------------------------------------
svn:executable = *
Modified:
poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
URL:
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java?rev=615610&r1=615609&r2=615610&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
(original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
Sun Jan 27 06:55:32 2008
@@ -379,15 +379,16 @@
fp = new FormulaParser("40000", null);
fp.parse();
ptg=fp.getRPNPtg();
- assertTrue("ptg should be Number, is "+ptg[0].getClass(),
ptg[0] instanceof NumberPtg);
+ assertTrue("ptg should be IntPtg, is "+ptg[0].getClass(),
ptg[0] instanceof IntPtg);
}
+
/** bug 33160, testcase by Amol Deshmukh*/
public void testSimpleLongFormula() {
FormulaParser fp = new FormulaParser("40000/2", null);
fp.parse();
Ptg[] ptgs = fp.getRPNPtg();
assertTrue("three tokens expected, got
"+ptgs.length,ptgs.length == 3);
- assertTrue("NumberPtg",(ptgs[0] instanceof NumberPtg));
+ assertTrue("IntPtg",(ptgs[0] instanceof IntPtg));
assertTrue("IntPtg",(ptgs[1] instanceof IntPtg));
assertTrue("DividePtg",(ptgs[2] instanceof DividePtg));
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]