From: PJ Fanning Date: Wed, 28 Jul 2021 09:36:37 +0000 (+0000) Subject: [bug-65464] fix issue where shared formulas can be corrupted X-Git-Tag: REL_5_1_0~112 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=3aa03459a7db618daafef8c78977309fd25104cf;p=poi.git [bug-65464] fix issue where shared formulas can be corrupted git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1891849 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index 3ff4fc70e4..a631b5f22b 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -4619,18 +4619,21 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { DONE: for(int i = cell.getRowIndex(); i <= ref.getLastRow(); i++){ XSSFRow row = getRow(i); - if(row != null) for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){ - XSSFCell nextCell = row.getCell(j); - if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA){ - CTCellFormula nextF = nextCell.getCTCell().getF(); - nextF.setStringValue(nextCell.getCellFormula(evalWb)); - CellRangeAddress nextRef = new CellRangeAddress( - nextCell.getRowIndex(), ref.getLastRow(), - nextCell.getColumnIndex(), ref.getLastColumn()); - nextF.setRef(nextRef.formatAsString()); - - sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF); - break DONE; + if(row != null) { + for(int j = cell.getColumnIndex(); j <= ref.getLastColumn(); j++){ + XSSFCell nextCell = row.getCell(j); + if(nextCell != null && nextCell != cell && nextCell.getCellType() == CellType.FORMULA) { + CTCellFormula nextF = nextCell.getCTCell().getF(); + nextF.setStringValue(nextCell.getCellFormula(evalWb)); + nextF.setT(STCellFormulaType.SHARED); //https://bz.apache.org/bugzilla/show_bug.cgi?id=65464 + CellRangeAddress nextRef = new CellRangeAddress( + nextCell.getRowIndex(), ref.getLastRow(), + nextCell.getColumnIndex(), ref.getLastColumn()); + nextF.setRef(nextRef.formatAsString()); + + sharedFormulas.put(Math.toIntExact(nextF.getSi()), nextF); + break DONE; + } } } } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index 450f02b7af..ea5803bc90 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -117,13 +117,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedName; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDefinedNames; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells; -import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTFontImpl; import org.xml.sax.InputSource; import org.xml.sax.SAXParseException; @@ -3544,4 +3538,25 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { assertEquals(HorizontalAlignment.LEFT, cellLeft.getCellStyle().getAlignment()); } } + + @Test + void test65464() throws IOException { + try (XSSFWorkbook wb = openSampleWorkbook("bug65464.xlsx")) { + XSSFSheet sheet = wb.getSheet("SheetWithSharedFormula"); + XSSFCell v15 = sheet.getRow(14).getCell(21); + XSSFCell v16 = sheet.getRow(15).getCell(21); + assertEquals("U15/R15", v15.getCellFormula()); + assertEquals(STCellFormulaType.SHARED, v15.getCTCell().getF().getT()); + assertEquals("U16/R16", v16.getCellFormula()); + assertEquals(STCellFormulaType.NORMAL, v16.getCTCell().getF().getT()); //anomaly in original file + int calcChainSize = wb.getCalculationChain().getCTCalcChain().sizeOfCArray(); + + v15.removeFormula(); + assertEquals(CellType.NUMERIC, v15.getCellType(), "V15 is no longer a function"); + assertNull(v15.getCTCell().getF(), "V15 xmlbeans function removed"); + assertEquals("U16/R16", v16.getCellFormula()); + assertEquals(STCellFormulaType.SHARED, v16.getCTCell().getF().getT()); + assertEquals(calcChainSize - 1, wb.getCalculationChain().getCTCalcChain().sizeOfCArray()); + } + } } diff --git a/test-data/spreadsheet/bug65464.xlsx b/test-data/spreadsheet/bug65464.xlsx new file mode 100644 index 0000000000..48eccea220 Binary files /dev/null and b/test-data/spreadsheet/bug65464.xlsx differ