You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by gw...@apache.org on 2019/01/11 18:20:03 UTC

svn commit: r1851084 - in /poi/trunk/src/ooxml: java/org/apache/poi/ooxml/POIXMLProperties.java testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java

Author: gwoolsey
Date: Fri Jan 11 18:20:03 2019
New Revision: 1851084

URL: http://svn.apache.org/viewvc?rev=1851084&view=rev
Log:
Bug #60977 writing XSSF with custom properties twice corrupts output

turns out the output XML data buffer for the custom properties document was appended to, not replaced, when writing in the presence of existing content.  Now clearing output buffer first in this case.  When first creating custom properties, i.e. first write after changes, there is no buffer yet, so nothing to clear.

Does not affect any read operations, or other writes beyond custom properties, as that was where the problem lay, not down in the Zip stuff.

Modified:
    poi/trunk/src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java

Modified: poi/trunk/src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java?rev=1851084&r1=1851083&r2=1851084&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/ooxml/POIXMLProperties.java Fri Jan 11 18:20:03 2019
@@ -232,6 +232,11 @@ public class POIXMLProperties {
             }
         }
         if(custPart != null && cust != null && cust.props != null){
+            /* bug #60977, when writing a file multiple times, 
+             * and there are custom properties and an existing package part,
+             * replace, don't append to raw document byte array
+             */
+            custPart.clear();
             try (OutputStream out = custPart.getOutputStream()) {
                 cust.props.save(out, DEFAULT_XML_OPTIONS);
             }

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java?rev=1851084&r1=1851083&r2=1851084&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/ooxml/TestPOIXMLProperties.java Fri Jan 11 18:20:03 2019
@@ -25,12 +25,18 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Optional;
 
 import org.apache.poi.ooxml.POIXMLProperties.CoreProperties;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LocaleUtil;
 import org.apache.poi.xssf.XSSFTestDataSamples;
@@ -272,4 +278,66 @@ public final class TestPOIXMLProperties
             return String.valueOf(i);
         }
     }
+
+    @Test
+    public void testBug60977() throws IOException {
+        
+        try (final XSSFWorkbook workbook = new XSSFWorkbook()) {
+            final Sheet sheet = workbook.createSheet("sheet");
+            final Row row = sheet.createRow(0);
+            final Cell cell = row.createCell(0);
+            cell.setCellValue("cell");
+
+            final POIXMLProperties properties = workbook.getProperties();
+            final POIXMLProperties.CustomProperties customProperties = properties.getCustomProperties();
+            final String propName = "Project";
+            final String propValue = "Some name";
+            customProperties.addProperty(propName, propValue);
+
+            // in the unit-test just try to write out the file more than once and see if we can still parse it
+            XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
+            assertNotNull(wbBack);
+            // properties documents are read lazily, so we have to access them to verify they parse properly
+            assertNotNull("First writeOutAndReadBack", wbBack.getProperties());
+            assertEquals("First prop check", propValue, wbBack.getProperties().getCustomProperties().getProperty(propName).getLpwstr());
+
+            customProperties.addProperty(propName + "1", propValue);
+            wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
+            assertNotNull(wbBack);
+            // properties documents are read lazily, so we have to access them to verify they parse properly
+            assertNotNull("Second writeOutAndReadBack", wbBack.getProperties());
+            assertEquals("Second prop check", propValue, wbBack.getProperties().getCustomProperties().getProperty(propName).getLpwstr());
+            assertEquals("Second prop check1", propValue, wbBack.getProperties().getCustomProperties().getProperty(propName + "1").getLpwstr());
+
+            wbBack = XSSFTestDataSamples.writeOutAndReadBack(workbook);
+            assertNotNull(wbBack);
+            // properties documents are read lazily, so we have to access them to verify they parse properly
+            assertNotNull("Third writeOutAndReadBack", wbBack.getProperties());
+            assertEquals("Third prop check", propValue, wbBack.getProperties().getCustomProperties().getProperty(propName).getLpwstr());
+            assertEquals("Third prop check1", propValue, wbBack.getProperties().getCustomProperties().getProperty(propName + "1").getLpwstr());
+            
+            /* Manual test to write out the file more than once:
+            File test1 = File.createTempFile("test1", ".xlsx", new File("C:\\temp"));
+            File test2 = File.createTempFile("test2", ".xlsx", new File("C:\\temp"));
+            try (final java.io.FileOutputStream fs = new java.io.FileOutputStream(test1)) {
+                workbook.write(fs);
+            }
+            try (final XSSFWorkbook wb = new XSSFWorkbook(test1)) {
+                assertNotNull(wb.getProperties());
+            } catch (InvalidFormatException e) {
+                fail("Test1 copy failed: " + e.getMessage());
+            }
+
+            try (final java.io.FileOutputStream fs = new java.io.FileOutputStream(test2)) {
+                workbook.write(fs);
+            }
+            
+            try (final XSSFWorkbook wb = new XSSFWorkbook(test2)) {
+                assertNotNull(wb.getProperties());
+            } catch (InvalidFormatException e) {
+                fail("Test2 copy failed: " + e.getMessage());
+            }
+             */
+        }
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org