Browse Source

REPORT-20372 CVE-2017-5644 fix

release/10.0
vito 5 years ago
parent
commit
1e95220dd8
  1. 51
      fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java
  2. 61
      fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java

51
fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java

@ -18,9 +18,11 @@
package com.fr.third.v2.org.apache.poi; package com.fr.third.v2.org.apache.poi;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
import java.io.StringReader;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -28,6 +30,7 @@ import java.util.Map;
import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamReader;
import com.fr.third.v2.org.apache.poi.util.DocumentHelper;
import com.fr.third.v2.org.apache.xmlbeans.SchemaType; import com.fr.third.v2.org.apache.xmlbeans.SchemaType;
import com.fr.third.v2.org.apache.xmlbeans.XmlBeans; import com.fr.third.v2.org.apache.xmlbeans.XmlBeans;
import com.fr.third.v2.org.apache.xmlbeans.XmlException; import com.fr.third.v2.org.apache.xmlbeans.XmlException;
@ -35,19 +38,26 @@ import com.fr.third.v2.org.apache.xmlbeans.XmlObject;
import com.fr.third.v2.org.apache.xmlbeans.XmlOptions; import com.fr.third.v2.org.apache.xmlbeans.XmlOptions;
import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLInputStream; import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLInputStream;
import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLStreamException; import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLStreamException;
import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class POIXMLTypeLoader { public class POIXMLTypeLoader {
public static final XmlOptions DEFAULT_XML_OPTIONS; public static final XmlOptions DEFAULT_XML_OPTIONS;
static { static {
DEFAULT_XML_OPTIONS = new XmlOptions(); DEFAULT_XML_OPTIONS = new XmlOptions();
DEFAULT_XML_OPTIONS.setSaveOuter(); DEFAULT_XML_OPTIONS.setSaveOuter();
DEFAULT_XML_OPTIONS.setUseDefaultNamespace(); DEFAULT_XML_OPTIONS.setUseDefaultNamespace();
DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces(); DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();
DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8"); DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8");
DEFAULT_XML_OPTIONS.setLoadEntityBytesLimit(4096); // Piccolo is disabled for POI builts, i.e. JAXP is used for parsing
// so only user code using XmlObject/XmlToken.Factory.parse
// directly can bypass the entity check, which is probably unlikely (... and not within our responsibility :))
// DEFAULT_XML_OPTIONS.setLoadEntityBytesLimit(4096);
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>();
map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a"); map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
@ -68,8 +78,7 @@ public class POIXMLTypeLoader {
} }
private static XmlOptions getXmlOptions(XmlOptions options) { private static XmlOptions getXmlOptions(XmlOptions options) {
XmlOptions opt = (options == null) ? DEFAULT_XML_OPTIONS : options; return options == null ? DEFAULT_XML_OPTIONS : options;
return opt;
} }
public static XmlObject newInstance(SchemaType type, XmlOptions options) { public static XmlObject newInstance(SchemaType type, XmlOptions options) {
@ -77,19 +86,38 @@ public class POIXMLTypeLoader {
} }
public static XmlObject parse(String xmlText, SchemaType type, XmlOptions options) throws XmlException { public static XmlObject parse(String xmlText, SchemaType type, XmlOptions options) throws XmlException {
return XmlBeans.getContextTypeLoader().parse(xmlText, type, getXmlOptions(options)); try {
return parse(new StringReader(xmlText), type, options);
} catch (IOException e) {
throw new XmlException("Unable to parse xml bean", e);
}
} }
public static XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException { public static XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException {
return XmlBeans.getContextTypeLoader().parse(file, type, getXmlOptions(options)); InputStream is = new FileInputStream(file);
try {
return parse(is, type, options);
} finally {
is.close();
}
} }
public static XmlObject parse(URL file, SchemaType type, XmlOptions options) throws XmlException, IOException { public static XmlObject parse(URL file, SchemaType type, XmlOptions options) throws XmlException, IOException {
return XmlBeans.getContextTypeLoader().parse(file, type, getXmlOptions(options)); InputStream is = file.openStream();
try {
return parse(is, type, options);
} finally {
is.close();
}
} }
public static XmlObject parse(InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException { public static XmlObject parse(InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException {
return XmlBeans.getContextTypeLoader().parse(jiois, type, getXmlOptions(options)); try {
Document doc = DocumentHelper.readDocument(jiois);
return XmlBeans.getContextTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options));
} catch (SAXException e) {
throw new IOException("Unable to parse xml bean", e);
}
} }
public static XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException { public static XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException {
@ -97,7 +125,12 @@ public class POIXMLTypeLoader {
} }
public static XmlObject parse(Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException { public static XmlObject parse(Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException {
return XmlBeans.getContextTypeLoader().parse(jior, type, getXmlOptions(options)); try {
Document doc = DocumentHelper.readDocument(new InputSource(jior));
return XmlBeans.getContextTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options));
} catch (SAXException e) {
throw new XmlException("Unable to parse xml bean", e);
}
} }
public static XmlObject parse(Node node, SchemaType type, XmlOptions options) throws XmlException { public static XmlObject parse(Node node, SchemaType type, XmlOptions options) throws XmlException {
@ -108,7 +141,7 @@ public class POIXMLTypeLoader {
return XmlBeans.getContextTypeLoader().parse(xis, type, getXmlOptions(options)); return XmlBeans.getContextTypeLoader().parse(xis, type, getXmlOptions(options));
} }
public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException { public static XMLInputStream newValidatingXMLInputStream(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException {
return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream(xis, type, getXmlOptions(options)); return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream(xis, type, getXmlOptions(options));
} }
} }

61
fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java

@ -29,12 +29,55 @@ import javax.xml.stream.events.Namespace;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public final class DocumentHelper { public final class DocumentHelper {
private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class); private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class);
private DocumentHelper() {} private DocumentHelper() {
}
private static class DocHelperErrorHandler implements ErrorHandler {
public void warning(SAXParseException exception) throws SAXException {
printError(POILogger.WARN, exception);
}
public void error(SAXParseException exception) throws SAXException {
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 * Creates a new document builder, with sensible defaults
@ -43,6 +86,7 @@ public final class DocumentHelper {
try { try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER); documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
documentBuilder.setErrorHandler(new DocHelperErrorHandler());
return documentBuilder; return documentBuilder;
} catch (ParserConfigurationException e) { } catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e); throw new IllegalStateException("cannot create a DocumentBuilder", e);
@ -50,6 +94,7 @@ public final class DocumentHelper {
} }
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
static { static {
documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false); documentBuilderFactory.setValidating(false);
@ -69,7 +114,7 @@ public final class DocumentHelper {
private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) { private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
// Try built-in JVM one first, standalone if not // Try built-in JVM one first, standalone if not
for (String securityManagerClassName : new String[] { for (String securityManagerClassName : new String[]{
"com.sun.org.apache.xerces.internal.util.SecurityManager", "com.sun.org.apache.xerces.internal.util.SecurityManager",
"org.apache.xerces.util.SecurityManager" "org.apache.xerces.util.SecurityManager"
}) { }) {
@ -89,6 +134,7 @@ public final class DocumentHelper {
/** /**
* Parses the given stream via the default (sensible) * Parses the given stream via the default (sensible)
* DocumentBuilder * DocumentBuilder
*
* @param inp Stream to read the XML data from * @param inp Stream to read the XML data from
* @return the parsed Document * @return the parsed Document
*/ */
@ -96,6 +142,17 @@ public final class DocumentHelper {
return newDocumentBuilder().parse(inp); return newDocumentBuilder().parse(inp);
} }
/**
* Parses the given stream via the default (sensible)
* DocumentBuilder
*
* @param inp sax source to read the XML data from
* @return the parsed Document
*/
public static Document readDocument(InputSource inp) throws IOException, SAXException {
return newDocumentBuilder().parse(inp);
}
// must only be used to create empty documents, do not use it for parsing! // must only be used to create empty documents, do not use it for parsing!
private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder(); private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();

Loading…
Cancel
Save