Skip to content

Commit c793018

Browse files
committed
Tweak XmlInputFactory settings
1 parent 6e51738 commit c793018

File tree

5 files changed

+76
-13
lines changed

5 files changed

+76
-13
lines changed

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

+6-2
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

+14-2
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.
@@ -53,6 +53,7 @@
5353
* The implementation is <b>not</b> thread-safe.
5454
*
5555
* @author Robert Kasanicky
56+
* @author Mahmoud Ben Hassine
5657
*/
5758
public class StaxEventItemReader<T> extends AbstractItemCountingItemStreamItemReader<T> implements
5859
ResourceAwareItemReaderItemStream<T>, InitializingBean {
@@ -75,6 +76,8 @@ public class StaxEventItemReader<T> extends AbstractItemCountingItemStreamItemRe
7576

7677
private boolean strict = true;
7778

79+
private XMLInputFactory xmlInputFactory = StaxUtils.createXmlInputFactory();
80+
7881
public StaxEventItemReader() {
7982
setName(ClassUtils.getShortName(StaxEventItemReader.class));
8083
}
@@ -117,6 +120,15 @@ public void setFragmentRootElementNames(String[] fragmentRootElementNames) {
117120
}
118121
}
119122

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

207219
inputStream = resource.getInputStream();
208-
eventReader = XMLInputFactory.newInstance().createXMLEventReader(inputStream);
220+
eventReader = xmlInputFactory.createXMLEventReader(inputStream);
209221
fragmentReader = new DefaultFragmentEventReader(eventReader);
210222
noInput = false;
211223

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

+10-1
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.
@@ -23,6 +23,7 @@
2323

2424
import javax.xml.stream.XMLEventReader;
2525
import javax.xml.stream.XMLEventWriter;
26+
import javax.xml.stream.XMLInputFactory;
2627
import javax.xml.transform.Result;
2728
import javax.xml.transform.Source;
2829
import java.lang.reflect.Constructor;
@@ -38,6 +39,7 @@
3839
* As the only class state maintained is to cache java reflection metadata, which is thread-safe, this class is thread-safe.
3940
*
4041
* @author Josh Long
42+
* @author Mahmoud Ben Hassine
4143
*
4244
*/
4345
public abstract class StaxUtils {
@@ -142,4 +144,11 @@ public static XMLEventReader getXmlEventReader(Source s) throws Exception {
142144
m.setAccessible(accessible);
143145
return (XMLEventReader) result;
144146
}
147+
148+
public static XMLInputFactory createXmlInputFactory() {
149+
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
150+
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
151+
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
152+
return xmlInputFactory;
153+
}
145154
}

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

+42-5
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 = StaxUtils.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"));
614+
}
615+
}
616+
580617
/**
581618
* Stub emulating problems during unmarshalling.
582619
*/

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

+4-3
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)