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
This commit is contained in:
Dominik Stadler 2015-08-19 13:36:08 +00:00
parent a6caec985c
commit c275dea88c
3 changed files with 81 additions and 5 deletions

View File

@ -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);

View File

@ -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: {

View File

@ -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();
}
}