From 690abbe5547df702ce83cf2fe63a3bc4c00f1df6 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Fri, 3 Apr 2015 15:55:21 +0000 Subject: [PATCH] Bug 56579: Throw exception if max string length of 32767 chars is exceeded in XSSF and SXSSF. Add verification testcase for bug 57008. Move some unit tests to the Bsae-Test-Class to verify things for all SS-implementations. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1671096 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/usermodel/HSSFCell.java | 8 +-- .../apache/poi/xssf/streaming/SXSSFCell.java | 11 +++ .../apache/poi/xssf/usermodel/XSSFCell.java | 5 ++ .../poi/ss/usermodel/BaseTestXCell.java | 28 +------- .../poi/xssf/XSSFITestDataProvider.java | 2 +- .../poi/xssf/usermodel/TestXSSFCell.java | 47 ++++++++++++ .../poi/hssf/usermodel/TestHSSFCell.java | 33 --------- .../apache/poi/ss/usermodel/BaseTestCell.java | 72 +++++++++++++++++++ 8 files changed, 141 insertions(+), 65 deletions(-) diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index e5de299a04..b1e8b7a008 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -538,18 +538,17 @@ public class HSSFCell implements Cell { public void setCellValue(RichTextString value) { - HSSFRichTextString hvalue = (HSSFRichTextString) value; int row=_record.getRow(); short col=_record.getColumn(); short styleIndex=_record.getXFIndex(); - if (hvalue == null) + if (value == null) { notifyFormulaChanging(); setCellType(CELL_TYPE_BLANK, false, row, col, styleIndex); return; } - if(hvalue.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){ + if(value.length() > SpreadsheetVersion.EXCEL97.getMaxTextLength()){ throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); } @@ -557,7 +556,7 @@ public class HSSFCell implements Cell { // Set the 'pre-evaluated result' for the formula // note - formulas do not preserve text formatting. FormulaRecordAggregate fr = (FormulaRecordAggregate) _record; - fr.setCachedStringResult(hvalue.getString()); + fr.setCachedStringResult(value.getString()); // Update our local cache to the un-formatted version _stringValue = new HSSFRichTextString(value.getString()); @@ -573,6 +572,7 @@ public class HSSFCell implements Cell { } int index = 0; + HSSFRichTextString hvalue = (HSSFRichTextString) value; UnicodeString str = hvalue.getUnicodeString(); index = _book.getWorkbook().addSSTString(str); (( LabelSSTRecord ) _record).setSSTIndex(index); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index f590cc01a2..7b67aa349d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -22,6 +22,7 @@ import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.formula.FormulaParseException; import org.apache.poi.ss.formula.eval.ErrorEval; import org.apache.poi.ss.usermodel.Cell; @@ -227,6 +228,11 @@ public class SXSSFCell implements Cell public void setCellValue(RichTextString value) { ensureRichTextStringType(); + + if(value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){ + throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); + } + ((RichTextValue)_value).setValue(value); } @@ -241,6 +247,11 @@ public class SXSSFCell implements Cell public void setCellValue(String value) { ensureTypeOrFormulaType(CELL_TYPE_STRING); + + if(value.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){ + throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); + } + if(_value.getType()==CELL_TYPE_FORMULA) ((StringFormulaValue)_value).setPreEvaluatedValue(value); else diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java index df8cbf2d2c..5c16f05e8b 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java @@ -346,6 +346,11 @@ public final class XSSFCell implements Cell { setCellType(Cell.CELL_TYPE_BLANK); return; } + + if(str.length() > SpreadsheetVersion.EXCEL2007.getMaxTextLength()){ + throw new IllegalArgumentException("The maximum length of cell contents (text) is 32,767 characters"); + } + int cellType = getCellType(); switch(cellType){ case Cell.CELL_TYPE_FORMULA: diff --git a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java index ba55f070a1..f78819ca30 100644 --- a/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java +++ b/src/ooxml/testcases/org/apache/poi/ss/usermodel/BaseTestXCell.java @@ -19,6 +19,7 @@ package org.apache.poi.ss.usermodel; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.ss.ITestDataProvider; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.streaming.SXSSFCell; @@ -48,32 +49,5 @@ public abstract class BaseTestXCell extends BaseTestCell { // invalid characters are replaced with question marks assertEquals("???<>\t\n\u00a0 &\"POI\'\u2122", wb.getSheetAt(0).getRow(0).getCell(0).getStringCellValue()); - - } - - public void testEncodingbeloAscii(){ - Workbook xwb = XSSFITestDataProvider.instance.createWorkbook(); - Cell xCell = xwb.createSheet().createRow(0).createCell(0); - - Workbook swb = SXSSFITestDataProvider.instance.createWorkbook(); - Cell sCell = swb.createSheet().createRow(0).createCell(0); - - StringBuffer sb = new StringBuffer(); - // test all possible characters - for(int i = 0; i < Character.MAX_VALUE; i++) sb.append((char)i) ; - - String str = sb.toString(); - - xCell.setCellValue(str); - assertEquals(str, xCell.getStringCellValue()); - sCell.setCellValue(str); - assertEquals(str, sCell.getStringCellValue()); - - xwb = XSSFITestDataProvider.instance.writeOutAndReadBack(xwb); - swb = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb); - xCell = xwb.getSheetAt(0).createRow(0).createCell(0); - sCell = swb.getSheetAt(0).createRow(0).createCell(0); - - assertEquals(xCell.getStringCellValue(), sCell.getStringCellValue()); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java b/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java index cacf8376ad..953b6a1807 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/XSSFITestDataProvider.java @@ -41,7 +41,7 @@ public final class XSSFITestDataProvider implements ITestDataProvider { public XSSFWorkbook writeOutAndReadBack(Workbook original) { if(!(original instanceof XSSFWorkbook)) { - throw new IllegalArgumentException("Expected an instance of XSSFWorkbook"); + throw new IllegalArgumentException("Expected an instance of XSSFWorkbook, but had " + original.getClass()); } return XSSFTestDataSamples.writeOutAndReadBack((XSSFWorkbook)original); } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java index 9740e416d5..1d020e9a33 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java @@ -19,6 +19,8 @@ package org.apache.poi.xssf.usermodel; import java.io.IOException; +import org.apache.poi.hssf.HSSFITestDataProvider; +import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.BaseTestXCell; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DataFormatter; @@ -28,6 +30,7 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.SXSSFITestDataProvider; import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.model.SharedStringsTable; @@ -402,4 +405,48 @@ public final class TestXSSFCell extends BaseTestXCell { wb.close(); } } + + public void testEncodingbeloAscii(){ + StringBuffer sb = new StringBuffer(); + // test all possible characters + for(int i = 0; i < Character.MAX_VALUE; i++) { + sb.append((char)i); + } + + String strAll = sb.toString(); + + // process in chunks as we have a limit on size of column now + int pos = 0; + while(pos < strAll.length()) { + String str = strAll.substring(pos, Math.min(strAll.length(), pos+SpreadsheetVersion.EXCEL2007.getMaxTextLength())); + + Workbook wb = HSSFITestDataProvider.instance.createWorkbook(); + Cell cell = wb.createSheet().createRow(0).createCell(0); + + Workbook xwb = XSSFITestDataProvider.instance.createWorkbook(); + Cell xCell = xwb.createSheet().createRow(0).createCell(0); + + Workbook swb = SXSSFITestDataProvider.instance.createWorkbook(); + Cell sCell = swb.createSheet().createRow(0).createCell(0); + + cell.setCellValue(str); + assertEquals(str, cell.getStringCellValue()); + xCell.setCellValue(str); + assertEquals(str, xCell.getStringCellValue()); + sCell.setCellValue(str); + assertEquals(str, sCell.getStringCellValue()); + + Workbook wbBack = HSSFITestDataProvider.instance.writeOutAndReadBack(wb); + Workbook xwbBack = XSSFITestDataProvider.instance.writeOutAndReadBack(xwb); + Workbook swbBack = SXSSFITestDataProvider.instance.writeOutAndReadBack(swb); + cell = wbBack.getSheetAt(0).createRow(0).createCell(0); + xCell = xwbBack.getSheetAt(0).createRow(0).createCell(0); + sCell = swbBack.getSheetAt(0).createRow(0).createCell(0); + + assertEquals(cell.getStringCellValue(), xCell.getStringCellValue()); + assertEquals(cell.getStringCellValue(), sCell.getStringCellValue()); + + pos += SpreadsheetVersion.EXCEL97.getMaxTextLength(); + } + } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java index 066c12e7f1..7c78fb0674 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFCell.java @@ -30,7 +30,6 @@ import org.apache.poi.hssf.record.DBCellRecord; import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.BaseTestCell; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.FormulaError; @@ -355,38 +354,6 @@ public final class TestHSSFCell extends BaseTestCell { assertEquals(DBCellRecord.class, dbcr.getClass()); } - /** - * The maximum length of cell contents (text) is 32,767 characters. - * @throws IOException - */ - public void testMaxTextLength() throws IOException{ - HSSFWorkbook wb = new HSSFWorkbook(); - HSSFSheet sheet = wb.createSheet(); - HSSFCell cell = sheet.createRow(0).createCell(0); - - int maxlen = SpreadsheetVersion.EXCEL97.getMaxTextLength(); - assertEquals(32767, maxlen); - - StringBuffer b = new StringBuffer() ; - - // 32767 is okay - for( int i = 0 ; i < maxlen ; i++ ) - { - b.append( "X" ) ; - } - cell.setCellValue(b.toString()); - - b.append("X"); - // 32768 produces an invalid XLS file - try { - cell.setCellValue(b.toString()); - fail("Expected exception"); - } catch (IllegalArgumentException e){ - assertEquals("The maximum length of cell contents (text) is 32,767 characters", e.getMessage()); - } - wb.close(); - } - /** * HSSF prior to version 3.7 had a bug: it could write a NaN but could not read such a file back. */ diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java index 35e95ab049..533a973974 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestCell.java @@ -25,6 +25,7 @@ import junit.framework.TestCase; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.ITestDataProvider; +import org.apache.poi.ss.SpreadsheetVersion; /** * Common superclass for testing implementations of @@ -695,4 +696,75 @@ public abstract class BaseTestCell extends TestCase { wb.close(); } + + public void test57008() throws IOException { + Workbook wb = _testDataProvider.createWorkbook(); + Sheet sheet = wb.createSheet(); + + Row row0 = sheet.createRow(0); + Cell cell0 = row0.createCell(0); + cell0.setCellValue("row 0, cell 0 _x0046_ without changes"); + + Cell cell1 = row0.createCell(1); + cell1.setCellValue("row 0, cell 1 _x005fx0046_ with changes"); + + Cell cell2 = row0.createCell(2); + cell2.setCellValue("hgh_x0041_**_x0100_*_x0101_*_x0190_*_x0200_*_x0300_*_x0427_*"); + + checkUnicodeValues(wb); + +// String fname = "/tmp/Test_xNNNN_inCell" + (wb instanceof HSSFWorkbook ? ".xls" : ".xlsx"); +// FileOutputStream out = new FileOutputStream(fname); +// try { +// wb.write(out); +// } finally { +// out.close(); +// } + + Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb); + checkUnicodeValues(wbBack); + } + + private void checkUnicodeValues(Workbook wb) { + assertEquals((wb instanceof HSSFWorkbook ? "row 0, cell 0 _x0046_ without changes" : "row 0, cell 0 F without changes"), + wb.getSheetAt(0).getRow(0).getCell(0).toString()); + assertEquals((wb instanceof HSSFWorkbook ? "row 0, cell 1 _x005fx0046_ with changes" : "row 0, cell 1 _x005fx0046_ with changes"), + wb.getSheetAt(0).getRow(0).getCell(1).toString()); + assertEquals((wb instanceof HSSFWorkbook ? "hgh_x0041_**_x0100_*_x0101_*_x0190_*_x0200_*_x0300_*_x0427_*" : "hghA**\u0100*\u0101*\u0190*\u0200*\u0300*\u0427*"), + wb.getSheetAt(0).getRow(0).getCell(2).toString()); + } + + /** + * The maximum length of cell contents (text) is 32,767 characters. + * @throws IOException + */ + public void testMaxTextLength() throws IOException{ + Workbook wb = _testDataProvider.createWorkbook(); + Sheet sheet = wb.createSheet(); + Cell cell = sheet.createRow(0).createCell(0); + + int maxlen = wb instanceof HSSFWorkbook ? + SpreadsheetVersion.EXCEL97.getMaxTextLength() + : SpreadsheetVersion.EXCEL2007.getMaxTextLength(); + assertEquals(32767, maxlen); + + StringBuffer b = new StringBuffer() ; + + // 32767 is okay + for( int i = 0 ; i < maxlen ; i++ ) + { + b.append( "X" ) ; + } + cell.setCellValue(b.toString()); + + b.append("X"); + // 32768 produces an invalid XLS file + try { + cell.setCellValue(b.toString()); + fail("Expected exception"); + } catch (IllegalArgumentException e){ + assertEquals("The maximum length of cell contents (text) is 32,767 characters", e.getMessage()); + } + wb.close(); + } } -- 2.39.5