Skip to content

Commit edfbdbb

Browse files
committed
Tweak XmlInputFactory settings
1 parent 7ca11f2 commit edfbdbb

File tree

7 files changed

+100
-15
lines changed

7 files changed

+100
-15
lines changed

spring-batch-infrastructure-tests/src/test/java/org/springframework/batch/item/xml/Jaxb2MarshallingTests.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2010-2014 the original author or authors.
2+
* Copyright 2010-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.io.StringWriter;
2121
import java.math.BigDecimal;
2222

23+
import javax.xml.XMLConstants;
2324
import javax.xml.transform.OutputKeys;
2425
import javax.xml.transform.Source;
2526
import javax.xml.transform.Transformer;
@@ -48,7 +49,10 @@ protected Marshaller getMarshaller() throws Exception {
4849

4950
public static String getTextFromSource(Source source) {
5051
try {
51-
Transformer transformer = TransformerFactory.newInstance().newTransformer();
52+
TransformerFactory transformerFactory = TransformerFactory.newInstance();
53+
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
54+
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
55+
Transformer transformer = transformerFactory.newTransformer();
5256
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
5357
StreamResult stream = new StreamResult(new StringWriter());
5458
transformer.transform(source, stream);

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxEventItemReader.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2007 the original author or authors.
2+
* Copyright 2006-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -54,6 +54,7 @@
5454
* The implementation is <b>not</b> thread-safe.
5555
*
5656
* @author Robert Kasanicky
57+
* @author Mahmoud Ben Hassine
5758
*/
5859
public class StaxEventItemReader<T> extends AbstractItemCountingItemStreamItemReader<T> implements
5960
ResourceAwareItemReaderItemStream<T>, InitializingBean {
@@ -76,6 +77,8 @@ public class StaxEventItemReader<T> extends AbstractItemCountingItemStreamItemRe
7677

7778
private boolean strict = true;
7879

80+
private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();
81+
7982
public StaxEventItemReader() {
8083
setName(ClassUtils.getShortName(StaxEventItemReader.class));
8184
}
@@ -118,6 +121,15 @@ public void setFragmentRootElementNames(String[] fragmentRootElementNames) {
118121
}
119122
}
120123

124+
/**
125+
* Set the {@link XMLInputFactory}.
126+
* @param xmlInputFactory to use
127+
*/
128+
public void setXmlInputFactory(XMLInputFactory xmlInputFactory) {
129+
Assert.notNull(xmlInputFactory, "XMLInputFactory must not be null");
130+
this.xmlInputFactory = xmlInputFactory;
131+
}
132+
121133
/**
122134
* Ensure that all required dependencies for the ItemReader to run are provided after all properties have been set.
123135
*
@@ -208,7 +220,7 @@ protected void doOpen() throws Exception {
208220
}
209221

210222
inputStream = resource.getInputStream();
211-
eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
223+
eventReader = xmlInputFactory.createXMLEventReader(inputStream);
212224
fragmentReader = new DefaultFragmentEventReader(eventReader);
213225
noInput = false;
214226

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/StaxUtils.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2007 the original author or authors.
2+
* Copyright 2006-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import javax.xml.stream.XMLEventReader;
2020
import javax.xml.stream.XMLEventWriter;
21+
import javax.xml.stream.XMLInputFactory;
2122
import javax.xml.stream.XMLStreamException;
2223
import javax.xml.transform.Result;
2324
import javax.xml.transform.Source;
@@ -31,6 +32,7 @@
3132
* This class is thread-safe.
3233
*
3334
* @author Josh Long
35+
* @author Mahmoud Ben Hassine
3436
*
3537
*/
3638
public abstract class StaxUtils {
@@ -42,4 +44,11 @@ public static Source getSource(XMLEventReader r) throws XMLStreamException {
4244
public static Result getResult(XMLEventWriter w) {
4345
return new StAXResult(w);
4446
}
47+
48+
public static XMLInputFactory createXmlInputFactory() {
49+
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
50+
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
51+
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
52+
return xmlInputFactory;
53+
}
4554
}

spring-batch-infrastructure/src/main/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilder.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,7 +19,10 @@
1919
import java.util.Arrays;
2020
import java.util.List;
2121

22+
import javax.xml.stream.XMLInputFactory;
23+
2224
import org.springframework.batch.item.xml.StaxEventItemReader;
25+
import org.springframework.batch.item.xml.StaxUtils;
2326
import org.springframework.core.io.Resource;
2427
import org.springframework.oxm.Unmarshaller;
2528
import org.springframework.util.Assert;
@@ -50,6 +53,8 @@ public class StaxEventItemReaderBuilder<T> {
5053

5154
private int currentItemCount;
5255

56+
private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();
57+
5358
/**
5459
* Configure if the state of the {@link org.springframework.batch.item.ItemStreamSupport}
5560
* should be persisted within the {@link org.springframework.batch.item.ExecutionContext}
@@ -175,6 +180,19 @@ public StaxEventItemReaderBuilder<T> strict(boolean strict) {
175180
return this;
176181
}
177182

183+
/**
184+
* Set the {@link XMLInputFactory}.
185+
*
186+
* @param xmlInputFactory to use
187+
* @return The current instance of the builder
188+
* @see StaxEventItemReader#setXmlInputFactory(XMLInputFactory)
189+
*/
190+
public StaxEventItemReaderBuilder<T> xmlInputFactory(XMLInputFactory xmlInputFactory) {
191+
this.xmlInputFactory = xmlInputFactory;
192+
193+
return this;
194+
}
195+
178196
/**
179197
* Validates the configuration and builds a new {@link StaxEventItemReader}
180198
*
@@ -203,6 +221,7 @@ public StaxEventItemReader<T> build() {
203221
reader.setUnmarshaller(this.unmarshaller);
204222
reader.setCurrentItemCount(this.currentItemCount);
205223
reader.setMaxItemCount(this.maxItemCount);
224+
reader.setXmlInputFactory(this.xmlInputFactory);
206225

207226
return reader;
208227
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/StaxEventItemReaderTests.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2014 the original author or authors.
2+
* Copyright 2008-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,8 @@
1515
*/
1616
package org.springframework.batch.item.xml;
1717

18+
import org.hamcrest.Matchers;
19+
import org.junit.Assert;
1820
import org.junit.Before;
1921
import org.junit.Test;
2022
import org.springframework.batch.item.ExecutionContext;
@@ -33,12 +35,12 @@
3335
import javax.xml.namespace.QName;
3436
import javax.xml.stream.FactoryConfigurationError;
3537
import javax.xml.stream.XMLEventReader;
36-
import javax.xml.stream.XMLInputFactory;
3738
import javax.xml.stream.XMLStreamException;
3839
import javax.xml.stream.events.EndElement;
3940
import javax.xml.stream.events.StartElement;
4041
import javax.xml.stream.events.XMLEvent;
4142
import javax.xml.transform.Source;
43+
import java.io.File;
4244
import java.io.IOException;
4345
import java.io.InputStream;
4446
import java.util.ArrayList;
@@ -56,6 +58,8 @@
5658
* Tests for {@link StaxEventItemReader}.
5759
*
5860
* @author Robert Kasanicky
61+
* @author Michael Minella
62+
* @author Mahmoud Ben Hassine
5963
*/
6064
public class StaxEventItemReaderTests {
6165

@@ -329,7 +333,7 @@ public void testMultiFragmentNestedRestart() throws Exception {
329333
@Test
330334
public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryConfigurationError, IOException {
331335
Resource resource = new ByteArrayResource(xml.getBytes());
332-
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
336+
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
333337

334338
final int EXPECTED_NUMBER_OF_FRAGMENTS = 2;
335339
for (int i = 0; i < EXPECTED_NUMBER_OF_FRAGMENTS; i++) {
@@ -346,7 +350,7 @@ public void testMoveCursorToNextFragment() throws XMLStreamException, FactoryCon
346350
@Test
347351
public void testMoveCursorToNextFragmentOnEmpty() throws XMLStreamException, FactoryConfigurationError, IOException {
348352
Resource resource = new ByteArrayResource(emptyXml.getBytes());
349-
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
353+
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
350354

351355
assertFalse(source.moveCursorToNextFragment(reader));
352356
}
@@ -357,7 +361,7 @@ public void testMoveCursorToNextFragmentOnEmpty() throws XMLStreamException, Fac
357361
@Test
358362
public void testMoveCursorToNextFragmentOnMissing() throws XMLStreamException, FactoryConfigurationError, IOException {
359363
Resource resource = new ByteArrayResource(missingXml.getBytes());
360-
XMLEventReader reader = XMLInputFactory.newInstance().createXMLEventReader(resource.getInputStream());
364+
XMLEventReader reader = StaxUtils.createXmlInputFactory().createXMLEventReader(resource.getInputStream());
361365
assertFalse(source.moveCursorToNextFragment(reader));
362366
}
363367

@@ -577,6 +581,39 @@ public void exceptionDuringUnmarshalling() throws Exception {
577581
assertNull(source.read());
578582
}
579583

584+
@Test
585+
public void testDtdXml() {
586+
String xmlWithDtd = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE rohit [\n<!ENTITY entityex SYSTEM \"file://" +
587+
new File("src/test/resources/org/springframework/batch/support/existing.txt").getAbsolutePath() +
588+
"\">\n]>\n<abc>&entityex;</abc>";
589+
StaxEventItemReader<String> reader = new StaxEventItemReader<>();
590+
reader.setName("foo");
591+
reader.setResource(new ByteArrayResource(xmlWithDtd.getBytes()));
592+
reader.setUnmarshaller(new MockFragmentUnmarshaller() {
593+
@Override
594+
public Object unmarshal(Source source) throws XmlMappingException {
595+
try {
596+
XMLEventReader xmlEventReader = StaxTestUtils.getXmlEventReader(source);
597+
xmlEventReader.nextEvent();
598+
xmlEventReader.nextEvent();
599+
return xmlEventReader.getElementText();
600+
} catch (Exception e) {
601+
throw new RuntimeException(e);
602+
}
603+
}
604+
});
605+
reader.setFragmentRootElementName("abc");
606+
607+
reader.open(new ExecutionContext());
608+
609+
try {
610+
reader.read();
611+
fail("Should fail when XML contains DTD");
612+
} catch (Exception e) {
613+
Assert.assertThat(e.getMessage(), Matchers.containsString("Undeclared general entity \"entityex\""));
614+
}
615+
}
616+
580617
/**
581618
* Stub emulating problems during unmarshalling.
582619
*/

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/builder/StaxEventItemReaderBuilderTests.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2017 the original author or authors.
2+
* Copyright 2017-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616
package org.springframework.batch.item.xml.builder;
1717

1818
import javax.xml.bind.annotation.XmlRootElement;
19+
import javax.xml.stream.XMLInputFactory;
1920

2021
import org.junit.Before;
2122
import org.junit.Test;
@@ -35,6 +36,7 @@
3536

3637
/**
3738
* @author Michael Minella
39+
* @author Mahmoud Ben Hassine
3840
*/
3941
public class StaxEventItemReaderBuilderTests {
4042

@@ -95,6 +97,7 @@ public void testConfiguration() throws Exception {
9597
.currentItemCount(1)
9698
.maxItemCount(2)
9799
.unmarshaller(unmarshaller)
100+
.xmlInputFactory(XMLInputFactory.newInstance())
98101
.build();
99102

100103
reader.afterPropertiesSet();

spring-batch-infrastructure/src/test/java/org/springframework/batch/item/xml/stax/DefaultFragmentEventReaderTests.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2012 the original author or authors.
2+
* Copyright 2008-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,20 +18,21 @@
1818
import java.util.NoSuchElementException;
1919

2020
import javax.xml.stream.XMLEventReader;
21-
import javax.xml.stream.XMLInputFactory;
2221
import javax.xml.stream.XMLStreamException;
2322
import javax.xml.stream.events.XMLEvent;
2423

2524
import junit.framework.TestCase;
2625

2726
import org.springframework.batch.item.xml.EventHelper;
27+
import org.springframework.batch.item.xml.StaxUtils;
2828
import org.springframework.core.io.ByteArrayResource;
2929
import org.springframework.core.io.Resource;
3030

3131
/**
3232
* Tests for {@link DefaultFragmentEventReader}.
3333
*
3434
* @author Robert Kasanicky
35+
* @author Mahmoud Ben Hassine
3536
*/
3637
public class DefaultFragmentEventReaderTests extends TestCase {
3738

@@ -50,7 +51,7 @@ public class DefaultFragmentEventReaderTests extends TestCase {
5051
@Override
5152
protected void setUp() throws Exception {
5253
Resource input = new ByteArrayResource(xml.getBytes());
53-
eventReader = XMLInputFactory.newInstance().createXMLEventReader(
54+
eventReader = StaxUtils.createXmlInputFactory().createXMLEventReader(
5455
input.getInputStream());
5556
fragmentReader = new DefaultFragmentEventReader(eventReader);
5657
}

0 commit comments

Comments
 (0)