Bug 62130 - XSSFRow can lose sync between CTRow and XSSFCell references to CTCell instances
Summary: XSSFRow can lose sync between CTRow and XSSFCell references to CTCell instances
Status: RESOLVED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: XSSF (show other bugs)
Version: 3.17-FINAL
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
: 62484 (view as bug list)
Depends on:
Blocks: 63657
  Show dependency tree
 
Reported: 2018-02-24 21:12 UTC by Greg Woolsey
Modified: 2019-08-11 08:29 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Greg Woolsey 2018-02-24 21:12:01 UTC
The fix for bug #56170 fixed some use cases of this, but is overly aggressive in looking for cases to do nothing.  Turns out there are too many ways the CTRow object's collection of CTCell objects can become stale compared to the XSSFCell collection held by XSSFRow.  Since the XSSF* values are the canonical ones, we should, on document write, always update the CTRow object to match the XSSFCell values.

This test case shows the problem, failing with 3.17 and 4.0 current trunk, because the saved value came from a stale CTRow:

@Test
public void testMultipleEditWriteCycles() {
        final XSSFWorkbook wb1 = new XSSFWorkbook();
        final XSSFSheet sheet1 = wb1.createSheet("Sheet1");
        final XSSFRow srcRow = sheet1.createRow(0);
        srcRow.createCell(0).setCellValue("hello");
        srcRow.createCell(3).setCellValue("world");
        
        // discard result
        XSSFTestDataSamples.writeOutAndReadBack(wb1);
        srcRow.createCell(1).setCellValue("cruel");
        // discard result
        XSSFTestDataSamples.writeOutAndReadBack(wb1);

        srcRow.getCell(1).setCellValue((RichTextString) null);
        
        XSSFWorkbook wb3 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
        assertEquals("Cell not blank"
                    , CellType.BLANK
                    , wb3.getSheet("Sheet1").getRow(0).getCell(1).getCellType());
}

The solution is to remove the extra logic from XSSFRow.onDocumentWrite() and always perform the update to CTRow at that point.  Otherwise, multiple edit/write cycles to the workbook will result in saved copies that don't match the logical structure of the original.
Comment 1 Greg Woolsey 2018-02-24 21:31:32 UTC
Fixed in r1825277.
Comment 2 Greg Woolsey 2018-06-27 02:05:27 UTC
*** Bug 62484 has been marked as a duplicate of this bug. ***
Comment 3 frank 2018-06-28 14:00:19 UTC
I can confirm that this fixed my issue as well (bug #62130). 
Thanks for providing the fix on such short notice!