]> source.dussan.org Git - poi.git/commitdiff
Bug 63768: Adjust handling of SchemaFactory
authorPJ Fanning <fanningpj@apache.org>
Tue, 24 Sep 2019 18:33:37 +0000 (18:33 +0000)
committerPJ Fanning <fanningpj@apache.org>
Tue, 24 Sep 2019 18:33:37 +0000 (18:33 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1867484 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/extractor/XSSFExportToXml.java
src/ooxml/testcases/org/apache/poi/xssf/extractor/TestXSSFExportToXML.java
test-data/spreadsheet/xxe_in_schema.xlsx [new file with mode: 0644]

index 9320a226dbb0db5f50b7fb83c61435552f08a0c7..53984fec281c04f75d5f9369b2c907c87b7aebff 100644 (file)
@@ -28,6 +28,7 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Vector;
 
+import javax.xml.XMLConstants;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -241,9 +242,10 @@ public class XSSFExportToXml implements Comparator<String>{
      * @throws SAXException If validating the document fails
      */
     private boolean isValid(Document xml) throws SAXException{
-        try{
+        try {
             String language = "http://www.w3.org/2001/XMLSchema";
             SchemaFactory factory = SchemaFactory.newInstance(language);
+            trySetFeature(factory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
 
             Source source = new DOMSource(map.getSchema());
             Schema schema = factory.newSchema(source);
@@ -313,7 +315,7 @@ public class XSSFExportToXml implements Comparator<String>{
         String[] xpathTokens = xpath.split("/");
 
 
-        Node currentNode =rootNode;
+        Node currentNode = rootNode;
         // The first token is empty, the second is the root node
         for(int i =2; i<xpathTokens.length;i++) {
 
@@ -535,4 +537,14 @@ public class XSSFExportToXml implements Comparator<String>{
         }
         return complexTypeNode;
     }
+
+    private static void trySetFeature(SchemaFactory sf, String feature, boolean enabled) {
+        try {
+            sf.setFeature(feature, enabled);
+        } catch (Exception e) {
+            LOG.log(POILogger.WARN, "SchemaFactory Feature unsupported", feature, e);
+        } catch (AbstractMethodError ame) {
+            LOG.log(POILogger.WARN, "Cannot set SchemaFactory feature because outdated XML parser in classpath", feature, ame);
+        }
+    }
 }
index e1c58b00cb77a2982b21ec6e4e42e86b9dd7e00b..282f02371e7babe3e92c7eff9b9711630f0e7445 100644 (file)
@@ -51,6 +51,7 @@ import org.junit.Test;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
 
 /**
  * @author Roberto Manicardi
@@ -59,7 +60,7 @@ public final class TestXSSFExportToXML {
 
     @Test
     public void testExportToXML() throws Exception {
-               try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx")) {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("CustomXMLMappings.xlsx")) {
 
             boolean found = false;
             for (POIXMLDocumentPart p : wb.getRelations()) {
@@ -102,12 +103,12 @@ public final class TestXSSFExportToXML {
             }
             assertTrue(found);
         }
-       }
+    }
 
     @Test
     public void testExportToXMLInverseOrder() throws Exception {
-               try (XSSFWorkbook wb = XSSFTestDataSamples
-                               .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx")) {
+        try (XSSFWorkbook wb = XSSFTestDataSamples
+                .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx")) {
 
             boolean found = false;
             for (POIXMLDocumentPart p : wb.getRelations()) {
@@ -150,12 +151,12 @@ public final class TestXSSFExportToXML {
             }
             assertTrue(found);
         }
-       }
+    }
 
     @Test
     public void testXPathOrdering() throws IOException {
-               try (XSSFWorkbook wb = XSSFTestDataSamples
-                               .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx")) {
+        try (XSSFWorkbook wb = XSSFTestDataSamples
+                .openSampleWorkbook("CustomXmlMappings-inverse-order.xlsx")) {
 
             boolean found = false;
             for (POIXMLDocumentPart p : wb.getRelations()) {
@@ -174,12 +175,12 @@ public final class TestXSSFExportToXML {
             }
             assertTrue(found);
         }
-       }
+    }
 
     @Test
     public void testMultiTable() throws Exception {
-               try (XSSFWorkbook wb = XSSFTestDataSamples
-                               .openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) {
+        try (XSSFWorkbook wb = XSSFTestDataSamples
+                .openSampleWorkbook("CustomXMLMappings-complex-type.xlsx")) {
 
             boolean found = false;
             for (POIXMLDocumentPart p : wb.getRelations()) {
@@ -218,7 +219,7 @@ public final class TestXSSFExportToXML {
             }
             assertTrue(found);
         }
-       }
+    }
 
     @Test
     @Ignore(value="Fails, but I don't know if it is ok or not...")
@@ -233,7 +234,7 @@ public final class TestXSSFExportToXML {
             }
         }
     }
-       
+
     @Test
     public void test55850ComplexXmlExport() throws Exception {
         try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55850.xlsx")) {
@@ -351,300 +352,300 @@ public final class TestXSSFExportToXML {
             assertTrue(found);
         }
     }
-   
-   @Test
-   public void testXmlExportIgnoresEmptyCells_Bugzilla_55924() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55924.xlsx")) {
-
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
-
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
-
-               XSSFMap map = mapInfo.getXSSFMapById(1);
-
-               assertNotNull("XSSFMap is null", map);
-
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, true);
-               String xmlData = os.toString("UTF-8");
 
-               assertNotNull(xmlData);
-               assertFalse(xmlData.isEmpty());
+    @Test
+    public void testXmlExportIgnoresEmptyCells_Bugzilla_55924() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55924.xlsx")) {
+
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
+
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
+
+                XSSFMap map = mapInfo.getXSSFMapById(1);
+
+                assertNotNull("XSSFMap is null", map);
+
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, true);
+                String xmlData = os.toString("UTF-8");
+
+                assertNotNull(xmlData);
+                assertFalse(xmlData.isEmpty());
+
+                String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
+                String euro = a.split("<EUR>")[1].split("</EUR>")[0].trim();
+                assertEquals("1", euro);
+
+                parseXML(xmlData);
+
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
+
+    @Test
+    public void testXmlExportSchemaWithXSAllTag_Bugzilla_56169() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56169.xlsx")) {
+
+            for (XSSFMap map : wb.getCustomXMLMappings()) {
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, true);
+                String xmlData = os.toString("UTF-8");
+
+                assertNotNull(xmlData);
+                assertTrue(!xmlData.isEmpty());
+
+                String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
+                String a_b = a.split("<B>")[1].split("</B>")[0].trim();
+                String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
+                String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
+                String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
+                String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
+
+                assertEquals("1", a_b_c_e_euro);
+                assertEquals("2", a_b_c_e_chf);
+
+                String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
+                String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
+
+                String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
+                String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
+
+                assertEquals("3", a_b_d_e_euro);
+                assertEquals("4", a_b_d_e_chf);
+            }
+        }
+    }
+
+    @Test
+    public void testXmlExportCompare_Bug_55923() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
+
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
+
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
+
+                XSSFMap map = mapInfo.getXSSFMapById(4);
+
+                assertNotNull("XSSFMap is null", map);
+
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                assertEquals(0, exporter.compare("", ""));
+                assertEquals(0, exporter.compare("/", "/"));
+                assertEquals(0, exporter.compare("//", "//"));
+                assertEquals(0, exporter.compare("/a/", "/b/"));
+
+                assertEquals(-1, exporter.compare("/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:EUR",
+                        "/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:CHF"));
+
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
+
+    @Test
+    public void testXmlExportSchemaOrderingBug_Bugzilla_55923() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
+
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
+
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
+
+                XSSFMap map = mapInfo.getXSSFMapById(4);
 
-               String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
-               String euro = a.split("<EUR>")[1].split("</EUR>")[0].trim();
-               assertEquals("1", euro);
+                assertNotNull("XSSFMap is null", map);
 
-               parseXML(xmlData);
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, true);
+                String xmlData = os.toString("UTF-8");
 
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
-
-   @Test
-   public void testXmlExportSchemaWithXSAllTag_Bugzilla_56169() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56169.xlsx")) {
+                assertNotNull(xmlData);
+                assertFalse(xmlData.isEmpty());
 
-           for (XSSFMap map : wb.getCustomXMLMappings()) {
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
+                String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
+                String a_b = a.split("<B>")[1].split("</B>")[0].trim();
+                String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
+                String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
+                String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
+                String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
 
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, true);
-               String xmlData = os.toString("UTF-8");
+                assertEquals("1", a_b_c_e_euro);
+                assertEquals("2", a_b_c_e_chf);
 
-               assertNotNull(xmlData);
-               assertTrue(!xmlData.isEmpty());
+                String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
+                String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
 
-               String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
-               String a_b = a.split("<B>")[1].split("</B>")[0].trim();
-               String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
-               String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
-               String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
-               String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
-
-               assertEquals("1", a_b_c_e_euro);
-               assertEquals("2", a_b_c_e_chf);
-
-               String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
-               String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
-
-               String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
-               String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
-
-               assertEquals("3", a_b_d_e_euro);
-               assertEquals("4", a_b_d_e_chf);
-           }
-       }
-   }
-   
-   @Test
-   public void testXmlExportCompare_Bug_55923() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
-
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
-
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
-
-               XSSFMap map = mapInfo.getXSSFMapById(4);
-
-               assertNotNull("XSSFMap is null", map);
-
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               assertEquals(0, exporter.compare("", ""));
-               assertEquals(0, exporter.compare("/", "/"));
-               assertEquals(0, exporter.compare("//", "//"));
-               assertEquals(0, exporter.compare("/a/", "/b/"));
-
-               assertEquals(-1, exporter.compare("/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:EUR",
-                       "/ns1:Entry/ns1:A/ns1:B/ns1:C/ns1:E/ns1:CHF"));
-
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
-   
-   @Test
-   public void testXmlExportSchemaOrderingBug_Bugzilla_55923() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
+                String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
+                String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
 
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
+                assertEquals("3", a_b_d_e_euro);
+                assertEquals("4", a_b_d_e_chf);
 
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
-
-               XSSFMap map = mapInfo.getXSSFMapById(4);
-
-               assertNotNull("XSSFMap is null", map);
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
 
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, true);
-               String xmlData = os.toString("UTF-8");
-
-               assertNotNull(xmlData);
-               assertFalse(xmlData.isEmpty());
-
-               String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
-               String a_b = a.split("<B>")[1].split("</B>")[0].trim();
-               String a_b_c = a_b.split("<C>")[1].split("</C>")[0].trim();
-               String a_b_c_e = a_b_c.split("<E>")[1].split("</EA>")[0].trim();
-               String a_b_c_e_euro = a_b_c_e.split("<EUR>")[1].split("</EUR>")[0].trim();
-               String a_b_c_e_chf = a_b_c_e.split("<CHF>")[1].split("</CHF>")[0].trim();
-
-               assertEquals("1", a_b_c_e_euro);
-               assertEquals("2", a_b_c_e_chf);
-
-               String a_b_d = a_b.split("<D>")[1].split("</Dd>")[0].trim();
-               String a_b_d_e = a_b_d.split("<E>")[1].split("</EA>")[0].trim();
+    private void parseXML(String xmlData) throws IOException, SAXException, ParserConfigurationException {
+        DocumentBuilderFactory docBuilderFactory = XMLHelper.getDocumentBuilderFactory();
+        docBuilderFactory.setNamespaceAware(true);
+        docBuilderFactory.setValidating(false);
+        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+        docBuilder.setEntityResolver(new DummyEntityResolver());
 
-               String a_b_d_e_euro = a_b_d_e.split("<EUR>")[1].split("</EUR>")[0].trim();
-               String a_b_d_e_chf = a_b_d_e.split("<CHF>")[1].split("</CHF>")[0].trim();
-
-               assertEquals("3", a_b_d_e_euro);
-               assertEquals("4", a_b_d_e_chf);
-
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
-   
-   private void parseXML(String xmlData) throws IOException, SAXException, ParserConfigurationException {
-       DocumentBuilderFactory docBuilderFactory = XMLHelper.getDocumentBuilderFactory();
-       docBuilderFactory.setNamespaceAware(true);
-       docBuilderFactory.setValidating(false);
-       DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
-       docBuilder.setEntityResolver(new DummyEntityResolver());
-
-       docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes(StandardCharsets.UTF_8)));
-   }
-
-   private static class DummyEntityResolver implements EntityResolver {
-       @Override
-       public InputSource resolveEntity(String publicId, String systemId) {
-           return null;
-       }
-   }
-   
-   @Test
-   public void testExportDataTypes() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
+        docBuilder.parse(new ByteArrayInputStream(xmlData.getBytes(StandardCharsets.UTF_8)));
+    }
 
-           Sheet sheet = wb.getSheetAt(0);
-           Row row = sheet.getRow(0);
+    private static class DummyEntityResolver implements EntityResolver {
+        @Override
+        public InputSource resolveEntity(String publicId, String systemId) {
+            return null;
+        }
+    }
 
-           Cell cString = row.createCell(0);
-           cString.setCellValue("somestring");
+    @Test
+    public void testExportDataTypes() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
 
-           Cell cBoolean = row.createCell(1);
-           cBoolean.setCellValue(true);
+            Sheet sheet = wb.getSheetAt(0);
+            Row row = sheet.getRow(0);
 
-           Cell cError = row.createCell(2);
-           cError.setCellErrorValue(FormulaError.NUM.getCode());
+            Cell cString = row.createCell(0);
+            cString.setCellValue("somestring");
 
-           Cell cFormulaString = row.createCell(3);
-           cFormulaString.setCellFormula("A1");
+            Cell cBoolean = row.createCell(1);
+            cBoolean.setCellValue(true);
 
-           Cell cFormulaNumeric = row.createCell(4);
-           cFormulaNumeric.setCellFormula("F1");
+            Cell cError = row.createCell(2);
+            cError.setCellErrorValue(FormulaError.NUM.getCode());
 
-           Cell cNumeric = row.createCell(5);
-           cNumeric.setCellValue(1.2);
+            Cell cFormulaString = row.createCell(3);
+            cFormulaString.setCellFormula("A1");
 
-           Cell cDate = row.createCell(6);
-           cDate.setCellValue(new Date());
+            Cell cFormulaNumeric = row.createCell(4);
+            cFormulaNumeric.setCellFormula("F1");
 
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
+            Cell cNumeric = row.createCell(5);
+            cNumeric.setCellValue(1.2);
 
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
+            Cell cDate = row.createCell(6);
+            cDate.setCellValue(new Date());
 
-               XSSFMap map = mapInfo.getXSSFMapById(4);
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
 
-               assertNotNull("XSSFMap is null", map);
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
 
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, true);
-               String xmlData = os.toString("UTF-8");
+                XSSFMap map = mapInfo.getXSSFMapById(4);
 
-               assertNotNull(xmlData);
-               assertFalse(xmlData.isEmpty());
+                assertNotNull("XSSFMap is null", map);
 
-               parseXML(xmlData);
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, true);
+                String xmlData = os.toString("UTF-8");
 
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
+                assertNotNull(xmlData);
+                assertFalse(xmlData.isEmpty());
 
-   @Test
-   public void testValidateFalse() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
+                parseXML(xmlData);
 
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
 
-               XSSFMap map = mapInfo.getXSSFMapById(4);
+    @Test
+    public void testValidateFalse() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("55923.xlsx")) {
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
 
-               assertNotNull("XSSFMap is null", map);
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
 
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, false);
-               String xmlData = os.toString("UTF-8");
+                XSSFMap map = mapInfo.getXSSFMapById(4);
 
-               assertNotNull(xmlData);
-               assertFalse(xmlData.isEmpty());
+                assertNotNull("XSSFMap is null", map);
 
-               parseXML(xmlData);
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, false);
+                String xmlData = os.toString("UTF-8");
+
+                assertNotNull(xmlData);
+                assertFalse(xmlData.isEmpty());
 
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
+                parseXML(xmlData);
+
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
 
-   @Test
-   public void testRefElementsInXmlSchema_Bugzilla_56730() throws Exception {
-       try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56730.xlsx")) {
+    @Test
+    public void testRefElementsInXmlSchema_Bugzilla_56730() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("56730.xlsx")) {
 
-           boolean found = false;
-           for (POIXMLDocumentPart p : wb.getRelations()) {
+            boolean found = false;
+            for (POIXMLDocumentPart p : wb.getRelations()) {
 
-               if (!(p instanceof MapInfo)) {
-                   continue;
-               }
-               MapInfo mapInfo = (MapInfo) p;
+                if (!(p instanceof MapInfo)) {
+                    continue;
+                }
+                MapInfo mapInfo = (MapInfo) p;
 
-               XSSFMap map = mapInfo.getXSSFMapById(1);
+                XSSFMap map = mapInfo.getXSSFMapById(1);
 
-               assertNotNull("XSSFMap is null", map);
+                assertNotNull("XSSFMap is null", map);
 
-               XSSFExportToXml exporter = new XSSFExportToXml(map);
-               ByteArrayOutputStream os = new ByteArrayOutputStream();
-               exporter.exportToXML(os, true);
-               String xmlData = os.toString("UTF-8");
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream os = new ByteArrayOutputStream();
+                exporter.exportToXML(os, true);
+                String xmlData = os.toString("UTF-8");
 
-               assertNotNull(xmlData);
-               assertFalse(xmlData.isEmpty());
+                assertNotNull(xmlData);
+                assertFalse(xmlData.isEmpty());
 
-               assertEquals("2014-12-31", xmlData.split("<DATE>")[1].split("</DATE>")[0].trim());
-               assertEquals("12.5", xmlData.split("<REFELEMENT>")[1].split("</REFELEMENT>")[0].trim());
+                assertEquals("2014-12-31", xmlData.split("<DATE>")[1].split("</DATE>")[0].trim());
+                assertEquals("12.5", xmlData.split("<REFELEMENT>")[1].split("</REFELEMENT>")[0].trim());
 
-               parseXML(xmlData);
+                parseXML(xmlData);
 
-               found = true;
-           }
-           assertTrue(found);
-       }
-   }
+                found = true;
+            }
+            assertTrue(found);
+        }
+    }
 
-   @Test
-   public void testBug59026() throws Exception {
+    @Test
+    public void testBug59026() throws Exception {
         try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("59026.xlsx")) {
             Collection<XSSFMap> mappings = wb.getCustomXMLMappings();
             assertTrue(mappings.size() > 0);
@@ -657,7 +658,7 @@ public final class TestXSSFExportToXML {
             }
         }
     }
-   
+
     @Test
     public void testExportTableWithNonMappedColumn_Bugzilla_61281() throws Exception {
         try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("61281.xlsx")) {
@@ -671,4 +672,15 @@ public final class TestXSSFExportToXML {
             }
         }
     }
+
+    @Test(expected = SAXParseException.class)
+    public void testXXEInSchema() throws Exception {
+        try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("xxe_in_schema.xlsx")) {
+            for (XSSFMap map : wb.getCustomXMLMappings()) {
+                XSSFExportToXml exporter = new XSSFExportToXml(map);
+                ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                exporter.exportToXML(bos, true);
+            }
+        }
+    }
 }
diff --git a/test-data/spreadsheet/xxe_in_schema.xlsx b/test-data/spreadsheet/xxe_in_schema.xlsx
new file mode 100644 (file)
index 0000000..aef99cc
Binary files /dev/null and b/test-data/spreadsheet/xxe_in_schema.xlsx differ