mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Consistently ignore exceptions for Xerces-specific properties
Closes gh-36682
(cherry picked from commit af7a5716e8)
This commit is contained in:
@@ -913,17 +913,29 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||
// By default, Spring will prevent the processing of external entities.
|
||||
// This is a mitigation against XXE attacks.
|
||||
if (xmlReader == null) {
|
||||
SAXParserFactory saxParserFactory = this.sourceParserFactory;
|
||||
if (saxParserFactory == null) {
|
||||
saxParserFactory = SAXParserFactory.newInstance();
|
||||
saxParserFactory.setNamespaceAware(true);
|
||||
saxParserFactory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
saxParserFactory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
this.sourceParserFactory = saxParserFactory;
|
||||
SAXParserFactory factory = this.sourceParserFactory;
|
||||
if (factory == null) {
|
||||
factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
this.sourceParserFactory = factory;
|
||||
}
|
||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
xmlReader = saxParser.getXMLReader();
|
||||
}
|
||||
if (!isProcessExternalEntities()) {
|
||||
@@ -931,8 +943,8 @@ public class Jaxb2Marshaller implements MimeMarshaller, MimeUnmarshaller, Generi
|
||||
}
|
||||
return new SAXSource(xmlReader, inputSource);
|
||||
}
|
||||
catch (SAXException | ParserConfigurationException ex) {
|
||||
logger.info("Processing of external entities could not be disabled", ex);
|
||||
catch (Exception ex) {
|
||||
logger.warn("Processing of external entities could not be disabled", ex);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
|
||||
(publicId, systemId) -> new InputSource(new StringReader(""));
|
||||
|
||||
|
||||
/** Logger available to subclasses. */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
@@ -167,8 +168,22 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
@@ -197,17 +212,29 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
* @throws ParserConfigurationException if thrown by JAXP methods
|
||||
*/
|
||||
protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException {
|
||||
SAXParserFactory parserFactory = this.saxParserFactory;
|
||||
if (parserFactory == null) {
|
||||
parserFactory = SAXParserFactory.newInstance();
|
||||
parserFactory.setNamespaceAware(true);
|
||||
parserFactory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
parserFactory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
this.saxParserFactory = parserFactory;
|
||||
SAXParserFactory factory = this.saxParserFactory;
|
||||
if (factory == null) {
|
||||
factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
this.saxParserFactory = factory;
|
||||
}
|
||||
SAXParser saxParser = parserFactory.newSAXParser();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
XMLReader xmlReader = saxParser.getXMLReader();
|
||||
if (!isProcessExternalEntities()) {
|
||||
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||
@@ -459,8 +486,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
|
||||
catch (NullPointerException ex) {
|
||||
if (!isSupportDtd()) {
|
||||
throw new UnmarshallingFailureException("NPE while unmarshalling. " +
|
||||
"This can happen on JDK 1.6 due to the presence of DTD " +
|
||||
"declarations, which are disabled.");
|
||||
"This can happen due to the presence of DTD declarations, which are disabled.");
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
|
||||
+27
-17
@@ -19,7 +19,6 @@ package org.springframework.http.converter.xml;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParser;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
import javax.xml.transform.Result;
|
||||
@@ -38,7 +37,6 @@ import jakarta.xml.bind.annotation.XmlRootElement;
|
||||
import jakarta.xml.bind.annotation.XmlType;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
@@ -68,6 +66,10 @@ import org.springframework.util.ClassUtils;
|
||||
*/
|
||||
public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessageConverter<Object> {
|
||||
|
||||
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
|
||||
(publicId, systemId) -> new InputSource(new StringReader(""));
|
||||
|
||||
|
||||
private boolean supportDtd = false;
|
||||
|
||||
private boolean processExternalEntities = false;
|
||||
@@ -177,24 +179,36 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||
try {
|
||||
// By default, Spring will prevent the processing of external entities.
|
||||
// This is a mitigation against XXE attacks.
|
||||
SAXParserFactory saxParserFactory = this.sourceParserFactory;
|
||||
if (saxParserFactory == null) {
|
||||
saxParserFactory = SAXParserFactory.newInstance();
|
||||
saxParserFactory.setNamespaceAware(true);
|
||||
saxParserFactory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
saxParserFactory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
this.sourceParserFactory = saxParserFactory;
|
||||
SAXParserFactory factory = this.sourceParserFactory;
|
||||
if (factory == null) {
|
||||
factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
this.sourceParserFactory = factory;
|
||||
}
|
||||
SAXParser saxParser = saxParserFactory.newSAXParser();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
XMLReader xmlReader = saxParser.getXMLReader();
|
||||
if (!isProcessExternalEntities()) {
|
||||
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||
}
|
||||
return new SAXSource(xmlReader, inputSource);
|
||||
}
|
||||
catch (SAXException | ParserConfigurationException ex) {
|
||||
catch (Exception ex) {
|
||||
logger.warn("Processing of external entities could not be disabled", ex);
|
||||
return source;
|
||||
}
|
||||
@@ -240,8 +254,4 @@ public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessa
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
|
||||
(publicId, systemId) -> new InputSource(new StringReader(""));
|
||||
|
||||
}
|
||||
|
||||
+49
-21
@@ -179,17 +179,29 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||
try {
|
||||
// By default, Spring will prevent the processing of external entities.
|
||||
// This is a mitigation against XXE attacks.
|
||||
DocumentBuilderFactory builderFactory = this.documentBuilderFactory;
|
||||
if (builderFactory == null) {
|
||||
builderFactory = DocumentBuilderFactory.newInstance();
|
||||
builderFactory.setNamespaceAware(true);
|
||||
builderFactory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
builderFactory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
this.documentBuilderFactory = builderFactory;
|
||||
DocumentBuilderFactory factory = this.documentBuilderFactory;
|
||||
if (factory == null) {
|
||||
factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
this.documentBuilderFactory = factory;
|
||||
}
|
||||
DocumentBuilder builder = builderFactory.newDocumentBuilder();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
if (!isProcessExternalEntities()) {
|
||||
builder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||
}
|
||||
@@ -215,17 +227,29 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||
|
||||
private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
|
||||
try {
|
||||
SAXParserFactory parserFactory = this.saxParserFactory;
|
||||
if (parserFactory == null) {
|
||||
parserFactory = SAXParserFactory.newInstance();
|
||||
parserFactory.setNamespaceAware(true);
|
||||
parserFactory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
parserFactory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
this.saxParserFactory = parserFactory;
|
||||
SAXParserFactory factory = this.saxParserFactory;
|
||||
if (factory == null) {
|
||||
factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Xerces properties not recognized/supported - ignore
|
||||
}
|
||||
try {
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
|
||||
factory.setFeature(
|
||||
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// SAX properties not recognized/supported - ignore
|
||||
}
|
||||
this.saxParserFactory = factory;
|
||||
}
|
||||
SAXParser saxParser = parserFactory.newSAXParser();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
XMLReader xmlReader = saxParser.getXMLReader();
|
||||
if (!isProcessExternalEntities()) {
|
||||
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
|
||||
@@ -233,7 +257,11 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
||||
byte[] bytes = StreamUtils.copyToByteArray(body);
|
||||
return new SAXSource(xmlReader, new InputSource(new ByteArrayInputStream(bytes)));
|
||||
}
|
||||
catch (SAXException | ParserConfigurationException ex) {
|
||||
catch (ParserConfigurationException ex) {
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not set feature: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
catch (SAXException ex) {
|
||||
throw new HttpMessageNotReadableException(
|
||||
"Could not parse document: " + ex.getMessage(), ex, inputMessage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user