]> source.dussan.org Git - poi.git/commitdiff
Bug 62629: Allow to handle files with invalid content types for pictures
authorDominik Stadler <centic@apache.org>
Thu, 27 Dec 2018 20:51:48 +0000 (20:51 +0000)
committerDominik Stadler <centic@apache.org>
Thu, 27 Dec 2018 20:51:48 +0000 (20:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1849814 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java
src/ooxml/testcases/org/apache/poi/openxml4j/opc/internal/TestContentTypeManager.java
test-data/spreadsheet/62629_target.xlsm [new file with mode: 0644]
test-data/spreadsheet/62629_toMerge.xlsx [new file with mode: 0644]

index 9b22850ddc23b4d41806bfbe7f05f473e700f974..4ca6189955e2d164d10e5c305f1c8eed8f7d2fc5 100644 (file)
@@ -153,8 +153,11 @@ public abstract class ContentTypeManager {
     public void addContentType(PackagePartName partName, String contentType) {
         boolean defaultCTExists = this.defaultContentType.containsValue(contentType);
         String extension = partName.getExtension().toLowerCase(Locale.ROOT);
-        if ((extension.length() == 0)
-                || (this.defaultContentType.containsKey(extension) && !defaultCTExists)) {
+        if ((extension.length() == 0) ||
+                // check if content-type and extension do match in both directions
+                // some applications create broken files, e.g. extension "jpg" instead of "jpeg"
+                (this.defaultContentType.containsKey(extension) && !defaultCTExists) ||
+                (!this.defaultContentType.containsKey(extension) && defaultCTExists)) {
             this.addOverrideContentType(partName, contentType);
         } else if (!defaultCTExists) {
             this.addDefaultContentType(extension, contentType);
index 936d0f9e8c667544689923ea10b676ebb736a99b..e4d8d4c33168eabd77b7308b4d7abd423db408dd 100644 (file)
@@ -18,9 +18,8 @@
 package org.apache.poi.openxml4j.opc.internal;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
 
 import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
@@ -31,8 +30,26 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.ss.usermodel.CreationHelper;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFDrawing;
+import org.apache.poi.xssf.usermodel.XSSFPicture;
+import org.apache.poi.xssf.usermodel.XSSFPictureData;
+import org.apache.poi.xssf.usermodel.XSSFShape;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
 
 public final class TestContentTypeManager {
 
@@ -44,21 +61,12 @@ public final class TestContentTypeManager {
         String filepath =  OpenXML4JTestDataSamples.getSampleFileName("sample.docx");
 
         // Retrieves core properties part
-        OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ);
-        try {
+        try (OPCPackage p = OPCPackage.open(filepath, PackageAccess.READ)) {
             PackageRelationshipCollection rels = p.getRelationshipsByType(PackageRelationshipTypes.CORE_PROPERTIES);
             PackageRelationship corePropertiesRelationship = rels.getRelationship(0);
             PackagePart coreDocument = p.getPart(corePropertiesRelationship);
 
             assertEquals("application/vnd.openxmlformats-package.core-properties+xml", coreDocument.getContentType());
-
-            // TODO - finish writing this test
-            assumeTrue("finish writing this test", false);
-
-            ContentTypeManager ctm = new ZipContentTypeManager(coreDocument.getInputStream(), p);
-            assertNotNull(ctm);
-        } finally {
-            p.close();
         }
     }
 
@@ -108,11 +116,11 @@ public final class TestContentTypeManager {
 
         assertEquals(ctm.getContentType(name1), "foo-type1");
         assertEquals(ctm.getContentType(name2), "foo-type1");
-        assertEquals(ctm.getContentType(name3), null);
+        assertNull(ctm.getContentType(name3));
 
         ctm.removeContentType(name1);
-        assertEquals(ctm.getContentType(name1), null);
-        assertEquals(ctm.getContentType(name2), null);
+        assertNull(ctm.getContentType(name1));
+        assertNull(ctm.getContentType(name2));
     }
 
     /**
@@ -124,4 +132,62 @@ public final class TestContentTypeManager {
         // TODO
         fail("test not written");
     }
+
+    protected byte[] toByteArray(Workbook wb) {
+        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
+            wb.write(os);
+            return os.toByteArray();
+        } catch (IOException e) {
+            throw new RuntimeException("failed to write excel file.");
+        }
+    }
+
+    @Test
+    public void bug62629CombinePictures() throws Exception {
+        // this file has incorrect default content-types which caused problems in Apache POI
+        // we now handle this broken file more gracefully
+        XSSFWorkbook book = XSSFTestDataSamples.openSampleWorkbook("62629_target.xlsm");
+        XSSFWorkbook b = XSSFTestDataSamples.openSampleWorkbook("62629_toMerge.xlsx");
+        for (int i = 0; i < b.getNumberOfSheets(); i++) {
+            XSSFSheet sheet = book.createSheet(b.getSheetName(i));
+            copyPictures(sheet, b.getSheetAt(i));
+        }
+
+        XSSFWorkbook wbBack = XSSFTestDataSamples.writeOutAndReadBack(book);
+        wbBack.close();
+        book.close();
+        b.close();
+    }
+
+    private static void copyPictures(Sheet newSheet, Sheet sheet) {
+        Drawing drawingOld = sheet.createDrawingPatriarch();
+        Drawing drawingNew = newSheet.createDrawingPatriarch();
+        CreationHelper helper = newSheet.getWorkbook().getCreationHelper();
+        if (drawingNew instanceof XSSFDrawing) {
+            List<XSSFShape> shapes = ((XSSFDrawing) drawingOld).getShapes();
+            for (int i = 0; i < shapes.size(); i++) {
+                if (shapes.get(i) instanceof XSSFPicture) {
+                    XSSFPicture pic = (XSSFPicture) shapes.get(i);
+                    XSSFPictureData picData = pic.getPictureData();
+                    int pictureIndex = newSheet.getWorkbook().addPicture(picData.getData(), picData.getPictureType());
+                    XSSFClientAnchor anchor = null;
+                    CTTwoCellAnchor oldAnchor = ((XSSFDrawing) drawingOld).getCTDrawing().getTwoCellAnchorArray(i);
+                    if (oldAnchor != null) {
+                        anchor = (XSSFClientAnchor) helper.createClientAnchor();
+                        CTMarker markerFrom = oldAnchor.getFrom();
+                        CTMarker markerTo = oldAnchor.getTo();
+                        anchor.setDx1((int) markerFrom.getColOff());
+                        anchor.setDx2((int) markerTo.getColOff());
+                        anchor.setDy1((int) markerFrom.getRowOff());
+                        anchor.setDy2((int) markerTo.getRowOff());
+                        anchor.setCol1(markerFrom.getCol());
+                        anchor.setCol2(markerTo.getCol());
+                        anchor.setRow1(markerFrom.getRow());
+                        anchor.setRow2(markerTo.getRow());
+                    }
+                    drawingNew.createPicture(anchor, pictureIndex);
+                }
+            }
+        }
+    }
 }
diff --git a/test-data/spreadsheet/62629_target.xlsm b/test-data/spreadsheet/62629_target.xlsm
new file mode 100644 (file)
index 0000000..3b55bab
Binary files /dev/null and b/test-data/spreadsheet/62629_target.xlsm differ
diff --git a/test-data/spreadsheet/62629_toMerge.xlsx b/test-data/spreadsheet/62629_toMerge.xlsx
new file mode 100644 (file)
index 0000000..dac7d76
Binary files /dev/null and b/test-data/spreadsheet/62629_toMerge.xlsx differ