diff options
author | Dominik Stadler <centic@apache.org> | 2015-08-19 13:36:08 +0000 |
---|---|---|
committer | Dominik Stadler <centic@apache.org> | 2015-08-19 13:36:08 +0000 |
commit | 7c44ce4dabc31d437307d72ba09411a5ae19b3b7 (patch) | |
tree | b7692ae5ccfff392a80341118d5025619e64f088 /src | |
parent | eb68abf765adf8be8744c096c555e92624553c7e (diff) | |
download | poi-7c44ce4dabc31d437307d72ba09411a5ae19b3b7.tar.gz poi-7c44ce4dabc31d437307d72ba09411a5ae19b3b7.zip |
POI Bug 58260: Fix checks for limit on number of styles in XSSF/SXSSF and fix having more than 32k styles in SXSSF workbooks
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1696586 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
3 files changed, 81 insertions, 5 deletions
diff --git a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java index c891509274..a119e457e4 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java @@ -563,11 +563,12 @@ public class StylesTable extends POIXMLDocumentPart { } public XSSFCellStyle createCellStyle() { - int xfSize = styleXfs.size(); - if (xfSize > MAXIMUM_STYLE_ID) + if (getNumCellStyles() > MAXIMUM_STYLE_ID) { throw new IllegalStateException("The maximum number of Cell Styles was exceeded. " + "You can define up to " + MAXIMUM_STYLE_ID + " style in a .xlsx Workbook"); + } + int xfSize = styleXfs.size(); CTXf xf = CTXf.Factory.newInstance(); xf.setNumFmtId(0); xf.setFontId(0); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java index fe72146617..fbcb6b103d 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java @@ -189,7 +189,12 @@ public class SheetDataWriter { String ref = new CellReference(_rownum, columnIndex).formatAsString();
_out.write("<c r=\"" + ref + "\"");
CellStyle cellStyle = cell.getCellStyle();
- if (cellStyle.getIndex() != 0) _out.write(" s=\"" + cellStyle.getIndex() + "\"");
+ if (cellStyle.getIndex() != 0) {
+ // need to convert the short to unsigned short as the indexes can be up to 64k
+ // ideally we would use int for this index, but that would need changes to some more
+ // APIs
+ _out.write(" s=\"" + (cellStyle.getIndex() & 0xffff) + "\"");
+ }
int cellType = cell.getCellType();
switch (cellType) {
case Cell.CELL_TYPE_BLANK: {
diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index 83450e45d4..a63e9db214 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -30,6 +30,7 @@ import java.io.IOException; import java.text.AttributedString; import java.util.HashMap; import java.util.Map; +import java.util.Random; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.PaneInformation; @@ -775,8 +776,7 @@ public abstract class BaseTestBugzillaIssues { // References to try - String ext = "xls"; - if (! (wb instanceof HSSFWorkbook)) ext += "x"; + String ext = _testDataProvider.getStandardFileNameExtension(); String refLocal = "'[test."+ext+"]Sheet1'!$A$2"; String refHttp = "'[http://example.com/test."+ext+"]Sheet1'!$A$2"; String otherCellText = "In Another Workbook"; @@ -1172,4 +1172,74 @@ public abstract class BaseTestBugzillaIssues { ev.evaluateFormulaCell(cell); assertEquals("ab", cell.getStringCellValue()); } + + @Test + public void bug58260() throws IOException { + //Create workbook and worksheet + Workbook wb = _testDataProvider.createWorkbook(); + Sheet worksheet = wb.createSheet("sample"); + + //Loop through and add all values from array list + // use a fixed seed to always produce the same file which makes comparing stuff easier + Random rnd = new Random(4352345); + int maxStyles = (wb instanceof HSSFWorkbook) ? 4009 : 64000; + for(int i = 0;i < maxStyles;i++) { + //Create new row + Row row = worksheet.createRow(i); + + //Create cell style + final CellStyle style; + try { + style = wb.createCellStyle(); + } catch (IllegalStateException e) { + throw new IllegalStateException("Failed for row " + i, e); + } + style.setAlignment(CellStyle.ALIGN_RIGHT); + if((wb instanceof HSSFWorkbook)) { + // there are some predefined styles + assertEquals(i+21, style.getIndex()); + } else { + // getIndex() returns short, which is not sufficient for > 32767 + // we should really change the API to be "int" for getIndex() but + // that needs API changes + assertEquals(i+1, style.getIndex() & 0xffff); + } + + //Create cell + Cell cell = row.createCell(0); + + //Set cell style + cell.setCellStyle(style); + + //Set cell value + cell.setCellValue("r" + rnd.nextInt()); + } + + // should fail if we try to add more now + try { + wb.createCellStyle(); + fail("Should fail after " + maxStyles + " styles, but did not fail"); + } catch (IllegalStateException e) { + // expected here + } + + /*//add column width for appearance sake + worksheet.setColumnWidth(0, 5000); + + // Write the output to a file + System.out.println("Writing..."); + OutputStream fileOut = new FileOutputStream("C:\\temp\\58260." + _testDataProvider.getStandardFileNameExtension()); + + // the resulting file can be compressed nicely, so we need to disable the zip bomb detection here + double before = ZipSecureFile.getMinInflateRatio(); + try { + ZipSecureFile.setMinInflateRatio(0.00001); + wb.write(fileOut); + } finally { + fileOut.close(); + ZipSecureFile.setMinInflateRatio(before); + }*/ + + wb.close(); + } } |