Skip to content

Commit cba8f22

Browse files
committed
Consistently ignore exceptions for Xerces-specific properties
Closes gh-36682 (cherry picked from commit af7a571)
1 parent 515152b commit cba8f22

4 files changed

Lines changed: 140 additions & 64 deletions

File tree

spring-oxm/src/main/java/org/springframework/oxm/jaxb/Jaxb2Marshaller.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -913,26 +913,38 @@ else if (streamSource.getReader() != null) {
913913
// By default, Spring will prevent the processing of external entities.
914914
// This is a mitigation against XXE attacks.
915915
if (xmlReader == null) {
916-
SAXParserFactory saxParserFactory = this.sourceParserFactory;
917-
if (saxParserFactory == null) {
918-
saxParserFactory = SAXParserFactory.newInstance();
919-
saxParserFactory.setNamespaceAware(true);
920-
saxParserFactory.setFeature(
921-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
922-
saxParserFactory.setFeature(
923-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
924-
this.sourceParserFactory = saxParserFactory;
916+
SAXParserFactory factory = this.sourceParserFactory;
917+
if (factory == null) {
918+
factory = SAXParserFactory.newInstance();
919+
factory.setNamespaceAware(true);
920+
try {
921+
factory.setFeature(
922+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
923+
}
924+
catch (Exception ex) {
925+
// Xerces properties not recognized/supported - ignore
926+
}
927+
try {
928+
factory.setFeature(
929+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
930+
factory.setFeature(
931+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
932+
}
933+
catch (Exception ex) {
934+
// SAX properties not recognized/supported - ignore
935+
}
936+
this.sourceParserFactory = factory;
925937
}
926-
SAXParser saxParser = saxParserFactory.newSAXParser();
938+
SAXParser saxParser = factory.newSAXParser();
927939
xmlReader = saxParser.getXMLReader();
928940
}
929941
if (!isProcessExternalEntities()) {
930942
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
931943
}
932944
return new SAXSource(xmlReader, inputSource);
933945
}
934-
catch (SAXException | ParserConfigurationException ex) {
935-
logger.info("Processing of external entities could not be disabled", ex);
946+
catch (Exception ex) {
947+
logger.warn("Processing of external entities could not be disabled", ex);
936948
return source;
937949
}
938950
}

spring-oxm/src/main/java/org/springframework/oxm/support/AbstractMarshaller.java

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public abstract class AbstractMarshaller implements Marshaller, Unmarshaller {
7575
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
7676
(publicId, systemId) -> new InputSource(new StringReader(""));
7777

78+
7879
/** Logger available to subclasses. */
7980
protected final Log logger = LogFactory.getLog(getClass());
8081

@@ -167,8 +168,22 @@ protected DocumentBuilderFactory createDocumentBuilderFactory() throws ParserCon
167168
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
168169
factory.setValidating(false);
169170
factory.setNamespaceAware(true);
170-
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
171-
factory.setFeature("http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
171+
try {
172+
factory.setFeature(
173+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
174+
}
175+
catch (Exception ex) {
176+
// Xerces properties not recognized/supported - ignore
177+
}
178+
try {
179+
factory.setFeature(
180+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
181+
factory.setFeature(
182+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
183+
}
184+
catch (Exception ex) {
185+
// SAX properties not recognized/supported - ignore
186+
}
172187
return factory;
173188
}
174189

@@ -197,17 +212,29 @@ protected DocumentBuilder createDocumentBuilder(DocumentBuilderFactory factory)
197212
* @throws ParserConfigurationException if thrown by JAXP methods
198213
*/
199214
protected XMLReader createXmlReader() throws SAXException, ParserConfigurationException {
200-
SAXParserFactory parserFactory = this.saxParserFactory;
201-
if (parserFactory == null) {
202-
parserFactory = SAXParserFactory.newInstance();
203-
parserFactory.setNamespaceAware(true);
204-
parserFactory.setFeature(
205-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
206-
parserFactory.setFeature(
207-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
208-
this.saxParserFactory = parserFactory;
215+
SAXParserFactory factory = this.saxParserFactory;
216+
if (factory == null) {
217+
factory = SAXParserFactory.newInstance();
218+
factory.setNamespaceAware(true);
219+
try {
220+
factory.setFeature(
221+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
222+
}
223+
catch (Exception ex) {
224+
// Xerces properties not recognized/supported - ignore
225+
}
226+
try {
227+
factory.setFeature(
228+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
229+
factory.setFeature(
230+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
231+
}
232+
catch (Exception ex) {
233+
// SAX properties not recognized/supported - ignore
234+
}
235+
this.saxParserFactory = factory;
209236
}
210-
SAXParser saxParser = parserFactory.newSAXParser();
237+
SAXParser saxParser = factory.newSAXParser();
211238
XMLReader xmlReader = saxParser.getXMLReader();
212239
if (!isProcessExternalEntities()) {
213240
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
@@ -459,8 +486,7 @@ protected Object unmarshalSaxSource(SAXSource saxSource) throws XmlMappingExcept
459486
catch (NullPointerException ex) {
460487
if (!isSupportDtd()) {
461488
throw new UnmarshallingFailureException("NPE while unmarshalling. " +
462-
"This can happen on JDK 1.6 due to the presence of DTD " +
463-
"declarations, which are disabled.");
489+
"This can happen due to the presence of DTD declarations, which are disabled.");
464490
}
465491
throw ex;
466492
}

spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2RootElementHttpMessageConverter.java

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.io.StringReader;
2020
import java.nio.charset.Charset;
2121

22-
import javax.xml.parsers.ParserConfigurationException;
2322
import javax.xml.parsers.SAXParser;
2423
import javax.xml.parsers.SAXParserFactory;
2524
import javax.xml.transform.Result;
@@ -38,7 +37,6 @@
3837
import jakarta.xml.bind.annotation.XmlType;
3938
import org.xml.sax.EntityResolver;
4039
import org.xml.sax.InputSource;
41-
import org.xml.sax.SAXException;
4240
import org.xml.sax.XMLReader;
4341

4442
import org.springframework.core.annotation.AnnotationUtils;
@@ -68,6 +66,10 @@
6866
*/
6967
public class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessageConverter<Object> {
7068

69+
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
70+
(publicId, systemId) -> new InputSource(new StringReader(""));
71+
72+
7173
private boolean supportDtd = false;
7274

7375
private boolean processExternalEntities = false;
@@ -177,24 +179,36 @@ protected Source processSource(Source source, @Nullable Charset charset) {
177179
try {
178180
// By default, Spring will prevent the processing of external entities.
179181
// This is a mitigation against XXE attacks.
180-
SAXParserFactory saxParserFactory = this.sourceParserFactory;
181-
if (saxParserFactory == null) {
182-
saxParserFactory = SAXParserFactory.newInstance();
183-
saxParserFactory.setNamespaceAware(true);
184-
saxParserFactory.setFeature(
185-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
186-
saxParserFactory.setFeature(
187-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
188-
this.sourceParserFactory = saxParserFactory;
182+
SAXParserFactory factory = this.sourceParserFactory;
183+
if (factory == null) {
184+
factory = SAXParserFactory.newInstance();
185+
factory.setNamespaceAware(true);
186+
try {
187+
factory.setFeature(
188+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
189+
}
190+
catch (Exception ex) {
191+
// Xerces properties not recognized/supported - ignore
192+
}
193+
try {
194+
factory.setFeature(
195+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
196+
factory.setFeature(
197+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
198+
}
199+
catch (Exception ex) {
200+
// SAX properties not recognized/supported - ignore
201+
}
202+
this.sourceParserFactory = factory;
189203
}
190-
SAXParser saxParser = saxParserFactory.newSAXParser();
204+
SAXParser saxParser = factory.newSAXParser();
191205
XMLReader xmlReader = saxParser.getXMLReader();
192206
if (!isProcessExternalEntities()) {
193207
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
194208
}
195209
return new SAXSource(xmlReader, inputSource);
196210
}
197-
catch (SAXException | ParserConfigurationException ex) {
211+
catch (Exception ex) {
198212
logger.warn("Processing of external entities could not be disabled", ex);
199213
return source;
200214
}
@@ -240,8 +254,4 @@ protected boolean supportsRepeatableWrites(Object o) {
240254
return true;
241255
}
242256

243-
244-
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
245-
(publicId, systemId) -> new InputSource(new StringReader(""));
246-
247257
}

spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,29 @@ private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage)
179179
try {
180180
// By default, Spring will prevent the processing of external entities.
181181
// This is a mitigation against XXE attacks.
182-
DocumentBuilderFactory builderFactory = this.documentBuilderFactory;
183-
if (builderFactory == null) {
184-
builderFactory = DocumentBuilderFactory.newInstance();
185-
builderFactory.setNamespaceAware(true);
186-
builderFactory.setFeature(
187-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
188-
builderFactory.setFeature(
189-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
190-
this.documentBuilderFactory = builderFactory;
182+
DocumentBuilderFactory factory = this.documentBuilderFactory;
183+
if (factory == null) {
184+
factory = DocumentBuilderFactory.newInstance();
185+
factory.setNamespaceAware(true);
186+
try {
187+
factory.setFeature(
188+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
189+
}
190+
catch (Exception ex) {
191+
// Xerces properties not recognized/supported - ignore
192+
}
193+
try {
194+
factory.setFeature(
195+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
196+
factory.setFeature(
197+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
198+
}
199+
catch (Exception ex) {
200+
// SAX properties not recognized/supported - ignore
201+
}
202+
this.documentBuilderFactory = factory;
191203
}
192-
DocumentBuilder builder = builderFactory.newDocumentBuilder();
204+
DocumentBuilder builder = factory.newDocumentBuilder();
193205
if (!isProcessExternalEntities()) {
194206
builder.setEntityResolver(NO_OP_ENTITY_RESOLVER);
195207
}
@@ -215,25 +227,41 @@ private DOMSource readDOMSource(InputStream body, HttpInputMessage inputMessage)
215227

216228
private SAXSource readSAXSource(InputStream body, HttpInputMessage inputMessage) throws IOException {
217229
try {
218-
SAXParserFactory parserFactory = this.saxParserFactory;
219-
if (parserFactory == null) {
220-
parserFactory = SAXParserFactory.newInstance();
221-
parserFactory.setNamespaceAware(true);
222-
parserFactory.setFeature(
223-
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
224-
parserFactory.setFeature(
225-
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
226-
this.saxParserFactory = parserFactory;
230+
SAXParserFactory factory = this.saxParserFactory;
231+
if (factory == null) {
232+
factory = SAXParserFactory.newInstance();
233+
factory.setNamespaceAware(true);
234+
try {
235+
factory.setFeature(
236+
"http://apache.org/xml/features/disallow-doctype-decl", !isSupportDtd());
237+
}
238+
catch (Exception ex) {
239+
// Xerces properties not recognized/supported - ignore
240+
}
241+
try {
242+
factory.setFeature(
243+
"http://xml.org/sax/features/external-general-entities", isProcessExternalEntities());
244+
factory.setFeature(
245+
"http://xml.org/sax/features/external-parameter-entities", isProcessExternalEntities());
246+
}
247+
catch (Exception ex) {
248+
// SAX properties not recognized/supported - ignore
249+
}
250+
this.saxParserFactory = factory;
227251
}
228-
SAXParser saxParser = parserFactory.newSAXParser();
252+
SAXParser saxParser = factory.newSAXParser();
229253
XMLReader xmlReader = saxParser.getXMLReader();
230254
if (!isProcessExternalEntities()) {
231255
xmlReader.setEntityResolver(NO_OP_ENTITY_RESOLVER);
232256
}
233257
byte[] bytes = StreamUtils.copyToByteArray(body);
234258
return new SAXSource(xmlReader, new InputSource(new ByteArrayInputStream(bytes)));
235259
}
236-
catch (SAXException | ParserConfigurationException ex) {
260+
catch (ParserConfigurationException ex) {
261+
throw new HttpMessageNotReadableException(
262+
"Could not set feature: " + ex.getMessage(), ex, inputMessage);
263+
}
264+
catch (SAXException ex) {
237265
throw new HttpMessageNotReadableException(
238266
"Could not parse document: " + ex.getMessage(), ex, inputMessage);
239267
}

0 commit comments

Comments
 (0)