diff --git a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/item/xml/Jaxb2MarshallingTests.java b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/item/xml/Jaxb2MarshallingTests.java
index 00e3d5296..b3f340b7a 100644
--- a/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/item/xml/Jaxb2MarshallingTests.java
+++ b/spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/item/xml/Jaxb2MarshallingTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2014 the original author or authors.
+ * Copyright 2010-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue;
import java.io.StringWriter;
import java.math.BigDecimal;
+import javax.xml.XMLConstants;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
@@ -48,7 +49,10 @@ public class Jaxb2MarshallingTests extends AbstractStaxEventWriterItemWriterTest
public static String getTextFromSource(Source source) {
try {
- Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ TransformerFactory transformerFactory = TransformerFactory.newInstance();
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+ Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult stream = new StreamResult(new StringWriter());
transformer.transform(source, stream);
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java
index db225b9c4..b2da676ee 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2007 the original author or authors.
+ * Copyright 2006-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@ import org.springframework.util.StringUtils;
* The implementation is not thread-safe.
*
* @author Robert Kasanicky
+ * @author Mahmoud Ben Hassine
*/
public class StaxEventItemReader extends AbstractItemCountingItemStreamItemReader implements
ResourceAwareItemReaderItemStream, InitializingBean {
@@ -76,6 +77,8 @@ ResourceAwareItemReaderItemStream, InitializingBean {
private boolean strict = true;
+ private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();
+
public StaxEventItemReader() {
setName(ClassUtils.getShortName(StaxEventItemReader.class));
}
@@ -118,6 +121,15 @@ ResourceAwareItemReaderItemStream, InitializingBean {
}
}
+ /**
+ * Set the {@link XMLInputFactory}.
+ * @param xmlInputFactory to use
+ */
+ public void setXmlInputFactory(XMLInputFactory xmlInputFactory) {
+ Assert.notNull(xmlInputFactory, "XMLInputFactory must not be null");
+ this.xmlInputFactory = xmlInputFactory;
+ }
+
/**
* Ensure that all required dependencies for the ItemReader to run are provided after all properties have been set.
*
@@ -208,7 +220,7 @@ ResourceAwareItemReaderItemStream, InitializingBean {
}
inputStream = resource.getInputStream();
- eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
+ eventReader = xmlInputFactory.createXMLEventReader(inputStream);
fragmentReader = new DefaultFragmentEventReader(eventReader);
noInput = false;
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java
index c274f0b3a..3122ab18f 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2007 the original author or authors.
+ * Copyright 2006-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.batch.item.xml;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
+import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -31,6 +32,7 @@ import javax.xml.transform.stax.StAXSource;
* This class is thread-safe.
*
* @author Josh Long
+ * @author Mahmoud Ben Hassine
*
*/
public abstract class StaxUtils {
@@ -42,4 +44,11 @@ public abstract class StaxUtils {
public static Result getResult(XMLEventWriter w) {
return new StAXResult(w);
}
+
+ public static XMLInputFactory createXmlInputFactory() {
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
+ xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
+ return xmlInputFactory;
+ }
}
diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilder.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilder.java
index f97798c6a..deaba19a1 100644
--- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilder.java
+++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import javax.xml.stream.XMLInputFactory;
+
import org.springframework.batch.item.xml.StaxEventItemReader;
+import org.springframework.batch.item.xml.StaxUtils;
import org.springframework.core.io.Resource;
import org.springframework.oxm.Unmarshaller;
import org.springframework.util.Assert;
@@ -50,6 +53,8 @@ public class StaxEventItemReaderBuilder {
private int currentItemCount;
+ private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();
+
/**
* Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport}
* should be persisted within the {@link org.springframework.batch.item.ExecutionContext}
@@ -175,6 +180,19 @@ public class StaxEventItemReaderBuilder {
return this;
}
+ /**
+ * Set the {@link XMLInputFactory}.
+ *
+ * @param xmlInputFactory to use
+ * @return The current instance of the builder
+ * @see StaxEventItemReader#setXmlInputFactory(XMLInputFactory)
+ */
+ public StaxEventItemReaderBuilder xmlInputFactory(XMLInputFactory xmlInputFactory) {
+ this.xmlInputFactory = xmlInputFactory;
+
+ return this;
+ }
+
/**
* Validates the configuration and builds a new {@link StaxEventItemReader}
*
@@ -203,6 +221,7 @@ public class StaxEventItemReaderBuilder {
reader.setUnmarshaller(this.unmarshaller);
reader.setCurrentItemCount(this.currentItemCount);
reader.setMaxItemCount(this.maxItemCount);
+ reader.setXmlInputFactory(this.xmlInputFactory);
return reader;
}
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java
index a33905ebf..1a92b6a24 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2014 the original author or authors.
+ * Copyright 2008-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
*/
package org.springframework.batch.item.xml;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.item.ExecutionContext;
@@ -33,12 +35,12 @@ import org.springframework.util.ClassUtils;
import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Source;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -56,6 +58,8 @@ import static org.junit.Assert.fail;
* Tests for {@link StaxEventItemReader}.
*
* @author Robert Kasanicky
+ * @author Michael Minella
+ * @author Mahmoud Ben Hassine
*/
public class StaxEventItemReaderTests {
@@ -329,7 +333,7 @@ public class StaxEventItemReaderTests {
@Test
public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(xml.getBytes());
- XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
+ XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
final int EXPECTED_NUMBER_OF_FRAGMENTS = 2;
for (int i = 0; i < EXPECTED_NUMBER_OF_FRAGMENTS; i++) {
@@ -346,7 +350,7 @@ public class StaxEventItemReaderTests {
@Test
public void testMoveCursorToNextFragmentOnEmpty() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(emptyXml.getBytes());
- XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
+ XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
assertFalse(source.moveCursorToNextFragment(reader));
}
@@ -357,7 +361,7 @@ public class StaxEventItemReaderTests {
@Test
public void testMoveCursorToNextFragmentOnMissing() throws XMLStreamException, FactoryConfigurationError, IOException {
Resource resource = new ByteArrayResource(missingXml.getBytes());
- XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
+ XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
assertFalse(source.moveCursorToNextFragment(reader));
}
@@ -577,6 +581,39 @@ public class StaxEventItemReaderTests {
assertNull(source.read());
}
+ @Test
+ public void testDtdXml() {
+ String xmlWithDtd = "\n\n]>\n&entityex;";
+ StaxEventItemReader reader = new StaxEventItemReader<>();
+ reader.setName("foo");
+ reader.setResource(new ByteArrayResource(xmlWithDtd.getBytes()));
+ reader.setUnmarshaller(new MockFragmentUnmarshaller() {
+ @Override
+ public Object unmarshal(Source source) throws XmlMappingException {
+ try {
+ XMLEventReader xmlEventReader = StaxTestUtils.getXmlEventReader(source);
+ xmlEventReader.nextEvent();
+ xmlEventReader.nextEvent();
+ return xmlEventReader.getElementText();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ reader.setFragmentRootElementName("abc");
+
+ reader.open(new ExecutionContext());
+
+ try {
+ reader.read();
+ fail("Should fail when XML contains DTD");
+ } catch (Exception e) {
+ Assert.assertThat(e.getMessage(), Matchers.containsString("Undeclared general entity \"entityex\""));
+ }
+ }
+
/**
* Stub emulating problems during unmarshalling.
*/
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilderTests.java
index ff7d16db8..c73ff7645 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilderTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 the original author or authors.
+ * Copyright 2017-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.batch.item.xml.builder;
import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.stream.XMLInputFactory;
import org.junit.Before;
import org.junit.Test;
@@ -35,6 +36,7 @@ import static org.junit.Assert.fail;
/**
* @author Michael Minella
+ * @author Mahmoud Ben Hassine
*/
public class StaxEventItemReaderBuilderTests {
@@ -95,6 +97,7 @@ public class StaxEventItemReaderBuilderTests {
.currentItemCount(1)
.maxItemCount(2)
.unmarshaller(unmarshaller)
+ .xmlInputFactory(XMLInputFactory.newInstance())
.build();
reader.afterPropertiesSet();
diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/DefaultFragmentEventReaderTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/DefaultFragmentEventReaderTests.java
index 8e1717ae2..719e9d4fd 100644
--- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/DefaultFragmentEventReaderTests.java
+++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/DefaultFragmentEventReaderTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2012 the original author or authors.
+ * Copyright 2008-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,13 +18,13 @@ package org.springframework.batch.item.xml.stax;
import java.util.NoSuchElementException;
import javax.xml.stream.XMLEventReader;
-import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import junit.framework.TestCase;
import org.springframework.batch.item.xml.EventHelper;
+import org.springframework.batch.item.xml.StaxUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
@@ -32,6 +32,7 @@ import org.springframework.core.io.Resource;
* Tests for {@link DefaultFragmentEventReader}.
*
* @author Robert Kasanicky
+ * @author Mahmoud Ben Hassine
*/
public class DefaultFragmentEventReaderTests extends TestCase {
@@ -50,7 +51,7 @@ public class DefaultFragmentEventReaderTests extends TestCase {
@Override
protected void setUp() throws Exception {
Resource input = new ByteArrayResource(xml.getBytes());
- eventReader = XMLInputFactory.newInstance().createXMLEventReader(
+ eventReader = StaxUtils.createXmlInputFactory().createXMLEventReader(
input.getInputStream());
fragmentReader = new DefaultFragmentEventReader(eventReader);
}