From a02fcfbb064daa85f5367ba0dbf5a14246c294af Mon Sep 17 00:00:00 2001 From: Juan Moreno Date: Mon, 5 Aug 2019 19:35:34 -0300 Subject: [PATCH] UPDATE Added additional tests, security config, and fix format issues (#7421) --- .../xml/attribute/Dom4jTransformer.java | 6 ++- .../xml/attribute/JaxpTransformer.java | 17 +++---- .../xml/attribute/jmh/AttributeBenchMark.java | 47 ++++++++++--------- .../xml/attribute/Dom4jProcessorUnitTest.java | 41 ++++++++++------ .../xml/attribute/JaxpProcessorUnitTest.java | 14 ++++++ .../xml/attribute/JooxProcessorUnitTest.java | 38 ++++++++++----- xml/src/test/resources/xml/xee_attribute.xml | 9 ++++ 7 files changed, 116 insertions(+), 56 deletions(-) create mode 100644 xml/src/test/resources/xml/xee_attribute.xml diff --git a/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java b/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java index a1922ad224..d4fdeb0d58 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/Dom4jTransformer.java @@ -3,6 +3,7 @@ package com.baeldung.xml.attribute; import org.dom4j.*; import org.dom4j.io.DocumentSource; import org.dom4j.io.SAXReader; +import org.xml.sax.SAXException; import javax.xml.XMLConstants; import javax.xml.transform.OutputKeys; @@ -17,9 +18,12 @@ import java.util.List; public class Dom4jTransformer { private final Document input; - public Dom4jTransformer(String resourcePath) throws DocumentException { + public Dom4jTransformer(String resourcePath) throws DocumentException, SAXException { // 1- Build the doc from the XML file SAXReader xmlReader = new SAXReader(); + xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); + xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); this.input = xmlReader.read(resourcePath); } diff --git a/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java b/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java index a2266a2b44..a55b00950c 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/JaxpTransformer.java @@ -32,7 +32,8 @@ public class JaxpTransformer { // 1- Build the doc from the XML file DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - input = factory.newDocumentBuilder() + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + this.input = factory.newDocumentBuilder() .parse(resourcePath); } @@ -40,24 +41,24 @@ public class JaxpTransformer { // 2- Locate the node(s) with xpath XPath xpath = XPathFactory.newInstance() .newXPath(); - NodeList nodes = (NodeList) xpath.evaluate(String.format("//*[contains(@%s, '%s')]", attribute, oldValue), input, XPathConstants.NODESET); + NodeList nodes = (NodeList) xpath.evaluate(String.format("//*[contains(@%s, '%s')]", attribute, oldValue), this.input, XPathConstants.NODESET); // 3- Make the change on the selected nodes for (int i = 0; i < nodes.getLength(); i++) { Element value = (Element) nodes.item(i); value.setAttribute(attribute, newValue); } - //Stream api syntax - // IntStream - // .range(0, nodes.getLength()) - // .mapToObj(i -> (Element) nodes.item(i)) - // .forEach(value -> value.setAttribute(attribute, newValue)); + // Stream api syntax + // IntStream + // .range(0, nodes.getLength()) + // .mapToObj(i -> (Element) nodes.item(i)) + // .forEach(value -> value.setAttribute(attribute, newValue)); // 4- Save the result to a new XML doc TransformerFactory factory = TransformerFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); Transformer xformer = factory.newTransformer(); xformer.setOutputProperty(OutputKeys.INDENT, "yes"); Writer output = new StringWriter(); - xformer.transform(new DOMSource(input), new StreamResult(output)); + xformer.transform(new DOMSource(this.input), new StreamResult(output)); return output.toString(); } } diff --git a/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java b/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java index 064e181713..f5f3a2ce6c 100644 --- a/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java +++ b/xml/src/main/java/com/baeldung/xml/attribute/jmh/AttributeBenchMark.java @@ -1,7 +1,19 @@ package com.baeldung.xml.attribute.jmh; +import java.io.IOException; +import java.util.concurrent.TimeUnit; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.xpath.XPathExpressionException; + import org.dom4j.DocumentException; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; @@ -12,30 +24,23 @@ import com.baeldung.xml.attribute.Dom4jTransformer; import com.baeldung.xml.attribute.JaxpTransformer; import com.baeldung.xml.attribute.JooxTransformer; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.xpath.XPathExpressionException; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) @State(Scope.Benchmark) public class AttributeBenchMark { public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include(AttributeBenchMark.class.getSimpleName()) - .forks(1) - .build(); + Options opt = new OptionsBuilder().include(AttributeBenchMark.class.getSimpleName()) + .forks(1) + .build(); new Runner(opt).run(); } @Benchmark - public String dom4jBenchmark() throws DocumentException, TransformerException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public String dom4jBenchmark() throws DocumentException, TransformerException, SAXException { + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -46,9 +51,9 @@ public class AttributeBenchMark { @Benchmark public String jooxBenchmark() throws IOException, SAXException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -59,9 +64,9 @@ public class AttributeBenchMark { @Benchmark public String jaxpBenchmark() throws TransformerException, ParserConfigurationException, SAXException, IOException, XPathExpressionException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = this.getClass() + .getResource("/xml/attribute.xml") + .toString(); JaxpTransformer transformer = new JaxpTransformer(path); String attribute = "customer"; String oldValue = "true"; diff --git a/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java index 485744f9a5..351b8bc437 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/Dom4jProcessorUnitTest.java @@ -2,14 +2,19 @@ package com.baeldung.xml.attribute; import org.dom4j.DocumentException; import org.junit.jupiter.api.Test; +import org.xml.sax.SAXException; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPathExpressionException; + import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; /** @@ -18,10 +23,9 @@ import static org.xmlunit.assertj.XmlAssert.assertThat; public class Dom4jProcessorUnitTest { @Test - public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws TransformerFactoryConfigurationError, TransformerException, DocumentException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws TransformerFactoryConfigurationError, TransformerException, DocumentException, SAXException { + String path = getClass().getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -33,23 +37,32 @@ public class Dom4jProcessorUnitTest { } @Test - public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, TransformerException, URISyntaxException, DocumentException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, TransformerException, URISyntaxException, DocumentException, SAXException { + String path = getClass().getResource("/xml/attribute.xml") + .toString(); Dom4jTransformer transformer = new Dom4jTransformer(path); String attribute = "customer"; String oldValue = "true"; String newValue = "false"; - String expectedXml = new String(Files.readAllBytes((Paths.get(getClass() - .getResource("/xml/attribute_expected.xml") - .toURI())))); + String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml") + .toURI())))); String result = transformer.modifyAttribute(attribute, oldValue, newValue); - assertThat(result) - .and(expectedXml) - .areSimilar(); + assertThat(result).and(expectedXml) + .areSimilar(); + } + + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new Dom4jTransformer(path); + + }).isInstanceOf(DocumentException.class); } } diff --git a/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java index 8394016dbd..8d814783e0 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/JaxpProcessorUnitTest.java @@ -1,5 +1,6 @@ package com.baeldung.xml.attribute; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; import java.io.IOException; @@ -11,6 +12,7 @@ import javax.xml.xpath.XPathExpressionException; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; /** * Unit test for {@link JaxpTransformer}. @@ -31,4 +33,16 @@ public class JaxpProcessorUnitTest { assertThat(result).hasXPath("//*[contains(@customer, 'false')]"); } + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new JaxpTransformer(path); + + }).isInstanceOf(SAXParseException.class); + } + } diff --git a/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java b/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java index 38c7c59789..40d0c671e7 100644 --- a/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java +++ b/xml/src/test/java/com/baeldung/xml/attribute/JooxProcessorUnitTest.java @@ -2,13 +2,19 @@ package com.baeldung.xml.attribute; import org.junit.jupiter.api.Test; import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.xpath.XPathExpressionException; + import java.io.IOException; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.xmlunit.assertj.XmlAssert.assertThat; /** @@ -18,9 +24,8 @@ public class JooxProcessorUnitTest { @Test public void givenXmlWithAttributes_whenModifyAttribute_thenGetXmlUpdated() throws IOException, SAXException, TransformerFactoryConfigurationError { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = getClass().getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; @@ -33,22 +38,31 @@ public class JooxProcessorUnitTest { @Test public void givenTwoXml_whenModifyAttribute_thenGetSimilarXml() throws IOException, TransformerFactoryConfigurationError, URISyntaxException, SAXException { - String path = getClass() - .getResource("/xml/attribute.xml") - .toString(); + String path = getClass().getResource("/xml/attribute.xml") + .toString(); JooxTransformer transformer = new JooxTransformer(path); String attribute = "customer"; String oldValue = "true"; String newValue = "false"; - String expectedXml = new String(Files.readAllBytes((Paths.get(getClass() - .getResource("/xml/attribute_expected.xml") - .toURI())))); + String expectedXml = new String(Files.readAllBytes((Paths.get(getClass().getResource("/xml/attribute_expected.xml") + .toURI())))); String result = transformer.modifyAttribute(attribute, oldValue, newValue); - assertThat(result) - .and(expectedXml) - .areSimilar(); + assertThat(result).and(expectedXml) + .areSimilar(); + } + + @Test + public void givenXmlXee_whenInit_thenThrowException() throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, TransformerFactoryConfigurationError, TransformerException { + String path = getClass().getResource("/xml/xee_attribute.xml") + .toString(); + + assertThatThrownBy(() -> { + + new JooxTransformer(path); + + }).isInstanceOf(SAXParseException.class); } } diff --git a/xml/src/test/resources/xml/xee_attribute.xml b/xml/src/test/resources/xml/xee_attribute.xml new file mode 100644 index 0000000000..9633ca15b0 --- /dev/null +++ b/xml/src/test/resources/xml/xee_attribute.xml @@ -0,0 +1,9 @@ + + ]> + + &xxe; + + john@email.com + mary@email.com + \ No newline at end of file