XmlEventDecoder uses common defensive XMLInputFactory (now in StaxUtils)
Issue: SPR-15797
This commit is contained in:
@@ -20,6 +20,8 @@ import java.util.List;
|
|||||||
import javax.xml.stream.XMLEventFactory;
|
import javax.xml.stream.XMLEventFactory;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
import javax.xml.stream.XMLEventWriter;
|
import javax.xml.stream.XMLEventWriter;
|
||||||
|
import javax.xml.stream.XMLInputFactory;
|
||||||
|
import javax.xml.stream.XMLResolver;
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import javax.xml.stream.XMLStreamReader;
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
@@ -33,13 +35,15 @@ import org.xml.sax.ContentHandler;
|
|||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.StreamUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience methods for working with the StAX API. Partly historic due to JAXP 1.3 compatibility;
|
* Convenience methods for working with the StAX API. Partly historic due to JAXP 1.3
|
||||||
* as of Spring 4.0, relying on JAXP 1.4 as included in JDK 1.6 and higher.
|
* compatibility; as of Spring 4.0, relying on JAXP 1.4 as included in JDK 1.6 and higher.
|
||||||
*
|
*
|
||||||
* <p>In particular, methods for using StAX ({@code javax.xml.stream}) in combination with the TrAX API
|
* <p>In particular, methods for using StAX ({@code javax.xml.stream}) in combination with
|
||||||
* ({@code javax.xml.transform}), and converting StAX readers/writers into SAX readers/handlers and vice-versa.
|
* the TrAX API ({@code javax.xml.transform}), and converting StAX readers/writers into SAX
|
||||||
|
* readers/handlers and vice-versa.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
@@ -47,6 +51,24 @@ import org.springframework.lang.Nullable;
|
|||||||
*/
|
*/
|
||||||
public abstract class StaxUtils {
|
public abstract class StaxUtils {
|
||||||
|
|
||||||
|
private static final XMLResolver NO_OP_XML_RESOLVER =
|
||||||
|
(publicID, systemID, base, ns) -> StreamUtils.emptyInput();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an {@link XMLInputFactory} with Spring's defensive setup,
|
||||||
|
* i.e. no support for the resolution of DTDs and external entities.
|
||||||
|
* @return a new input factory to use
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public static XMLInputFactory createDefensiveInputFactory() {
|
||||||
|
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
||||||
|
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
||||||
|
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
||||||
|
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
|
||||||
|
return inputFactory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a JAXP 1.4 {@link StAXSource} for the given {@link XMLStreamReader}.
|
* Create a JAXP 1.4 {@link StAXSource} for the given {@link XMLStreamReader}.
|
||||||
* @param streamReader the StAX stream reader
|
* @param streamReader the StAX stream reader
|
||||||
@@ -57,7 +79,7 @@ public abstract class StaxUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a JAXP 1.4 a {@link StAXSource} for the given {@link XMLEventReader}.
|
* Create a JAXP 1.4 {@link StAXSource} for the given {@link XMLEventReader}.
|
||||||
* @param eventReader the StAX event reader
|
* @param eventReader the StAX event reader
|
||||||
* @return a source wrapping the {@code eventReader}
|
* @return a source wrapping the {@code eventReader}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.springframework.lang.Nullable;
|
|||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.MimeType;
|
import org.springframework.util.MimeType;
|
||||||
import org.springframework.util.MimeTypeUtils;
|
import org.springframework.util.MimeTypeUtils;
|
||||||
|
import org.springframework.util.xml.StaxUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a {@link DataBuffer} stream into a stream of {@link XMLEvent}s.
|
* Decodes a {@link DataBuffer} stream into a stream of {@link XMLEvent}s.
|
||||||
@@ -77,7 +78,7 @@ import org.springframework.util.MimeTypeUtils;
|
|||||||
*/
|
*/
|
||||||
public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
public class XmlEventDecoder extends AbstractDecoder<XMLEvent> {
|
||||||
|
|
||||||
private static final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
private static final XMLInputFactory inputFactory = StaxUtils.createDefensiveInputFactory();
|
||||||
|
|
||||||
private static final boolean aaltoPresent = ClassUtils.isPresent(
|
private static final boolean aaltoPresent = ClassUtils.isPresent(
|
||||||
"com.fasterxml.aalto.AsyncXMLStreamReader", XmlEventDecoder.class.getClassLoader());
|
"com.fasterxml.aalto.AsyncXMLStreamReader", XmlEventDecoder.class.getClassLoader());
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
|
||||||
import javax.xml.stream.XMLResolver;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFilter;
|
import com.fasterxml.jackson.annotation.JsonFilter;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
@@ -62,8 +60,8 @@ import org.springframework.context.ApplicationContext;
|
|||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StreamUtils;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.util.xml.StaxUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A builder used to create {@link ObjectMapper} instances with a fluent API.
|
* A builder used to create {@link ObjectMapper} instances with a fluent API.
|
||||||
@@ -827,38 +825,27 @@ public class Jackson2ObjectMapperBuilder {
|
|||||||
private static class XmlObjectMapperInitializer {
|
private static class XmlObjectMapperInitializer {
|
||||||
|
|
||||||
public ObjectMapper create() {
|
public ObjectMapper create() {
|
||||||
return new XmlMapper(xmlInputFactory());
|
return new XmlMapper(StaxUtils.createDefensiveInputFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectMapper create(boolean defaultUseWrapper) {
|
public ObjectMapper create(boolean defaultUseWrapper) {
|
||||||
JacksonXmlModule module = new JacksonXmlModule();
|
JacksonXmlModule module = new JacksonXmlModule();
|
||||||
module.setDefaultUseWrapper(defaultUseWrapper);
|
module.setDefaultUseWrapper(defaultUseWrapper);
|
||||||
return new XmlMapper(new XmlFactory(xmlInputFactory()), module);
|
return new XmlMapper(new XmlFactory(StaxUtils.createDefensiveInputFactory()), module);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static XMLInputFactory xmlInputFactory() {
|
|
||||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
|
||||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
|
||||||
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
|
||||||
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
|
|
||||||
return inputFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
|
|
||||||
@Override
|
|
||||||
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
|
|
||||||
return StreamUtils.emptyInput();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class SmileFactoryInitializer {
|
private static class SmileFactoryInitializer {
|
||||||
|
|
||||||
public JsonFactory create() {
|
public JsonFactory create() {
|
||||||
return new SmileFactory();
|
return new SmileFactory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class CborFactoryInitializer {
|
private static class CborFactoryInitializer {
|
||||||
|
|
||||||
public JsonFactory create() {
|
public JsonFactory create() {
|
||||||
return new CBORFactory();
|
return new CBORFactory();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import javax.xml.bind.Unmarshaller;
|
|||||||
import javax.xml.bind.annotation.XmlRootElement;
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
import javax.xml.stream.XMLResolver;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import javax.xml.stream.XMLStreamReader;
|
||||||
import javax.xml.transform.Result;
|
import javax.xml.transform.Result;
|
||||||
@@ -47,7 +46,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
|
|||||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.util.StreamUtils;
|
import org.springframework.util.xml.StaxUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@code HttpMessageConverter} that can read XML collections using JAXB2.
|
* An {@code HttpMessageConverter} that can read XML collections using JAXB2.
|
||||||
@@ -242,25 +241,15 @@ public class Jaxb2CollectionHttpMessageConverter<T extends Collection>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@code XMLInputFactory} that this converter will use to create {@link
|
* Create an {@code XMLInputFactory} that this converter will use to create
|
||||||
* javax.xml.stream.XMLStreamReader} and {@link javax.xml.stream.XMLEventReader} objects.
|
* {@link javax.xml.stream.XMLStreamReader} and {@link javax.xml.stream.XMLEventReader}
|
||||||
|
* objects.
|
||||||
* <p>Can be overridden in subclasses, adding further initialization of the factory.
|
* <p>Can be overridden in subclasses, adding further initialization of the factory.
|
||||||
* The resulting factory is cached, so this method will only be called once.
|
* The resulting factory is cached, so this method will only be called once.
|
||||||
|
* @see StaxUtils#createDefensiveInputFactory()
|
||||||
*/
|
*/
|
||||||
protected XMLInputFactory createXmlInputFactory() {
|
protected XMLInputFactory createXmlInputFactory() {
|
||||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
|
return StaxUtils.createDefensiveInputFactory();
|
||||||
inputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
|
||||||
inputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
|
|
||||||
inputFactory.setXMLResolver(NO_OP_XML_RESOLVER);
|
|
||||||
return inputFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
|
|
||||||
@Override
|
|
||||||
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
|
|
||||||
return StreamUtils.emptyInput();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2017 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -66,7 +66,13 @@ import org.springframework.util.StreamUtils;
|
|||||||
*/
|
*/
|
||||||
public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMessageConverter<T> {
|
public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMessageConverter<T> {
|
||||||
|
|
||||||
private static final Set<Class<?>> SUPPORTED_CLASSES = new HashSet<>(5);
|
private static final EntityResolver NO_OP_ENTITY_RESOLVER =
|
||||||
|
(publicId, systemId) -> new InputSource(new StringReader(""));
|
||||||
|
|
||||||
|
private static final XMLResolver NO_OP_XML_RESOLVER =
|
||||||
|
(publicID, systemID, base, ns) -> StreamUtils.emptyInput();
|
||||||
|
|
||||||
|
private static final Set<Class<?>> SUPPORTED_CLASSES = new HashSet<>(8);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
SUPPORTED_CLASSES.add(DOMSource.class);
|
SUPPORTED_CLASSES.add(DOMSource.class);
|
||||||
@@ -279,19 +285,4 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final EntityResolver NO_OP_ENTITY_RESOLVER = new EntityResolver() {
|
|
||||||
@Override
|
|
||||||
public InputSource resolveEntity(String publicId, String systemId) {
|
|
||||||
return new InputSource(new StringReader(""));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
|
|
||||||
@Override
|
|
||||||
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
|
|
||||||
return StreamUtils.emptyInput();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user