Skip to content

Commit 57f9344

Browse files
committed
Merge #555 from remote-tracking branch 'origin/554-addParameterToSetMaxEntities'
2 parents 9a73d3c + f0a618a commit 57f9344

File tree

2 files changed

+91
-12
lines changed

2 files changed

+91
-12
lines changed

metafacture-xml/src/main/java/org/metafacture/xml/XmlDecoder.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,41 +41,54 @@
4141
* @author Christoph Böhme
4242
*
4343
*/
44-
@Description("Reads an XML file and passes the XML events to a receiver.")
44+
@Description("Reads an XML file and passes the XML events to a receiver. Set `totalEntitySizeLimit=\"0\"` to allow unlimited XML entities.")
4545
@In(Reader.class)
4646
@Out(XmlReceiver.class)
4747
@FluxCommand("decode-xml")
4848
public final class XmlDecoder extends DefaultObjectPipe<Reader, XmlReceiver> {
4949

5050
private static final String SAX_PROPERTY_LEXICAL_HANDLER = "http://xml.org/sax/properties/lexical-handler";
51-
51+
private static final String TOTAL_ENTITY_SIZE_LIMIT = "http://www.oracle.com/xml/jaxp/properties/totalEntitySizeLimit";
5252
private final XMLReader saxReader;
5353

5454
/**
55-
* Constructs an XmlDecoder by obtaining a new instance of an
55+
* Creates an instance of {@link XmlDecoder} by obtaining a new instance of an
5656
* {@link org.xml.sax.XMLReader}.
5757
*/
5858
public XmlDecoder() {
5959
try {
6060
final SAXParserFactory parserFactory = SAXParserFactory.newInstance();
6161
parserFactory.setNamespaceAware(true);
62-
6362
saxReader = parserFactory.newSAXParser().getXMLReader();
6463
}
6564
catch (final ParserConfigurationException | SAXException e) {
6665
throw new MetafactureException(e);
6766
}
6867
}
6968

69+
/**
70+
* Sets the total entity size limit for the XML parser.
71+
* See <a href="https://docs.oracle.com/en/java/javase/13/security/java-api-xml-processing-jaxp-security-guide.html#GUID-82F8C206-F2DF-4204-9544-F96155B1D258__TABLE_RQ1_3PY_HHB">java-api-xml-processing-jaxp-security-guide.html</a>
72+
*
73+
* Defaults to "50,000,000". Set to "0" to allow unlimited entities.
74+
*
75+
* @param totalEntitySizeLimit the size of the allowed entities. Set to "0" if entities should be unlimited.
76+
*/
77+
public void setTotalEntitySizeLimit(final String totalEntitySizeLimit) {
78+
try {
79+
saxReader.setProperty(TOTAL_ENTITY_SIZE_LIMIT, totalEntitySizeLimit);
80+
}
81+
catch (final SAXException e) {
82+
throw new MetafactureException(e);
83+
}
84+
}
85+
7086
@Override
7187
public void process(final Reader reader) {
7288
try {
7389
saxReader.parse(new InputSource(reader));
7490
}
75-
catch (final IOException e) {
76-
throw new MetafactureException(e);
77-
}
78-
catch (final SAXException e) {
91+
catch (final IOException | SAXException e) {
7992
throw new MetafactureException(e);
8093
}
8194
}
@@ -89,10 +102,7 @@ protected void onSetReceiver() {
89102
try {
90103
saxReader.setProperty(SAX_PROPERTY_LEXICAL_HANDLER, getReceiver());
91104
}
92-
catch (final SAXNotRecognizedException e) {
93-
throw new MetafactureException(e);
94-
}
95-
catch (final SAXNotSupportedException e) {
105+
catch (final SAXNotRecognizedException | SAXNotSupportedException e) {
96106
throw new MetafactureException(e);
97107
}
98108
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2024 Pascal Christoph (hbz)
3+
*
4+
* Licensed under the Apache License, Version 2.0 the "License";
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.metafacture.xml;
18+
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.metafacture.framework.MetafactureException;
22+
23+
import java.io.IOException;
24+
import java.io.Reader;
25+
import java.io.StringReader;
26+
27+
/**
28+
* Tests for class {@link XmlDecoder}.
29+
*
30+
* @author Pascal Christoph (dr0i)
31+
*/
32+
public final class XmlDecoderTest {
33+
34+
private final String TEST_XML_WITH_TWO_ENTITIES = "<record>&gt;&gt;</record>";
35+
private XmlDecoder xmlDecoder;
36+
private final Reader reader = new StringReader(TEST_XML_WITH_TWO_ENTITIES);
37+
38+
@Before
39+
public void initSystemUnderTest() {
40+
xmlDecoder = new XmlDecoder();
41+
}
42+
43+
@Test
44+
public void issue554_default() {
45+
process(xmlDecoder);
46+
}
47+
48+
@Test(expected = MetafactureException.class)
49+
public void issue554_shouldFail() {
50+
xmlDecoder.setTotalEntitySizeLimit("1");
51+
process(xmlDecoder);
52+
}
53+
54+
@Test
55+
public void issue554_unlimitedEntities() {
56+
xmlDecoder.setTotalEntitySizeLimit("0");
57+
process(xmlDecoder);
58+
}
59+
60+
private void process(XmlDecoder xmlDecoder) {
61+
try {
62+
xmlDecoder.process(reader);
63+
reader.close();
64+
}
65+
catch (IOException e) {
66+
throw new RuntimeException(e);
67+
}
68+
}
69+
}

0 commit comments

Comments
 (0)