diff --git a/.classpath b/.classpath index d3cabd61b..f3e6af28f 100644 --- a/.classpath +++ b/.classpath @@ -20,7 +20,7 @@ - + diff --git a/build.xml b/build.xml index a90ba392a..fede4bce6 100644 --- a/build.xml +++ b/build.xml @@ -146,9 +146,12 @@ under the License. - - + + + @@ -218,7 +221,7 @@ under the License. - + @@ -249,7 +252,7 @@ under the License. - + @@ -408,7 +411,8 @@ under the License. - + + @@ -423,13 +427,17 @@ under the License. - - + + + + + + @@ -474,7 +482,7 @@ under the License. + classpath="${ooxml.xmlbeans23.jar}:${ooxml.jsr173.jar}"/> @@ -513,7 +521,7 @@ under the License. description="Compiles the OOXML encryption xsd files into XmlBeans"> + classpath="${ooxml.xmlbeans23.jar}:${ooxml.jsr173.jar}"/> @@ -1255,7 +1263,7 @@ under the License. - + @@ -1284,7 +1292,7 @@ under the License. - + diff --git a/maven/poi-ooxml-schemas.pom b/maven/poi-ooxml-schemas.pom index 361fe64f3..baf531d54 100644 --- a/maven/poi-ooxml-schemas.pom +++ b/maven/poi-ooxml-schemas.pom @@ -62,7 +62,7 @@ org.apache.xmlbeans xmlbeans - 2.3.0 + 2.6.0 diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocument.java b/src/ooxml/java/org/apache/poi/POIXMLDocument.java index fa41a5744..a1e6f95a8 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocument.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocument.java @@ -34,6 +34,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationshipCollection; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.util.IOUtils; +import org.apache.xmlbeans.impl.common.SystemCache; public abstract class POIXMLDocument extends POIXMLDocumentPart{ public static final String DOCUMENT_CREATOR = "Apache POI"; @@ -55,6 +56,11 @@ public abstract class POIXMLDocument extends POIXMLDocumentPart{ protected POIXMLDocument(OPCPackage pkg) { super(pkg); this.pkg = pkg; + + // Workaround for XMLBEANS-512 - ensure that when we parse + // the file, we start with a fresh XML Parser each time, + // and avoid the risk of getting a SaxHandler that's in error + SystemCache.get().setSaxLoader(null); } /** diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java index e157176eb..f98002b1b 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/PackageRelationshipCollection.java @@ -22,10 +22,10 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.TreeMap; +import org.apache.poi.util.SAXHelper; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; -import org.dom4j.io.SAXReader; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; import org.apache.poi.util.POILogger; @@ -298,21 +298,19 @@ public final class PackageRelationshipCollection implements return relationshipsByID.values().size(); } - /** - * Parse the relationship part and add all relationship in this collection. - * - * @param relPart - * The package part to parse. - * @throws InvalidFormatException - * Throws if the relationship part is invalid. - */ - private void parseRelationshipsPart(PackagePart relPart) - throws InvalidFormatException { - try { - SAXReader reader = new SAXReader(); - logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName()); - Document xmlRelationshipsDoc = reader - .read(relPart.getInputStream()); + /** + * Parse the relationship part and add all relationship in this collection. + * + * @param relPart + * The package part to parse. + * @throws InvalidFormatException + * Throws if the relationship part is invalid. + */ + private void parseRelationshipsPart(PackagePart relPart) + throws InvalidFormatException { + try { + logger.log(POILogger.DEBUG, "Parsing relationship: " + relPart.getPartName()); + Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); // Browse default types Element root = xmlRelationshipsDoc.getRootElement(); diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java index b8c30df93..2c3b97a7f 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ContentTypeManager.java @@ -23,8 +23,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Iterator; import java.util.List; -import java.util.TreeMap; import java.util.Map.Entry; +import java.util.TreeMap; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidOperationException; @@ -33,13 +33,13 @@ import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePartName; import org.apache.poi.openxml4j.opc.PackagingURIHelper; +import org.apache.poi.util.SAXHelper; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.QName; -import org.dom4j.io.SAXReader; /** * Manage package content types ([Content_Types].xml part). @@ -373,8 +373,7 @@ public abstract class ContentTypeManager { private void parseContentTypesFile(InputStream in) throws InvalidFormatException { try { - SAXReader xmlReader = new SAXReader(); - Document xmlContentTypetDoc = xmlReader.read(in); + Document xmlContentTypetDoc = SAXHelper.readSAXDocument(in); // Default content types List defaultTypes = xmlContentTypetDoc.getRootElement().elements( diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java index 36719d347..6f1d62b8a 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/unmarshallers/PackagePropertiesUnmarshaller.java @@ -23,13 +23,6 @@ import java.util.Iterator; import java.util.List; import java.util.zip.ZipEntry; -import org.dom4j.Attribute; -import org.dom4j.Document; -import org.dom4j.DocumentException; -import org.dom4j.Element; -import org.dom4j.Namespace; -import org.dom4j.QName; -import org.dom4j.io.SAXReader; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackageNamespaces; import org.apache.poi.openxml4j.opc.PackagePart; @@ -38,6 +31,13 @@ import org.apache.poi.openxml4j.opc.ZipPackage; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; import org.apache.poi.openxml4j.opc.internal.PartUnmarshaller; import org.apache.poi.openxml4j.opc.internal.ZipHelper; +import org.apache.poi.util.SAXHelper; +import org.dom4j.Attribute; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.Namespace; +import org.dom4j.QName; /** * Package properties unmarshaller. @@ -118,10 +118,9 @@ public final class PackagePropertiesUnmarshaller implements PartUnmarshaller { "Error while trying to get the part input stream."); } - SAXReader xmlReader = new SAXReader(); Document xmlDoc; try { - xmlDoc = xmlReader.read(in); + xmlDoc = SAXHelper.readSAXDocument(in); /* Check OPC compliance */ diff --git a/src/ooxml/java/org/apache/poi/util/SAXHelper.java b/src/ooxml/java/org/apache/poi/util/SAXHelper.java new file mode 100644 index 000000000..b38b2c2be --- /dev/null +++ b/src/ooxml/java/org/apache/poi/util/SAXHelper.java @@ -0,0 +1,92 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.lang.reflect.Method; + +import javax.xml.XMLConstants; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.io.SAXReader; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + + +/** + * Provides handy methods for working with SAX parsers and readers + */ +public final class SAXHelper { + private static POILogger logger = POILogFactory.getLogger(SAXHelper.class); + + /** + * Creates a new SAX Reader, with sensible defaults + */ + public static SAXReader getSAXReader() { + SAXReader xmlReader = new SAXReader(); + xmlReader.setValidation(false); + xmlReader.setEntityResolver(new EntityResolver() { + public InputSource resolveEntity(String publicId, String systemId) + throws SAXException, IOException { + return new InputSource(new StringReader("")); + } + }); + trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING, true); + trySetXercesSecurityManager(xmlReader); + return xmlReader; + } + private static void trySetSAXFeature(SAXReader xmlReader, String feature, boolean enabled) { + try { + xmlReader.setFeature(feature, enabled); + } catch (Exception e) { + logger.log(POILogger.INFO, "SAX Feature unsupported", feature, e); + } + } + private static void trySetXercesSecurityManager(SAXReader xmlReader) { + // Try built-in JVM one first, standalone if not + for (String securityManagerClassName : new String[] { + "com.sun.org.apache.xerces.internal.util.SecurityManager", + "org.apache.xerces.util.SecurityManager" + }) { + try { + Object mgr = Class.forName(securityManagerClassName).newInstance(); + Method setLimit = mgr.getClass().getMethod("setEntityExpansionLimit", Integer.TYPE); + setLimit.invoke(mgr, 4096); + xmlReader.setProperty("http://apache.org/xml/properties/security-manager", mgr); + // Stop once one can be setup without error + return; + } catch (Exception e) { + logger.log(POILogger.INFO, "SAX Security Manager could not be setup", e); + } + } + } + + /** + * Parses the given stream via the default (sensible) + * SAX Reader + * @param inp Stream to read the XML data from + * @return the SAX processed Document + */ + public static Document readSAXDocument(InputStream inp) throws DocumentException { + return getSAXReader().read(inp); + } +} diff --git a/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java b/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java index 432b1faab..420eed7c1 100644 --- a/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java @@ -20,16 +20,20 @@ package org.apache.poi.xssf.model; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlOptions; -import org.apache.poi.POIXMLDocumentPart; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSst; import org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument; -import org.apache.poi.openxml4j.opc.PackagePart; -import org.apache.poi.openxml4j.opc.PackageRelationship; /** diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java index b4ac8bd7c..01116abcf 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackage.java @@ -17,10 +17,19 @@ package org.apache.poi.openxml4j.opc; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.lang.reflect.Field; import java.net.URI; -import java.util.*; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.TreeMap; import java.util.regex.Pattern; import junit.framework.TestCase; @@ -31,15 +40,15 @@ import org.apache.poi.openxml4j.exceptions.InvalidOperationException; import org.apache.poi.openxml4j.opc.internal.ContentTypeManager; import org.apache.poi.openxml4j.opc.internal.FileHelper; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; -import org.apache.poi.util.TempFile; -import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; +import org.apache.poi.util.SAXHelper; +import org.apache.poi.util.TempFile; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.Namespace; import org.dom4j.QName; -import org.dom4j.io.SAXReader; public final class TestPackage extends TestCase { private static final POILogger logger = POILogFactory.getLogger(TestPackage.class); @@ -211,9 +220,8 @@ public final class TestPackage extends TestCase { private void assertMSCompatibility(OPCPackage pkg) throws Exception { PackagePartName relName = PackagingURIHelper.createPartName(PackageRelationship.getContainerPartRelationship()); PackagePart relPart = pkg.getPart(relName); - SAXReader reader = new SAXReader(); - Document xmlRelationshipsDoc = reader - .read(relPart.getInputStream()); + + Document xmlRelationshipsDoc = SAXHelper.readSAXDocument(relPart.getInputStream()); Element root = xmlRelationshipsDoc.getRootElement(); for (Iterator i = root diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java index d5ca8936d..d3dfee130 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestPackageCoreProperties.java @@ -21,6 +21,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; @@ -33,8 +34,8 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart; import org.apache.poi.openxml4j.util.Nullable; -import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; public final class TestPackageCoreProperties extends TestCase { private static final POILogger logger = POILogFactory.getLogger(TestPackageCoreProperties.class); @@ -197,4 +198,29 @@ public final class TestPackageCoreProperties extends TestCase { props2.setTitleProperty("Bug 51444 fixed"); } + public void testEntitiesInCoreProps_56164() throws Exception { + InputStream is = OpenXML4JTestDataSamples.openSampleStream("CorePropertiesHasEntities.ooxml"); + OPCPackage p = OPCPackage.open(is); + is.close(); + + // Should have 3 root relationships + boolean foundDocRel = false, foundCorePropRel = false, foundExtPropRel = false; + for (PackageRelationship pr : p.getRelationships()) { + if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_DOCUMENT)) + foundDocRel = true; + if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) + foundCorePropRel = true; + if (pr.getRelationshipType().equals(PackageRelationshipTypes.EXTENDED_PROPERTIES)) + foundExtPropRel = true; + } + assertTrue("Core/Doc Relationship not found in " + p.getRelationships(), foundDocRel); + assertTrue("Core Props Relationship not found in " + p.getRelationships(), foundCorePropRel); + assertTrue("Ext Props Relationship not found in " + p.getRelationships(), foundExtPropRel); + + // Get the Core Properties + PackagePropertiesPart props = (PackagePropertiesPart)p.getPackageProperties(); + + // Check + assertEquals("Stefan Kopf", props.getCreatorProperty().getValue()); + } } diff --git a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java index f32935670..6a32c38e5 100644 --- a/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java +++ b/src/ooxml/testcases/org/apache/poi/openxml4j/opc/TestRelationships.java @@ -17,15 +17,18 @@ package org.apache.poi.openxml4j.opc; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.net.URI; import java.util.regex.Pattern; import junit.framework.TestCase; import org.apache.poi.openxml4j.OpenXML4JTestDataSamples; -import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogFactory; +import org.apache.poi.util.POILogger; +import org.apache.poi.xwpf.usermodel.XWPFRelation; public class TestRelationships extends TestCase { @@ -309,6 +312,7 @@ public class TestRelationships extends TestCase { URI rel1 = parent.relativize(rId1.getTargetURI()); URI rel11 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId1.getTargetURI()); assertEquals("'Another Sheet'!A1", rel1.getFragment()); + assertEquals("'Another Sheet'!A1", rel11.getFragment()); PackageRelationship rId2 = drawingPart.getRelationship("rId2"); URI rel2 = PackagingURIHelper.relativizeURI(drawingPart.getPartName().getURI(), rId2.getTargetURI()); @@ -390,6 +394,40 @@ public class TestRelationships extends TestCase { targetUri = rId1.getTargetURI(); assertEquals("mailto:nobody@nowhere.uk%C2%A0", targetUri.toASCIIString()); assertEquals("nobody@nowhere.uk\u00A0", targetUri.getSchemeSpecificPart()); + } + + public void testEntitiesInRels_56164() throws Exception { + InputStream is = OpenXML4JTestDataSamples.openSampleStream("PackageRelsHasEntities.ooxml"); + OPCPackage p = OPCPackage.open(is); + is.close(); + // Should have 3 root relationships + boolean foundDocRel = false, foundCorePropRel = false, foundExtPropRel = false; + for (PackageRelationship pr : p.getRelationships()) { + if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_DOCUMENT)) + foundDocRel = true; + if (pr.getRelationshipType().equals(PackageRelationshipTypes.CORE_PROPERTIES)) + foundCorePropRel = true; + if (pr.getRelationshipType().equals(PackageRelationshipTypes.EXTENDED_PROPERTIES)) + foundExtPropRel = true; + } + assertTrue("Core/Doc Relationship not found in " + p.getRelationships(), foundDocRel); + assertTrue("Core Props Relationship not found in " + p.getRelationships(), foundCorePropRel); + assertTrue("Ext Props Relationship not found in " + p.getRelationships(), foundExtPropRel); + + // Should have normal work parts + boolean foundCoreProps = false, foundDocument = false; + for (PackagePart part : p.getParts()) { + if (part.getPartName().toString().equals("/docProps/core.xml")) { + assertEquals(ContentTypes.CORE_PROPERTIES_PART, part.getContentType()); + foundCoreProps = true; + } + if (part.getPartName().toString().equals("/word/document.xml")) { + assertEquals(XWPFRelation.DOCUMENT.getContentType(), part.getContentType()); + foundDocument = true; + } + } + assertTrue("Core not found in " + p.getParts(), foundCoreProps); + assertTrue("Document not found in " + p.getParts(), foundDocument); } } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java index faf5825b0..2c727d0dd 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java @@ -32,6 +32,8 @@ import java.util.List; import org.apache.poi.EncryptedDocumentException; import org.apache.poi.POIDataSamples; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLException; +import org.apache.poi.POIXMLProperties; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackagePart; @@ -1440,4 +1442,37 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues { fail("Should've raised a EncryptedDocumentException error"); } catch (EncryptedDocumentException e) {} } + + @Test + public void bug54764() throws Exception { + OPCPackage pkg = XSSFTestDataSamples.openSamplePackage("54764.xlsx"); + + // Check the core properties - will be found but empty, due + // to the expansion being too much to be considered valid + POIXMLProperties props = new POIXMLProperties(pkg); + assertEquals(null, props.getCoreProperties().getTitle()); + assertEquals(null, props.getCoreProperties().getSubject()); + assertEquals(null, props.getCoreProperties().getDescription()); + + // Now check the spreadsheet itself + try { + new XSSFWorkbook(pkg); + fail("Should fail as too much expansion occurs"); + } catch(POIXMLException e) { + // Expected + } + + // Try with one with the entities in the Content Types + try { + XSSFTestDataSamples.openSamplePackage("54764-2.xlsx"); + fail("Should fail as too much expansion occurs"); + } catch(Exception e) { + // Expected + } + + // Check we can still parse valid files after all that + Workbook wb = XSSFTestDataSamples.openSampleWorkbook("sample.xlsx"); + assertEquals(3, wb.getNumberOfSheets()); + } + } diff --git a/test-data/openxml4j/CorePropertiesHasEntities.ooxml b/test-data/openxml4j/CorePropertiesHasEntities.ooxml new file mode 100644 index 000000000..bdd884b0f Binary files /dev/null and b/test-data/openxml4j/CorePropertiesHasEntities.ooxml differ diff --git a/test-data/openxml4j/PackageRelsHasEntities.ooxml b/test-data/openxml4j/PackageRelsHasEntities.ooxml new file mode 100644 index 000000000..505fdce52 Binary files /dev/null and b/test-data/openxml4j/PackageRelsHasEntities.ooxml differ diff --git a/test-data/spreadsheet/54764-2.xlsx b/test-data/spreadsheet/54764-2.xlsx new file mode 100644 index 000000000..0d942ca8d Binary files /dev/null and b/test-data/spreadsheet/54764-2.xlsx differ diff --git a/test-data/spreadsheet/54764.xlsx b/test-data/spreadsheet/54764.xlsx new file mode 100644 index 000000000..938245b61 Binary files /dev/null and b/test-data/spreadsheet/54764.xlsx differ