diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 35f3cbef91..b8b3e81d21 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53650 - Prevent unreadable content and disalow to overwrite rows from input template in SXSSF 54228,53672 - Fixed XSSF to read cells with missing R attribute 54206 - Ensure that shared formuals are updated when shifting rows in a spreadsheet Synchronize table headers with parent sheet in XSSF diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index c2c438d7d4..401f339de0 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -106,6 +106,20 @@ public class SXSSFSheet implements Sheet, Cloneable + ") outside allowable range (0.." + maxrow + ")"); } + // attempt to overwrite a row that is already flushed to disk + if(rownum <= _writer.getLastFlushedRow() ) { + throw new IllegalArgumentException( + "Attempting to write a row["+rownum+"] " + + "in the range [0," + _writer.getLastFlushedRow() + "] that is already written to disk."); + } + + // attempt to overwrite a existing row in the input template + if(_sh.getPhysicalNumberOfRows() > 0 && rownum <= _sh.getLastRowNum() ) { + throw new IllegalArgumentException( + "Attempting to write a row["+rownum+"] " + + "in the range [0," + _sh.getLastRowNum() + "] that is already written to disk."); + } + //Make the initial allocation as big as the row above. Row previousRow=rownum>0?getRow(rownum-1):null; int initialAllocationSize=0; diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java index 649d0b72fc..e205224758 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java @@ -44,6 +44,7 @@ public class SheetDataWriter { int _numberOfFlushedRows; int _lowestIndexOfFlushedRows; // meaningful only of _numberOfFlushedRows>0 int _numberOfCellsOfLastFlushedRow; // meaningful only of _numberOfFlushedRows>0 + int _numberLastFlushedRow = -1; // meaningful only of _numberOfFlushedRows>0 public SheetDataWriter() throws IOException { _fd = createTempFile(); @@ -105,6 +106,10 @@ public class SheetDataWriter { return _lowestIndexOfFlushedRows; } + public int getLastFlushedRow() { + return _numberLastFlushedRow; + } + protected void finalize() throws Throwable { _fd.delete(); } @@ -118,6 +123,7 @@ public class SheetDataWriter { public void writeRow(int rownum, SXSSFRow row) throws IOException { if (_numberOfFlushedRows == 0) _lowestIndexOfFlushedRows = rownum; + _numberLastFlushedRow = Math.max(rownum, _numberLastFlushedRow); _numberOfCellsOfLastFlushedRow = row.getLastCellNum(); _numberOfFlushedRows++; beginRow(rownum, row); diff --git a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java index 2116a0be52..db5a1362e2 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/streaming/TestSXSSFSheet.java @@ -19,8 +19,10 @@ package org.apache.poi.xssf.streaming; -import org.apache.poi.ss.usermodel.BaseTestSheet; +import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.SXSSFITestDataProvider; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class TestSXSSFSheet extends BaseTestSheet { @@ -90,4 +92,44 @@ public class TestSXSSFSheet extends BaseTestSheet { public void testDefaultColumnStyle() { //TODO column styles are not yet supported by XSSF } + + public void testOverrideFlushedRows() { + Workbook wb = new SXSSFWorkbook(3); + Sheet sheet = wb.createSheet(); + + sheet.createRow(1); + sheet.createRow(2); + sheet.createRow(3); + sheet.createRow(4); + try { + sheet.createRow(1); + fail("expected exception"); + } catch (Throwable e){ + assertEquals("Attempting to write a row[1] in the range [0,1] that is already written to disk.", e.getMessage()); + } + + } + + public void testOverrideRowsInTemplate() { + XSSFWorkbook template = new XSSFWorkbook(); + template.createSheet().createRow(1); + + Workbook wb = new SXSSFWorkbook(template); + Sheet sheet = wb.getSheetAt(0); + + try { + sheet.createRow(1); + fail("expected exception"); + } catch (Throwable e){ + assertEquals("Attempting to write a row[1] in the range [0,1] that is already written to disk.", e.getMessage()); + } + try { + sheet.createRow(0); + fail("expected exception"); + } catch (Throwable e){ + assertEquals("Attempting to write a row[0] in the range [0,1] that is already written to disk.", e.getMessage()); + } + sheet.createRow(2); + + } }