From 02719ac4ba076b0f4d4246794c7f5bae86123bcf Mon Sep 17 00:00:00 2001 From: Greg Woolsey Date: Sat, 24 Feb 2018 21:30:47 +0000 Subject: [PATCH] Fix for bug #62130. Turns out there were cases when a workbook with multiple edit/save cycles on the same instance would save stale cell data, resulting in incorrect copies. Includes new unit test. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1825277 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFRow.java | 48 +++++-------------- .../poi/xssf/usermodel/TestXSSFRow.java | 23 +++++++++ 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java index 78a92dac6c..0217f83117 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java @@ -498,43 +498,21 @@ public class XSSFRow implements Row, Comparable { * @see org.apache.poi.xssf.usermodel.XSSFSheet#write(java.io.OutputStream) () */ protected void onDocumentWrite(){ - // check if cells in the CTRow are ordered - boolean isOrdered = true; - CTCell[] cArray = _row.getCArray(); - if (cArray.length != _cells.size()) { - isOrdered = false; - } else { - int i = 0; - for (XSSFCell cell : _cells.values()) { - CTCell c1 = cell.getCTCell(); - CTCell c2 = cArray[i++]; - - String r1 = c1.getR(); - String r2 = c2.getR(); - if (!(r1==null ? r2==null : r1.equals(r2))){ - isOrdered = false; - break; - } - } + CTCell[] cArray = new CTCell[_cells.size()]; + int i = 0; + for (XSSFCell xssfCell : _cells.values()) { + cArray[i] = (CTCell) xssfCell.getCTCell().copy(); + + // we have to copy and re-create the XSSFCell here because the + // elements as otherwise setCArray below invalidates all the columns! + // see Bug 56170, XMLBeans seems to always release previous objects + // in the CArray, so we need to provide completely new ones here! + //_cells.put(entry.getKey(), new XSSFCell(this, cArray[i])); + xssfCell.setCTCell(cArray[i]); + i++; } - if(!isOrdered){ - cArray = new CTCell[_cells.size()]; - int i = 0; - for (XSSFCell xssfCell : _cells.values()) { - cArray[i] = (CTCell) xssfCell.getCTCell().copy(); - - // we have to copy and re-create the XSSFCell here because the - // elements as otherwise setCArray below invalidates all the columns! - // see Bug 56170, XMLBeans seems to always release previous objects - // in the CArray, so we need to provide completely new ones here! - //_cells.put(entry.getKey(), new XSSFCell(this, cArray[i])); - xssfCell.setCTCell(cArray[i]); - i++; - } - - _row.setCArray(cArray); - } + _row.setCArray(cArray); } /** diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java index 9db9171e1e..cf8c526355 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java @@ -18,6 +18,7 @@ package org.apache.poi.xssf.usermodel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; @@ -27,9 +28,11 @@ import org.apache.poi.ss.usermodel.BaseTestXRow; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellCopyPolicy; import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.RichTextString; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.XSSFITestDataProvider; +import org.apache.poi.xssf.XSSFTestDataSamples; import org.junit.Test; /** @@ -193,4 +196,24 @@ public final class TestXSSFRow extends BaseTestXRow { workbook.close(); } + + @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()); + } } -- 2.39.5