Bug 66598 - IndexOutOfBoundsException when saving a XSSF document after overwriting a row multiple times
Summary: IndexOutOfBoundsException when saving a XSSF document after overwriting a row...
Status: RESOLVED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: XSSF (show other bugs)
Version: 5.2.3-FINAL
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-12 12:58 UTC by M.Brandl
Modified: 2023-05-14 07:49 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description M.Brandl 2023-05-12 12:58:49 UTC
Hi there,

when upgrading POI-OOXML from an ancient V 3.7 to latest stable 5.2.3, all of a sudden some code caused an IndexOutOfBoundsException when saving the document. Although it is getting thrown in XmlBeans, I guess its more at the XSSF side.

Exception in thread "main" java.lang.IndexOutOfBoundsException
	at org.apache.xmlbeans.impl.store.Xobj.removeElement(Xobj.java:2099)
	at org.apache.xmlbeans.impl.store.Xobj.remove_element(Xobj.java:2130)
	at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.removeC(CTRowImpl.java:146)
	at org.apache.poi.xssf.usermodel.XSSFRow.fixupCTCells(XSSFRow.java:612)
	at org.apache.poi.xssf.usermodel.XSSFRow.onDocumentWrite(XSSFRow.java:582)
	at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:3806)
	at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:3749)
	at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:467)
	at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:472)
	at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:221)
	at CreateExcel.writeToFile(CreateExcel.java:61)
	at CreateExcel.create(CreateExcel.java:23)
	at CreateExcel.main(CreateExcel.java:77)

The problem was that in some function the first row of a sheet was overwritten 1x by mistake but the header cells have been set multiple times in a loop. 

Admitedly this is probably not a common use case, but maybe there could be checked something and a meaninful error could be thrown. Finding the main cause took us some hours because the Exception didn't ring anything :)

below I pasted a small POC which triggers the Exception when the first row is clobbered twice (second run of the function).


Best 
Martin 

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;

public class CreateExcel {

    private final String o_filename;

    public CreateExcel(String p_filename) {
        o_filename = p_filename;
    }

    public void create() {
    	Workbook wb = new XSSFWorkbook();
        fillData(wb, 1);
        writeToFile(wb);
        System.out.println("First file is ok");
        wb = new XSSFWorkbook();
        fillData(wb, 0);
        writeToFile(wb);

    }


    private void fillData(Workbook p_wb, int startAtRow) {
        Sheet sheet = p_wb.createSheet("sheet123");
Row header =sheet.createRow(0);
boolean headerSet =false;
for (int rownum =startAtRow; rownum< 4; rownum++) {
//	if (!headerSet) {
		fillRow(header,true);
		headerSet =true;
//	}
	
	Row row =sheet.createRow(rownum);
		
	fillRow(row, false);
}
    }

	public void fillRow(Row row, boolean header) {
		String text =header ? "header " : "cell";
		for (int i =0; i < 10; i++) {
			Cell cell =row.createCell(i);
			cell.setCellValue(text +i);
		}
	}


    private void writeToFile(Workbook p_wb) {
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(o_filename);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            p_wb.write(fileOut);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if (fileOut != null) {
                fileOut.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        CreateExcel createExcel = new CreateExcel("e://wobo.xlsx");
        createExcel.create();
    }
}
Comment 1 Dominik Stadler 2023-05-14 07:49:27 UTC
Thanks for the nice report with reproducer code, it seems an invalid condition caused this and this was not covered by tests or production code at all until now.

Should be fixed in the next release via r1909808