<classpathentry kind="lib" path="lib/log4j-1.2.13.jar"/>
<classpathentry kind="lib" path="ooxml-lib/dom4j-1.6.1.jar"/>
<classpathentry kind="lib" path="ooxml-lib/stax-api-1.0.1.jar"/>
- <classpathentry kind="lib" path="ooxml-lib/xmlbeans-2.3.0.jar"/>
+ <classpathentry kind="lib" path="ooxml-lib/xmlbeans-2.6.0.jar"/>
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
<classpathentry kind="lib" path="lib/junit-4.11.jar"/>
<classpathentry kind="lib" path="ooxml-lib/ooxml-schemas-1.1.jar" sourcepath="ooxml-lib/ooxml-schemas-src-1.1.jar"/>
<!-- jars in the lib-ooxml directory, see the fetch-ooxml-jars target-->
<property name="ooxml.dom4j.jar" location="${ooxml.lib}/dom4j-1.6.1.jar"/>
<property name="ooxml.dom4j.url" value="${repository.m2}/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar"/>
- <property name="ooxml.xmlbeans.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
- <property name="ooxml.xmlbeans.url"
+ <property name="ooxml.xmlbeans23.jar" location="${ooxml.lib}/xmlbeans-2.3.0.jar"/>
+ <property name="ooxml.xmlbeans23.url"
value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.3.0/xmlbeans-2.3.0.jar"/>
+ <property name="ooxml.xmlbeans26.jar" location="${ooxml.lib}/xmlbeans-2.6.0.jar"/>
+ <property name="ooxml.xmlbeans26.url"
+ value="${repository.m2}/maven2/org/apache/xmlbeans/xmlbeans/2.6.0/xmlbeans-2.6.0.jar"/>
<property name="ooxml.jsr173.jar" location="${ooxml.lib}/stax-api-1.0.1.jar"/>
<property name="ooxml.jsr173.url" value="${repository.m2}/maven2/stax/stax-api/1.0.1/stax-api-1.0.1.jar"/>
<path id="ooxml.classpath">
<pathelement location="${ooxml.jsr173.jar}"/>
<pathelement location="${ooxml.dom4j.jar}"/>
- <pathelement location="${ooxml.xmlbeans.jar}"/>
+ <pathelement location="${ooxml.xmlbeans26.jar}"/>
<pathelement location="${ooxml.xsds.jar}"/>
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
<path id="ooxml-lite.classpath">
<pathelement location="${ooxml.jsr173.jar}"/>
<pathelement location="${ooxml.dom4j.jar}"/>
- <pathelement location="${ooxml.xmlbeans.jar}"/>
+ <pathelement location="${ooxml.xmlbeans26.jar}"/>
<pathelement location="build/ooxml-xsds-lite"/> <!-- instead of ooxml-xsds.jar use the filtered classes-->
<path refid="main.classpath"/>
<pathelement location="${main.output.dir}"/>
<or>
<and>
<available file="${ooxml.dom4j.jar}"/>
- <available file="${ooxml.xmlbeans.jar}"/>
+ <available file="${ooxml.xmlbeans23.jar}"/>
+ <available file="${ooxml.xmlbeans26.jar}"/>
<available file="${ooxml.jsr173.jar}"/>
<available file="${ooxml.xsds.jar}"/>
</and>
<param name="destfile" value="${ooxml.dom4j.jar}"/>
</antcall>
<antcall target="downloadfile">
- <param name="sourcefile" value="${ooxml.xmlbeans.url}"/>
- <param name="destfile" value="${ooxml.xmlbeans.jar}"/>
+ <param name="sourcefile" value="${ooxml.xmlbeans23.url}"/>
+ <param name="destfile" value="${ooxml.xmlbeans23.jar}"/>
</antcall>
<antcall target="downloadfile">
<param name="sourcefile" value="${ooxml.jsr173.url}"/>
<param name="destfile" value="${ooxml.jsr173.jar}"/>
</antcall>
+ <antcall target="downloadfile">
+ <param name="sourcefile" value="${ooxml.xmlbeans26.url}"/>
+ <param name="destfile" value="${ooxml.xmlbeans26.jar}"/>
+ </antcall>
</target>
<target name="check-ooxml-xsds">
<taskdef name="xmlbean"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
- classpath="${ooxml.xmlbeans.jar}:${ooxml.jsr173.jar}"/>
+ classpath="${ooxml.xmlbeans23.jar}:${ooxml.jsr173.jar}"/>
<!-- We need a fair amount of memory to compile the xml schema, -->
<!-- but limit it in case it goes wrong! -->
description="Compiles the OOXML encryption xsd files into XmlBeans">
<taskdef name="xmlbean"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
- classpath="${ooxml.xmlbeans.jar}:${ooxml.jsr173.jar}"/>
+ classpath="${ooxml.xmlbeans23.jar}:${ooxml.jsr173.jar}"/>
<!-- We need a fair amount of memory to compile the xml schema, -->
<!-- but limit it in case it goes wrong! -->
<zipfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
<include name="dom4j-*.jar"/>
<include name="stax-api-*.jar"/>
- <include name="xmlbeans-*.jar"/>
+ <include name="xmlbeans-2.6*.jar"/>
</zipfileset>
<zipfileset dir="${dist.dir}" prefix="${zipdir}">
<patternset refid="bin.dist.jars"/>
<tarfileset dir="${ooxml.lib}" prefix="${zipdir}/ooxml-lib">
<include name="dom4j-*.jar"/>
<include name="stax-api-*.jar"/>
- <include name="xmlbeans-*.jar"/>
+ <include name="xmlbeans-2.6*.jar"/>
</tarfileset>
<tarfileset dir="${build.site}" prefix="${zipdir}/docs"/>
<tarfileset dir="${dist.dir}" prefix="${zipdir}">
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
- <version>2.3.0</version>
+ <version>2.6.0</version>
</dependency>
</dependencies>
</project>
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";
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);
}
/**
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;
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();
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;
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).
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(
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;
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.
"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 */
--- /dev/null
+/* ====================================================================
+ 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);
+ }
+}
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;
/**
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;
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);
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
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;
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);
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());
+ }
}
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 {
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());
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);
}
}
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;
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());
+ }
+
}