Bug 61798 - Corrupted Excel file produced due to wrong dimension calculation during XSSFWorkbook.write(str) call
Summary: Corrupted Excel file produced due to wrong dimension calculation during XSSFW...
Alias: None
Product: POI
Classification: Unclassified
Component: XSSF (show other bugs)
Version: 3.17-FINAL
Hardware: PC All
: P2 major (vote)
Target Milestone: ---
Assignee: POI Developers List
Depends on: 53611
  Show dependency tree
Reported: 2017-11-22 13:33 UTC by Marek
Modified: 2017-12-28 08:47 UTC (History)
1 user (show)

Corrupted file generated by JUnit test attached (3.25 KB, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)
2017-11-22 13:33 UTC, Marek

Note You need to log in before you can comment on or make changes to this bug.
Description Marek 2017-11-22 13:33:09 UTC
Created attachment 35546 [details]
Corrupted file generated by JUnit test attached

Fix introduced for bug 53611 is causing another bug which produce a corrupted Excel file.

POI will generate corrupted file if dimension end column will be the last possible column (number 16384 /column XFD/).

Dimension calculation algorithm introduced in revision:
has a bug, which sets dimention end cell value too big (+1 column).

This bug will lead to corrupted file when last cell will be in use.

Following test:
has wrong assertion. Cell number 7 is H (not I) column.

Test code to easy reproduce this bug (corrupted Excel file):

public void test53611_bug() throws IOException {
    Workbook wb = new XSSFWorkbook();
    Sheet sheet = wb.createSheet("test");
    Row row = sheet.createRow(1);
    Cell cell = row.createCell(1);

    row = sheet.createRow(4);
	// Allowable column range for EXCEL2007 is (0..16383) or ('A'..'XDF')
    cell = row.createCell(16383);

    // we currently only populate the dimension during writing out
    // to avoid having to iterate all rows/cells in each add/remove of a row or cell
    //OutputStream str = new FileOutputStream("/tmp/53611_bug.xlsx");
    OutputStream str = new ByteArrayOutputStream();
    try {
    } finally {

	// Expected :B2:XFD5
	// Actual   :B2:XFE5   <-- which is out of Excel range. This will produce corrupted Excel file
    assertEquals("B2:XFD5", ((XSSFSheet)sheet).getCTWorksheet().getDimension().getRef());


Corrupted file generated by this test also attached.
Comment 1 dolphin.in.the.sky.51 2017-12-06 12:39:37 UTC
Excuse my poor English.

I am applying the patch of the following contents.

in org.apache.xssf.usermodel.XSSFSheet

protected write(OutputStream out) throws IOException {
   // then calculate min/max cell-numbers for the worksheet-dimension
    if(row.getFirstCellNum() != -1) {
//     maxCell = Math.min(maxCell, row.getLastCellNum());
       maxCell = Math.min(maxCell, row.getLastCellNum()-1);

Row.getLastCellNum() is return the index of the last cell contained in this row PLUS ONE. 

I would be pleased if it will be helpful.
Comment 2 dolphin.in.the.sky.51 2017-12-06 12:50:44 UTC
I made a mistake in patch code.

not "row.getFirstCellNum()"

Comment 3 Dominik Stadler 2017-12-28 08:47:06 UTC
Fixed with r1819404, now the dimension should be calculated correctly.