Sonar Fixes + Refactor scattered XML initializations to XMLHelper

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1870769 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2019-12-03 21:56:47 +00:00
parent dd3279df30
commit 08159e66a7
34 changed files with 600 additions and 763 deletions

View File

@ -30,7 +30,7 @@ import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
import org.apache.poi.xssf.model.SharedStrings;
@ -188,7 +188,7 @@ public class XLSX2CSV {
DataFormatter formatter = new DataFormatter();
InputSource sheetSource = new InputSource(sheetInputStream);
try {
XMLReader sheetParser = SAXHelper.newXMLReader();
XMLReader sheetParser = XMLHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler(
styles, null, strings, sheetHandler, formatter, false);
sheetParser.setContentHandler(handler);

View File

@ -23,13 +23,13 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
@ -78,7 +78,7 @@ public class FromHowTo {
}
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException {
XMLReader parser = SAXHelper.newXMLReader();
XMLReader parser = XMLHelper.newXMLReader();
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;

View File

@ -35,7 +35,7 @@ import javax.xml.transform.stream.StreamSource;
import org.apache.poi.sl.draw.binding.CTCustomGeometry2D;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StaxHelper;
import org.apache.poi.util.XMLHelper;
/**
*
@ -50,7 +50,7 @@ public class PresetGeometries extends LinkedHashMap<String, CustomGeometry> {
@SuppressWarnings("unused")
public void init(InputStream is) throws XMLStreamException, JAXBException {
XMLInputFactory staxFactory = StaxHelper.newXMLInputFactory();
XMLInputFactory staxFactory = XMLHelper.newXMLInputFactory();
XMLStreamReader streamReader = staxFactory.createXMLStreamReader(new StreamSource(is));
try {
// ignore StartElement:

View File

@ -17,8 +17,6 @@
package org.apache.poi.util;
import java.util.function.Consumer;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
@ -26,50 +24,33 @@ import javax.xml.stream.XMLOutputFactory;
/**
* Provides handy methods for working with StAX parsers and readers
*
* @deprecated use {@link XMLHelper}
*/
@Deprecated
@Removal(version = "5.0.0")
public final class StaxHelper {
private static final POILogger logger = POILogFactory.getLogger(StaxHelper.class);
private StaxHelper() {
}
/**
* Creates a new StAX XMLInputFactory, with sensible defaults
*/
@SuppressWarnings({"squid:S2755"})
public static XMLInputFactory newXMLInputFactory() {
XMLInputFactory factory = XMLInputFactory.newInstance();
trySet(XMLInputFactory.IS_NAMESPACE_AWARE, (n) -> factory.setProperty(n, true));
trySet(XMLInputFactory.IS_VALIDATING, (n) -> factory.setProperty(n, false));
trySet(XMLInputFactory.SUPPORT_DTD, (n) -> factory.setProperty(n, false));
trySet(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, (n) -> factory.setProperty(n, false));
return factory;
return XMLHelper.newXMLInputFactory();
}
/**
* Creates a new StAX XMLOutputFactory, with sensible defaults
*/
public static XMLOutputFactory newXMLOutputFactory() {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
trySet(XMLOutputFactory.IS_REPAIRING_NAMESPACES, (n) -> factory.setProperty(n, true));
return factory;
return XMLHelper.newXMLOutputFactory();
}
/**
* Creates a new StAX XMLEventFactory, with sensible defaults
*/
public static XMLEventFactory newXMLEventFactory() {
// this method seems safer on Android than getFactory()
return XMLEventFactory.newInstance();
}
private static void trySet(String name, Consumer<String> securityFeature) {
try {
securityFeature.accept(name);
} catch (Exception e) {
logger.log(POILogger.WARN, "StAX Property unsupported", name, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set StAX property because outdated StAX parser in classpath", name, ame);
}
return XMLHelper.newXMLEventFactory();
}
}

View File

@ -17,19 +17,71 @@
package org.apache.poi.util;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.validation.SchemaFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
/**
* Helper methods for working with javax.xml classes.
*/
@Internal
public final class XMLHelper {
static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
static final String FEATURE_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities";
static final String FEATURE_EXTERNAL_ENTITIES = "http://xml.org/sax/features/external-general-entities";
static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
static final String PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
static final String METHOD_ENTITY_EXPANSION_XERCES = "setEntityExpansionLimit";
static final String[] SECURITY_MANAGERS = {
//"com.sun.org.apache.xerces.internal.util.SecurityManager",
"org.apache.xerces.util.SecurityManager"
};
private static POILogger logger = POILogFactory.getLogger(XMLHelper.class);
private static long lastLog;
// DocumentBuilderFactory.newDocumentBuilder is thread-safe
// see https://stackoverflow.com/questions/12455602/is-documentbuilder-thread-safe
private static final DocumentBuilderFactory documentBuilderFactory = getDocumentBuilderFactory();
private static final SAXParserFactory saxFactory = getSaxParserFactory();
@FunctionalInterface
private interface SecurityFeature {
void accept(String name) throws ParserConfigurationException;
void accept(String name, boolean value) throws ParserConfigurationException, SAXException, TransformerException;
}
@FunctionalInterface
private interface SecurityProperty {
void accept(String name, Object value) throws SAXException;
}
private XMLHelper() {
}
/**
@ -40,26 +92,225 @@ public final class XMLHelper {
@SuppressWarnings({"squid:S2755"})
public static DocumentBuilderFactory getDocumentBuilderFactory() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
// this doesn't appear to work, and we still need to limit
// entity expansions to 1 in trySetXercesSecurityManager
factory.setExpandEntityReferences(false);
trySet(XMLConstants.FEATURE_SECURE_PROCESSING, (n) -> factory.setFeature(n, true));
trySet(XMLConstants.ACCESS_EXTERNAL_SCHEMA, (n) -> factory.setAttribute(n, ""));
trySet(XMLConstants.ACCESS_EXTERNAL_DTD, (n) -> factory.setAttribute(n, ""));
trySet("http://xml.org/sax/features/external-general-entities", (n) -> factory.setFeature(n, false));
trySet("http://xml.org/sax/features/external-parameter-entities", (n) -> factory.setFeature(n, false));
trySet("http://apache.org/xml/features/nonvalidating/load-external-dtd", (n) -> factory.setFeature(n, false));
trySet("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", (n) -> factory.setFeature(n, false));
trySet("http://apache.org/xml/features/disallow-doctype-decl", (n) -> factory.setFeature(n, true));
trySet("XIncludeAware", (n) -> factory.setXIncludeAware(false));
factory.setValidating(false);
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
trySet(factory::setAttribute, XMLConstants.ACCESS_EXTERNAL_DTD, "");
trySet(factory::setFeature, FEATURE_EXTERNAL_ENTITIES, false);
trySet(factory::setFeature, FEATURE_PARAMETER_ENTITIES, false);
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
trySet(factory::setFeature, FEATURE_DISALLOW_DOCTYPE_DECL, true);
trySet((n, b) -> factory.setXIncludeAware(b), "XIncludeAware", false);
Object manager = getXercesSecurityManager();
if (manager == null || !trySet(factory::setAttribute, PROPERTY_SECURITY_MANAGER, manager)) {
// separate old version of Xerces not found => use the builtin way of setting the property
// Note: when entity_expansion_limit==0, there is no limit!
trySet(factory::setAttribute, PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
}
return factory;
}
private static void trySet(String name, SecurityFeature feature) {
/**
* Creates a new document builder, with sensible defaults
*
* @throws IllegalStateException If creating the DocumentBuilder fails, e.g.
* due to {@link ParserConfigurationException}.
*/
public static DocumentBuilder newDocumentBuilder() {
try {
feature.accept(name);
} catch (Exception e) {
logger.log(POILogger.WARN, "SAX Feature unsupported", name, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", name, ame);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(XMLHelper::ignoreEntity);
documentBuilder.setErrorHandler(new DocHelperErrorHandler());
return documentBuilder;
} catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e);
}
}
public static SAXParserFactory getSaxParserFactory() {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(factory::setFeature, FEATURE_LOAD_DTD_GRAMMAR, false);
trySet(factory::setFeature, FEATURE_LOAD_EXTERNAL_DTD, false);
return factory;
} catch (RuntimeException | Error re) { // NOSONAR
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
logThrowable(re, "Failed to create SAXParserFactory", "-");
throw re;
} catch (Exception e) {
logThrowable(e, "Failed to create SAXParserFactory", "-");
throw new RuntimeException("Failed to create SAXParserFactory", e);
}
}
/**
* Creates a new SAX XMLReader, with sensible defaults
*/
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
xmlReader.setEntityResolver(XMLHelper::ignoreEntity);
trySet(xmlReader::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
Object manager = getXercesSecurityManager();
if (manager == null || !trySet(xmlReader::setProperty, PROPERTY_SECURITY_MANAGER, manager)) {
// separate old version of Xerces not found => use the builtin way of setting the property
trySet(xmlReader::setProperty, PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
}
return xmlReader;
}
/**
* Creates a new StAX XMLInputFactory, with sensible defaults
*/
@SuppressWarnings({"squid:S2755"})
public static XMLInputFactory newXMLInputFactory() {
XMLInputFactory factory = XMLInputFactory.newInstance();
trySet(factory::setProperty, XMLInputFactory.IS_NAMESPACE_AWARE, true);
trySet(factory::setProperty, XMLInputFactory.IS_VALIDATING, false);
trySet(factory::setProperty, XMLInputFactory.SUPPORT_DTD, false);
trySet(factory::setProperty, XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
return factory;
}
/**
* Creates a new StAX XMLOutputFactory, with sensible defaults
*/
public static XMLOutputFactory newXMLOutputFactory() {
XMLOutputFactory factory = XMLOutputFactory.newInstance();
trySet(factory::setProperty, XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
return factory;
}
/**
* Creates a new StAX XMLEventFactory, with sensible defaults
*/
public static XMLEventFactory newXMLEventFactory() {
// this method seems safer on Android than getFactory()
return XMLEventFactory.newInstance();
}
public static TransformerFactory getTransformerFactory() {
TransformerFactory factory = TransformerFactory.newInstance();
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
return factory;
}
public static Transformer newTransformer() throws TransformerConfigurationException {
Transformer serializer = getTransformerFactory().newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
serializer.setOutputProperty(OutputKeys.INDENT, "no");
serializer.setOutputProperty(OutputKeys.METHOD, "xml");
return serializer;
}
public static SchemaFactory getSchemaFactory() {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
trySet(factory::setFeature, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_DTD, "");
trySet(factory::setProperty, XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
return factory;
}
private static Object getXercesSecurityManager() {
// Try built-in JVM one first, standalone if not
for (String securityManagerClassName : SECURITY_MANAGERS) {
try {
Object mgr = Class.forName(securityManagerClassName).newInstance();
Method setLimit = mgr.getClass().getMethod(METHOD_ENTITY_EXPANSION_XERCES, Integer.TYPE);
setLimit.invoke(mgr, 1);
// Stop once one can be setup without error
return mgr;
} catch (ClassNotFoundException ignored) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
logThrowable(e, "SAX Feature unsupported", securityManagerClassName);
}
}
return null;
}
@SuppressWarnings("UnusedReturnValue")
private static boolean trySet(SecurityFeature feature, String name, boolean value) {
try {
feature.accept(name, value);
return true;
} catch (Exception e) {
logThrowable(e, "SAX Feature unsupported", name);
} catch (AbstractMethodError ame) {
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
private static boolean trySet(SecurityProperty property, String name, Object value) {
try {
property.accept(name, value);
return true;
} catch (Exception e) {
logThrowable(e, "SAX Feature unsupported", name);
} catch (AbstractMethodError ame) {
logThrowable(ame, "Cannot set SAX feature because outdated XML parser in classpath", name);
}
return false;
}
private static void logThrowable(Throwable t, String message, String name) {
if (System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, message + " [log suppressed for 5 minutes]", name, t);
lastLog = System.currentTimeMillis();
}
}
private static class DocHelperErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) {
printError(POILogger.WARN, exception);
}
public void error(SAXParseException exception) {
printError(POILogger.ERROR, exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
printError(POILogger.FATAL, exception);
throw exception;
}
/**
* Prints the error message.
*/
private void printError(int type, SAXParseException ex) {
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf('/');
if (index != -1) {
systemId = systemId.substring(index + 1);
}
}
String message = (systemId == null ? "" : systemId) +
':' + ex.getLineNumber() +
':' + ex.getColumnNumber() +
':' + ex.getMessage();
logger.log(type, message, ex);
}
}
private static InputSource ignoreEntity(String publicId, String systemId) {
return new InputSource(new StringReader(""));
}
}

View File

@ -16,24 +16,33 @@
==================================================================== */
package org.apache.poi.ooxml.dev;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.TransformerHelper;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.util.IOUtils;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.internal.ZipHelper;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
/**
* Reads a zipped OOXML file and produces a copy with the included
* pretty-printed XML files.
@ -42,6 +51,8 @@ import java.util.zip.ZipOutputStream;
* use different formatting of the XML.
*/
public class OOXMLPrettyPrint {
private static final String XML_INDENT_AMOUNT = "{http://xml.apache.org/xslt}indent-amount";
private final DocumentBuilder documentBuilder;
public OOXMLPrettyPrint() {
@ -109,13 +120,11 @@ public class OOXMLPrettyPrint {
}
private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException {
TransformerFactory transformerFactory = TransformerHelper.getFactory();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
Transformer transformer = XMLHelper.newTransformer();
if (indent > 0) {
// set properties to indent the resulting XML nicely
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent));
transformer.setOutputProperty(XML_INDENT_AMOUNT, Integer.toString(indent));
}
Result result = new StreamResult(outputStream);
Source source = new DOMSource(document);

View File

@ -19,66 +19,24 @@ package org.apache.poi.ooxml.util;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.events.Namespace;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.w3c.dom.*;
import org.xml.sax.ErrorHandler;
import org.apache.poi.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public final class DocumentHelper {
private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class);
private static long lastLog;
// must only be used to create empty documents, do not use it for parsing!
private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
private DocumentHelper() {}
private static class DocHelperErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) {
printError(POILogger.WARN, exception);
}
public void error(SAXParseException exception) {
printError(POILogger.ERROR, exception);
}
public void fatalError(SAXParseException exception) throws SAXException {
printError(POILogger.FATAL, exception);
throw exception;
}
/** Prints the error message. */
private void printError(int type, SAXParseException ex) {
StringBuilder sb = new StringBuilder();
String systemId = ex.getSystemId();
if (systemId != null) {
int index = systemId.lastIndexOf('/');
if (index != -1)
systemId = systemId.substring(index + 1);
sb.append(systemId);
}
sb.append(':');
sb.append(ex.getLineNumber());
sb.append(':');
sb.append(ex.getColumnNumber());
sb.append(": ");
sb.append(ex.getMessage());
logger.log(type, sb.toString(), ex);
}
}
/**
* Creates a new document builder, with sensible defaults
*
@ -86,80 +44,14 @@ public final class DocumentHelper {
* due to {@link ParserConfigurationException}.
*/
public static DocumentBuilder newDocumentBuilder() {
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
documentBuilder.setErrorHandler(new DocHelperErrorHandler());
return documentBuilder;
} catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e);
}
}
static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
static {
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
//this doesn't appear to work, and we still need to limit
//entity expansions to 1 in trySetXercesSecurityManager
documentBuilderFactory.setExpandEntityReferences(false);
trySetFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL, true);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR, false);
trySetFeature(documentBuilderFactory, POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD, false);
trySetXercesSecurityManager(documentBuilderFactory);
}
private static void trySetFeature(@SuppressWarnings("SameParameterValue") DocumentBuilderFactory dbf, String feature, boolean enabled) {
try {
dbf.setFeature(feature, enabled);
} catch (Exception e) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set DocumentBuilderFactory feature because outdated XML parser in classpath", feature, ame);
}
}
private static void trySetXercesSecurityManager(@SuppressWarnings("SameParameterValue") DocumentBuilderFactory dbf) {
// 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, 1);
dbf.setAttribute(POIXMLConstants.PROPERTY_SECURITY_MANAGER, mgr);
// Stop once one can be setup without error
return;
} catch (ClassNotFoundException e) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
}
// separate old version of Xerces not found => use the builtin way of setting the property
// Note: when entity_expansion_limit==0, there is no limit!
try {
dbf.setAttribute(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
} catch (Throwable e) {
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "DocumentBuilderFactory Entity Expansion Limit could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
return XMLHelper.newDocumentBuilder();
}
/**
* Parses the given stream via the default (sensible)
* DocumentBuilder
* @param inp Stream to read the XML data from
* @return the parsed Document
* @return the parsed Document
*/
public static Document readDocument(InputStream inp) throws IOException, SAXException {
return newDocumentBuilder().parse(inp);
@ -175,9 +67,6 @@ public final class DocumentHelper {
return newDocumentBuilder().parse(inp);
}
// must only be used to create empty documents, do not use it for parsing!
private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
/**
* Creates a new DOM Document
*/

View File

@ -1,26 +0,0 @@
/* ====================================================================
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.ooxml.util;
public class POIXMLConstants {
public static final String FEATURE_LOAD_DTD_GRAMMAR = "http://apache.org/xml/features/nonvalidating/load-dtd-grammar";
public static final String FEATURE_LOAD_EXTERNAL_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
public static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
public static final String PROPERTY_ENTITY_EXPANSION_LIMIT = "http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit";
public static final String PROPERTY_SECURITY_MANAGER = "http://apache.org/xml/properties/security-manager";
}

View File

@ -17,120 +17,25 @@
package org.apache.poi.ooxml.util;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.apache.poi.util.Removal;
import org.apache.poi.util.XMLHelper;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
* Provides handy methods for working with SAX parsers and readers
* @deprecated use {@link XMLHelper}
*/
@Deprecated
@Removal(version = "5.0.0")
public final class SAXHelper {
private static final POILogger logger = POILogFactory.getLogger(SAXHelper.class);
private static long lastLog;
private SAXHelper() {}
/**
* Creates a new SAX XMLReader, with sensible defaults
*/
public static XMLReader newXMLReader() throws SAXException, ParserConfigurationException {
XMLReader xmlReader = saxFactory.newSAXParser().getXMLReader();
xmlReader.setEntityResolver(IGNORING_ENTITY_RESOLVER);
trySetSAXFeature(xmlReader, XMLConstants.FEATURE_SECURE_PROCESSING);
trySetXercesSecurityManager(xmlReader);
return xmlReader;
}
static final EntityResolver IGNORING_ENTITY_RESOLVER = (publicId, systemId) -> new InputSource(new StringReader(""));
private static final SAXParserFactory saxFactory;
static {
try {
saxFactory = SAXParserFactory.newInstance();
saxFactory.setValidating(false);
saxFactory.setNamespaceAware(true);
trySetSAXFeature(saxFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
trySetSAXFeature(saxFactory, POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR, false);
trySetSAXFeature(saxFactory, POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD, false);
} catch (RuntimeException | Error re) { // NOSONAR
// this also catches NoClassDefFoundError, which may be due to a local class path issue
// This may occur if the code is run inside a web container
// or a restricted JVM
// See bug 61170: https://bz.apache.org/bugzilla/show_bug.cgi?id=61170
logger.log(POILogger.WARN, "Failed to create SAXParserFactory", re);
throw re;
} catch (Exception e) {
logger.log(POILogger.WARN, "Failed to create SAXParserFactory", e);
throw new RuntimeException("Failed to create SAXParserFactory", e);
}
}
private static void trySetSAXFeature(@SuppressWarnings("SameParameterValue") SAXParserFactory spf,
String feature, boolean flag) {
try {
spf.setFeature(feature, flag);
} catch (Exception e) {
logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
}
}
private static void trySetSAXFeature(XMLReader xmlReader, @SuppressWarnings("SameParameterValue") String feature) {
try {
xmlReader.setFeature(feature, true);
} catch (Exception e) {
logger.log(POILogger.WARN, "SAX Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
}
}
private static void trySetXercesSecurityManager(XMLReader 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, 1);
xmlReader.setProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER, mgr);
// Stop once one can be setup without error
return;
} catch (ClassNotFoundException e) {
// continue without log, this is expected in some setups
} catch (Throwable e) { // NOSONAR - also catch things like NoClassDefError here
// throttle the log somewhat as it can spam the log otherwise
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
}
// separate old version of Xerces not found => use the builtin way of setting the property
try {
xmlReader.setProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT, 1);
} catch (SAXException e) { // NOSONAR - also catch things like NoClassDefError here
// throttle the log somewhat as it can spam the log otherwise
if(System.currentTimeMillis() > lastLog + TimeUnit.MINUTES.toMillis(5)) {
logger.log(POILogger.WARN, "SAX Security Manager could not be setup [log suppressed for 5 minutes]", e);
lastLog = System.currentTimeMillis();
}
}
return XMLHelper.newXMLReader();
}
}

View File

@ -17,33 +17,20 @@
package org.apache.poi.ooxml.util;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import javax.xml.XMLConstants;
import javax.xml.transform.TransformerFactory;
public final class TransformerHelper {
private static POILogger logger = POILogFactory.getLogger(TransformerHelper.class);
import org.apache.poi.util.Removal;
import org.apache.poi.util.XMLHelper;
/**
* @deprecated use {@link XMLHelper}
*/
@Removal(version = "5.0.0")
@Deprecated
public final class TransformerHelper {
private TransformerHelper() {}
static final TransformerFactory transformerFactory = TransformerFactory.newInstance();
static {
trySetFeature(transformerFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true);
}
public static TransformerFactory getFactory() {
return transformerFactory;
}
private static void trySetFeature(TransformerFactory tf, String feature, boolean enabled) {
try {
tf.setFeature(feature, enabled);
} catch (Exception e) {
logger.log(POILogger.WARN, "TransformerFactory Feature unsupported", feature, e);
} catch (AbstractMethodError ame) {
logger.log(POILogger.WARN, "Cannot set TransformerFactory feature because outdated XML parser in classpath", feature, ame);
}
return XMLHelper.getTransformerFactory();
}
}

View File

@ -30,7 +30,8 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.ooxml.util.TransformerHelper;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.w3c.dom.Document;
public final class StreamHelper {
@ -39,10 +40,6 @@ public final class StreamHelper {
// Do nothing
}
private static synchronized Transformer getIdentityTransformer() throws TransformerException {
return TransformerHelper.getFactory().newTransformer();
}
/**
* Save the document object in the specified output stream.
*
@ -56,7 +53,7 @@ public final class StreamHelper {
public static boolean saveXmlInStream(Document xmlContent,
OutputStream outStream) {
try {
Transformer trans = getIdentityTransformer();
Transformer trans = XMLHelper.newTransformer();
Source xmlSource = new DOMSource(xmlContent);
// prevent close of stream by transformer:
Result outputTarget = new StreamResult(new FilterOutputStream(
@ -97,14 +94,10 @@ public final class StreamHelper {
*/
public static boolean copyStream(InputStream inStream, OutputStream outStream) {
try {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) >= 0) {
outStream.write(buffer, 0, bytesRead);
}
IOUtils.copy(inStream, outStream);
return true;
} catch (Exception e) {
return false;
}
return true;
}
}

View File

@ -96,7 +96,7 @@ public class TSPTimeStampService implements TimeStampService {
}
}
@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked","squid:S2647"})
public byte[] timeStamp(byte[] data, RevocationData revocationData)
throws Exception {
// digest the message

View File

@ -18,18 +18,19 @@ package org.apache.poi.xssf.eventusermodel;
import static org.apache.poi.xssf.usermodel.XSSFRelation.NS_SPREADSHEETML;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.util.Removal;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.SharedStrings;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
@ -173,7 +174,7 @@ public class ReadOnlySharedStringsTable extends DefaultHandler implements Shared
pis.unread(emptyTest);
InputSource sheetSource = new InputSource(pis);
try {
XMLReader sheetParser = SAXHelper.newXMLReader();
XMLReader sheetParser = XMLHelper.newXMLReader();
sheetParser.setContentHandler(this);
sheetParser.parse(sheetSource);
} catch(ParserConfigurationException e) {

View File

@ -16,7 +16,6 @@
==================================================================== */
package org.apache.poi.xssf.eventusermodel;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -30,6 +29,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@ -42,7 +43,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
@ -253,7 +254,7 @@ public class XSSFReader {
XMLSheetRefReader xmlSheetRefReader = new XMLSheetRefReader();
XMLReader xmlReader;
try {
xmlReader = SAXHelper.newXMLReader();
xmlReader = XMLHelper.newXMLReader();
} catch (ParserConfigurationException | SAXException e) {
throw new POIXMLException(e);
}

View File

@ -16,7 +16,6 @@
==================================================================== */
package org.apache.poi.xssf.extractor;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
@ -24,6 +23,8 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.POIXMLProperties.CoreProperties;
import org.apache.poi.ooxml.POIXMLProperties.CustomProperties;
@ -34,12 +35,15 @@ import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.model.*;
import org.apache.poi.xssf.model.Comments;
import org.apache.poi.xssf.model.SharedStrings;
import org.apache.poi.xssf.model.Styles;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSimpleShape;
@ -244,7 +248,7 @@ public class XSSFEventBasedExcelExtractor extends POIXMLTextExtractor
InputSource sheetSource = new InputSource(sheetInputStream);
try {
XMLReader sheetParser = SAXHelper.newXMLReader();
XMLReader sheetParser = XMLHelper.newXMLReader();
ContentHandler handler = new XSSFSheetXMLHandler(
styles, comments, strings, sheetContentsExtractor, formatter, formulasNotResults);
sheetParser.setContentHandler(handler);

View File

@ -28,7 +28,6 @@ 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;
@ -40,12 +39,12 @@ import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.TransformerHelper;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFRow;
@ -225,7 +224,7 @@ public class XSSFExportToXml implements Comparator<String>{
//Output the XML
//set up a transformer
Transformer trans = TransformerHelper.getFactory().newTransformer();
Transformer trans = XMLHelper.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
trans.setOutputProperty(OutputKeys.ENCODING, encoding);
@ -250,10 +249,7 @@ public class XSSFExportToXml implements Comparator<String>{
@SuppressWarnings({"squid:S2755"})
private boolean isValid(Document xml) throws SAXException{
try {
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
trySet(XMLConstants.FEATURE_SECURE_PROCESSING, (n) -> factory.setFeature(n, true));
trySet(XMLConstants.ACCESS_EXTERNAL_DTD, (n) -> factory.setProperty(n,""));
trySet(XMLConstants.ACCESS_EXTERNAL_SCHEMA, (n) -> factory.setProperty(n,""));
SchemaFactory factory = XMLHelper.getSchemaFactory();
Source source = new DOMSource(map.getSchema());
Schema schema = factory.newSchema(source);
@ -407,7 +403,7 @@ public class XSSFExportToXml implements Comparator<String>{
String[] rightTokens = rightXpath.split("/");
String samePath = "";
int minLength = leftTokens.length< rightTokens.length? leftTokens.length : rightTokens.length;
int minLength = Math.min(leftTokens.length, rightTokens.length);
Node localComplexTypeRootNode = xmlSchema;

View File

@ -25,22 +25,24 @@ import java.nio.charset.StandardCharsets;
import java.util.EnumMap;
import java.util.Map;
import org.apache.poi.ooxml.util.TransformerHelper;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ss.usermodel.DifferentialStyleProvider;
import org.apache.poi.ss.usermodel.TableStyle;
import org.apache.poi.ss.usermodel.TableStyleType;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.StylesTable;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Table style names defined in the OOXML spec.
* The actual styling is defined in presetTableStyles.xml
@ -440,9 +442,8 @@ public enum XSSFBuiltinTableStyle {
}
private static String writeToString(Node node) throws IOException, TransformerException {
TransformerFactory tf = TransformerHelper.getFactory();
try (StringWriter sw = new StringWriter()){
Transformer transformer = tf.newTransformer();
Transformer transformer = XMLHelper.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString();

View File

@ -1,73 +0,0 @@
/* ====================================================================
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.ooxml.util;
import org.junit.Test;
import org.xml.sax.InputSource;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
public class TestDocumentHelper {
@Test
public void testDocumentBuilder() throws Exception {
DocumentBuilder documentBuilder = DocumentHelper.newDocumentBuilder();
assertNotSame(documentBuilder, DocumentHelper.newDocumentBuilder());
assertTrue(documentBuilder.isNamespaceAware());
assertFalse(documentBuilder.isValidating());
documentBuilder.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyDocumentBuilders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<DocumentBuilder>> futures = new ArrayList<>();
for(int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(DocumentHelper::newDocumentBuilder));
}
HashSet<DocumentBuilder> dbs = new HashSet<>();
for(CompletableFuture<DocumentBuilder> future : futures) {
DocumentBuilder documentBuilder = future.get(10, TimeUnit.SECONDS);
assertTrue(documentBuilder.isNamespaceAware());
dbs.add(documentBuilder);
}
assertEquals(limit, dbs.size());
}
@Test
public void testDocumentBuilderFactory() throws Exception {
try {
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertTrue(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL));
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(DocumentHelper.documentBuilderFactory.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
} catch(AbstractMethodError e) {
// ignore exceptions from old parsers that don't support this API (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
}
}

View File

@ -1,85 +0,0 @@
/* ====================================================================
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.ooxml.util;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.XMLReader;
public class TestSAXHelper {
@Test
public void testXMLReader() throws Exception {
XMLReader reader = SAXHelper.newXMLReader();
assertNotSame(reader, SAXHelper.newXMLReader());
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(reader.getFeature(POIXMLConstants.FEATURE_LOAD_EXTERNAL_DTD));
assertEquals(SAXHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertEquals("1", reader.getProperty(POIXMLConstants.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertNotNull(reader.getProperty(POIXMLConstants.PROPERTY_SECURITY_MANAGER));
} catch(SAXNotRecognizedException e) {
// ignore exceptions from old parsers that don't support these features
// (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyXMLReaders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<XMLReader>> futures = new ArrayList<>();
for(int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(() -> {
try {
return SAXHelper.newXMLReader();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
HashSet<XMLReader> readers = new HashSet<>();
for(CompletableFuture<XMLReader> future : futures) {
XMLReader reader = future.get(10, TimeUnit.SECONDS);
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
} catch (SAXNotRecognizedException e) {
// can happen for older XML Parsers, e.g. we have a CI Job which runs with Xerces XML Parser
assertTrue("Had Exception about not-recognized SAX feature: " + e + " which is only expected" +
" for Xerces XML Parser, but had parser: " + reader,
reader.getClass().getName().contains("org.apache.xerces"));
}
readers.add(reader);
}
assertEquals(limit, readers.size());
}
}

View File

@ -17,7 +17,15 @@
package org.apache.poi.openxml4j.opc;
import org.apache.poi.ooxml.util.POIXMLConstants;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.poi.openxml4j.OpenXML4JTestDataSamples;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.internal.ContentType;
@ -25,19 +33,13 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Tests for content type (ContentType class).
*/
public final class TestContentType {
private static final String FEATURE_DISALLOW_DOCTYPE_DECL = "http://apache.org/xml/features/disallow-doctype-decl";
@Rule
public ExpectedException exception = ExpectedException.none();
@ -242,7 +244,7 @@ public final class TestContentType {
public static boolean isOldXercesActive() {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
dbf.setFeature(POIXMLConstants.FEATURE_DISALLOW_DOCTYPE_DECL, true);
dbf.setFeature(FEATURE_DISALLOW_DOCTYPE_DECL, true);
return false;
} catch (Exception|AbstractMethodError ignored) {}
return true;

View File

@ -32,15 +32,13 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.xssf.model.MapInfo;
@ -48,8 +46,6 @@ import org.apache.poi.xssf.usermodel.XSSFMap;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Ignore;
import org.junit.Test;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@ -401,7 +397,7 @@ public final class TestXSSFExportToXML {
String xmlData = os.toString("UTF-8");
assertNotNull(xmlData);
assertTrue(!xmlData.isEmpty());
assertFalse(xmlData.isEmpty());
String a = xmlData.split("<A>")[1].split("</A>")[0].trim();
String a_b = a.split("<B>")[1].split("</B>")[0].trim();
@ -505,23 +501,11 @@ public final class TestXSSFExportToXML {
}
}
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());
private void parseXML(String xmlData) throws IOException, SAXException {
DocumentBuilder docBuilder = XMLHelper.newDocumentBuilder();
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")) {

View File

@ -59,7 +59,6 @@ import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.ooxml.POIXMLProperties;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.InvalidOperationException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
@ -84,32 +83,7 @@ import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.functions.Function;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.FormulaError;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellRangeAddress;
@ -118,6 +92,7 @@ import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.util.LocaleUtil;
import org.apache.poi.util.NullOutputStream;
import org.apache.poi.util.TempFile;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.SXSSFITestDataProvider;
import org.apache.poi.xssf.XLSBUnsupportedException;
import org.apache.poi.xssf.XSSFITestDataProvider;
@ -1946,7 +1921,7 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
File testFile = XSSFTestDataSamples.getSampleFile("54764.xlsx");
ZipFile zip = new ZipFile(testFile);
ZipArchiveEntry ze = zip.getEntry("xl/sharedStrings.xml");
XMLReader reader = SAXHelper.newXMLReader();
XMLReader reader = XMLHelper.newXMLReader();
try {
reader.parse(new InputSource(zip.getInputStream(ze)));
fail("should have thrown SAXParseException");

View File

@ -20,9 +20,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
@ -92,12 +90,8 @@ public class ExcelToFoConverter extends AbstractExcelConverter
DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "xml" );
Transformer serializer = XMLHelper.newTransformer();
serializer.transform( domSource, streamResult );
}
@ -113,8 +107,7 @@ public class ExcelToFoConverter extends AbstractExcelConverter
final HSSFWorkbook workbook = AbstractExcelUtils.loadXls( xlsFile );
try {
ExcelToFoConverter excelToHtmlConverter = new ExcelToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder()
.newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook );
return excelToHtmlConverter.getDocument();
} finally {

View File

@ -27,7 +27,6 @@ import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
@ -85,11 +84,8 @@ public class ExcelToHtmlConverter extends AbstractExcelConverter {
DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
Transformer serializer = XMLHelper.newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "html" );
serializer.transform( domSource, streamResult );
}
@ -133,8 +129,7 @@ public class ExcelToHtmlConverter extends AbstractExcelConverter {
*/
public static Document process( HSSFWorkbook workbook ) throws IOException, ParserConfigurationException {
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder()
.newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook );
return excelToHtmlConverter.getDocument();
}

View File

@ -24,9 +24,7 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
@ -86,17 +84,14 @@ public class WordToFoConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File( args[1] ) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
Transformer serializer = XMLHelper.newTransformer();
serializer.transform( domSource, streamResult );
}
static Document process( File docFile ) throws Exception
{
final DocumentBuilder docBuild = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder();
final DocumentBuilder docBuild = XMLHelper.newDocumentBuilder();
try (final HWPFDocumentCore hwpfDocument = WordToFoUtils.loadDoc( docFile )) {
WordToFoConverter wordToFoConverter = new WordToFoConverter(docBuild.newDocument());
wordToFoConverter.processDocument(hwpfDocument);

View File

@ -30,7 +30,6 @@ import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
@ -154,18 +153,15 @@ public class WordToHtmlConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File(args[1]) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
Transformer serializer = XMLHelper.newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "yes" );
serializer.setOutputProperty( OutputKeys.METHOD, "html" );
serializer.transform( domSource, streamResult );
}
static Document process( File docFile ) throws IOException, ParserConfigurationException
{
final DocumentBuilder docBuild = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder();
final DocumentBuilder docBuild = XMLHelper.newDocumentBuilder();
try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) {
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(docBuild.newDocument());
wordToHtmlConverter.processDocument(wordDocument);

View File

@ -76,7 +76,7 @@ public class WordToTextConverter extends AbstractWordConverter
throws Exception
{
WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
wordToTextConverter.processDocument( wordDocument );
return wordToTextConverter.getText();
}
@ -105,11 +105,8 @@ public class WordToTextConverter extends AbstractWordConverter
DOMSource domSource = new DOMSource( doc );
StreamResult streamResult = new StreamResult( new File( args[1] ) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer serializer = tf.newTransformer();
Transformer serializer = XMLHelper.newTransformer();
// TODO set encoding from a command argument
serializer.setOutputProperty( OutputKeys.ENCODING, "UTF-8" );
serializer.setOutputProperty( OutputKeys.INDENT, "no" );
serializer.setOutputProperty( OutputKeys.METHOD, "text" );
serializer.transform( domSource, streamResult );
}
@ -117,7 +114,7 @@ public class WordToTextConverter extends AbstractWordConverter
private static Document process( File docFile ) throws IOException, ParserConfigurationException {
try (final HWPFDocumentCore wordDocument = AbstractWordUtils.loadDoc( docFile )) {
WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument());
XMLHelper.newDocumentBuilder().newDocument());
wordToTextConverter.processDocument(wordDocument);
return wordToTextConverter.getDocument();
}
@ -141,8 +138,7 @@ public class WordToTextConverter extends AbstractWordConverter
public WordToTextConverter() throws ParserConfigurationException
{
this.textDocumentFacade = new TextDocumentFacade(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder()
.newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
}
/**

View File

@ -16,26 +16,26 @@
==================================================================== */
package org.apache.poi.hssf.converter;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.XMLHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FilenameFilter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertNotNull;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.util.XMLHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestExcelConverterSuite
@ -53,15 +53,7 @@ public class TestExcelConverterSuite
List<Object[]> files = new ArrayList<>();
File directory = POIDataSamples.getDocumentInstance().getFile(
"../spreadsheet" );
for ( final File child : directory.listFiles( new FilenameFilter()
{
@Override
public boolean accept( File dir, String name )
{
return name.endsWith( ".xls" ) && !failingFiles.contains( name );
}
} ) )
{
for ( final File child : directory.listFiles((dir,name) -> name.endsWith( ".xls" ) && !failingFiles.contains( name ))) {
files.add(new Object[] { child });
}
@ -84,16 +76,12 @@ public class TestExcelConverterSuite
}
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook );
StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
Transformer transformer = XMLHelper.newTransformer();
transformer.transform(
new DOMSource( excelToHtmlConverter.getDocument() ),
new StreamResult( stringWriter ) );
@ -113,7 +101,7 @@ public class TestExcelConverterSuite
}
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
excelToHtmlConverter.processWorkbook( workbook );
StringWriter stringWriter = new StringWriter();

View File

@ -18,17 +18,17 @@ package org.apache.poi.hwpf.converter;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FilenameFilter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hwpf.HWPFDocumentCore;
@ -55,15 +55,7 @@ public class TestWordToConverterSuite
List<Object[]> files = new ArrayList<>();
File directory = POIDataSamples.getDocumentInstance().getFile(
"../document" );
for ( final File child : directory.listFiles( new FilenameFilter()
{
@Override
public boolean accept( File dir, String name )
{
return name.endsWith( ".doc" ) && !failingFiles.contains( name );
}
} ) )
{
for ( final File child : directory.listFiles((dir,name) -> name.endsWith( ".doc" ) && !failingFiles.contains( name ))) {
files.add(new Object[] { child });
}
@ -83,15 +75,12 @@ public class TestWordToConverterSuite
}
WordToFoConverter wordToFoConverter = new WordToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
wordToFoConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty( OutputKeys.ENCODING, "utf-8" );
transformer.setOutputProperty( OutputKeys.INDENT, "false" );
Transformer transformer = XMLHelper.newTransformer();
transformer.transform(
new DOMSource( wordToFoConverter.getDocument() ),
new StreamResult( stringWriter ) );
@ -111,7 +100,7 @@ public class TestWordToConverterSuite
}
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
wordToHtmlConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter();
@ -140,7 +129,7 @@ public class TestWordToConverterSuite
}
WordToTextConverter wordToTextConverter = new WordToTextConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
wordToTextConverter.processDocument( wordDocument );
StringWriter stringWriter = new StringWriter();

View File

@ -22,9 +22,7 @@ import static org.apache.poi.POITestCase.assertContains;
import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
@ -45,14 +43,12 @@ public class TestWordToFoConverter
.getDocumentInstance().openResourceAsStream( sampleFileName ) );
WordToFoConverter wordToFoConverter = new WordToFoConverter(
XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument() );
XMLHelper.newDocumentBuilder().newDocument() );
wordToFoConverter.processDocument( hwpfDocument );
StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
Transformer transformer = XMLHelper.newTransformer();
transformer.transform(
new DOMSource( wordToFoConverter.getDocument() ),
new StreamResult( stringWriter ) );

View File

@ -16,22 +16,22 @@
==================================================================== */
package org.apache.poi.hwpf.converter;
import static org.apache.poi.POITestCase.assertContains;
import static org.junit.Assert.assertFalse;
import java.io.StringWriter;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.util.XMLHelper;
import org.junit.Test;
import org.w3c.dom.Document;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import static org.apache.poi.POITestCase.assertContains;
import static org.junit.Assert.assertFalse;
/**
* Test cases for {@link WordToHtmlConverter}
*/
@ -45,7 +45,7 @@ public class TestWordToHtmlConverter {
HWPFDocument hwpfDocument = new HWPFDocument(POIDataSamples
.getDocumentInstance().openResourceAsStream(sampleFileName));
Document newDocument = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument();
Document newDocument = XMLHelper.newDocumentBuilder().newDocument();
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
newDocument);
@ -58,10 +58,7 @@ public class TestWordToHtmlConverter {
StringWriter stringWriter = new StringWriter();
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
Transformer transformer = XMLHelper.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "html");
transformer.transform(
new DOMSource(wordToHtmlConverter.getDocument()),

View File

@ -899,7 +899,7 @@ public class TestBugs{
@Test
public void test59322() throws Exception {
try(HWPFDocument doc = HWPFTestDataSamples.openSampleFile("59322.doc")) {
Document document = XMLHelper.getDocumentBuilderFactory().newDocumentBuilder().newDocument();
Document document = XMLHelper.newDocumentBuilder().newDocument();
WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);
wordToHtmlConverter.processDocument(doc);
assertNotNull(document);

View File

@ -1,64 +0,0 @@
/* ====================================================================
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import org.junit.Test;
/**
* Unit test for StaxHelper
*/
public class TestStaxHelper {
/**
* test that newXMLInputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLInputFactory() throws XMLStreamException {
XMLInputFactory factory = StaxHelper.newXMLInputFactory();
assertEquals(true, factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
assertEquals(false, factory.getProperty(XMLInputFactory.IS_VALIDATING));
assertEquals(false, factory.getProperty(XMLInputFactory.SUPPORT_DTD));
assertEquals(false, factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
}
/**
* test that newXMLOutputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLOutputFactory() {
XMLOutputFactory factory = StaxHelper.newXMLOutputFactory();
assertEquals(true, factory.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES));
}
/**
* test that newXMLEventFactory returns a factory
*/
@Test
public void testNewXMLEventFactory() {
assertNotNull(StaxHelper.newXMLEventFactory());
}
}

View File

@ -0,0 +1,161 @@
/* ====================================================================
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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.XMLReader;
public class TestXMLHelper {
@Test
public void testDocumentBuilder() throws Exception {
DocumentBuilder documentBuilder = XMLHelper.newDocumentBuilder();
assertNotSame(documentBuilder, XMLHelper.newDocumentBuilder());
assertTrue(documentBuilder.isNamespaceAware());
assertFalse(documentBuilder.isValidating());
documentBuilder.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyDocumentBuilders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<DocumentBuilder>> futures = new ArrayList<>();
for (int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(XMLHelper::newDocumentBuilder));
}
HashSet<DocumentBuilder> dbs = new HashSet<>();
for (CompletableFuture<DocumentBuilder> future : futures) {
DocumentBuilder documentBuilder = future.get(10, TimeUnit.SECONDS);
assertTrue(documentBuilder.isNamespaceAware());
dbs.add(documentBuilder);
}
assertEquals(limit, dbs.size());
}
@Test
public void testDocumentBuilderFactory() throws Exception {
try {
DocumentBuilderFactory dbf = XMLHelper.getDocumentBuilderFactory();
assertTrue(dbf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertTrue(dbf.getFeature(XMLHelper.FEATURE_DISALLOW_DOCTYPE_DECL));
assertFalse(dbf.getFeature(XMLHelper.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(dbf.getFeature(XMLHelper.FEATURE_LOAD_EXTERNAL_DTD));
} catch (AbstractMethodError e) {
// ignore exceptions from old parsers that don't support this API (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
}
@Test
public void testXMLReader() throws Exception {
XMLReader reader = XMLHelper.newXMLReader();
assertNotSame(reader, XMLHelper.newXMLReader());
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
assertFalse(reader.getFeature(XMLHelper.FEATURE_LOAD_DTD_GRAMMAR));
assertFalse(reader.getFeature(XMLHelper.FEATURE_LOAD_EXTERNAL_DTD));
// assertEquals(XMLHelper.IGNORING_ENTITY_RESOLVER, reader.getEntityResolver());
assertNotNull(reader.getProperty(XMLHelper.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertEquals("1", reader.getProperty(XMLHelper.PROPERTY_ENTITY_EXPANSION_LIMIT));
assertNotNull(reader.getProperty(XMLHelper.PROPERTY_SECURITY_MANAGER));
} catch (SAXNotRecognizedException e) {
// ignore exceptions from old parsers that don't support these features
// (https://bz.apache.org/bugzilla/show_bug.cgi?id=62692)
}
reader.parse(new InputSource(new ByteArrayInputStream("<xml></xml>".getBytes(StandardCharsets.UTF_8))));
}
@Test
public void testCreatingManyXMLReaders() throws Exception {
int limit = 1000;
ArrayList<CompletableFuture<XMLReader>> futures = new ArrayList<>();
for (int i = 0; i < limit; i++) {
futures.add(CompletableFuture.supplyAsync(() -> {
try {
return XMLHelper.newXMLReader();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
HashSet<XMLReader> readers = new HashSet<>();
for (CompletableFuture<XMLReader> future : futures) {
XMLReader reader = future.get(10, TimeUnit.SECONDS);
try {
assertTrue(reader.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING));
} catch (SAXNotRecognizedException e) {
// can happen for older XML Parsers, e.g. we have a CI Job which runs with Xerces XML Parser
assertTrue("Had Exception about not-recognized SAX feature: " + e + " which is only expected" +
" for Xerces XML Parser, but had parser: " + reader,
reader.getClass().getName().contains("org.apache.xerces"));
}
readers.add(reader);
}
assertEquals(limit, readers.size());
}
/**
* test that newXMLInputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLInputFactory() {
XMLInputFactory factory = XMLHelper.newXMLInputFactory();
assertTrue((boolean)factory.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE));
assertFalse((boolean)factory.getProperty(XMLInputFactory.IS_VALIDATING));
assertFalse((boolean)factory.getProperty(XMLInputFactory.SUPPORT_DTD));
assertFalse((boolean)factory.getProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES));
}
/**
* test that newXMLOutputFactory returns a factory with sensible defaults
*/
@Test
public void testNewXMLOutputFactory() {
XMLOutputFactory factory = XMLHelper.newXMLOutputFactory();
assertTrue((boolean)factory.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES));
}
/**
* test that newXMLEventFactory returns a factory
*/
@Test
public void testNewXMLEventFactory() {
assertNotNull(XMLHelper.newXMLEventFactory());
}
}