diff --git a/spring-core/src/main/java/org/springframework/util/xml/XmlValidationModeDetector.java b/spring-core/src/main/java/org/springframework/util/xml/XmlValidationModeDetector.java index 19814c2b83..32e81c6f1f 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/XmlValidationModeDetector.java +++ b/spring-core/src/main/java/org/springframework/util/xml/XmlValidationModeDetector.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2022 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. @@ -58,7 +58,7 @@ public class XmlValidationModeDetector { /** - * The token in a XML document that declares the DTD to use for validation + * The token in an XML document that declares the DTD to use for validation * and thus that DTD validation is being used. */ private static final String DOCTYPE = "DOCTYPE"; @@ -82,13 +82,15 @@ public class XmlValidationModeDetector { /** * Detect the validation mode for the XML document in the supplied {@link InputStream}. - * Note that the supplied {@link InputStream} is closed by this method before returning. + *
Note that the supplied {@link InputStream} is closed by this method before returning. * @param inputStream the InputStream to parse * @throws IOException in case of I/O failure * @see #VALIDATION_DTD * @see #VALIDATION_XSD */ public int detectValidationMode(InputStream inputStream) throws IOException { + this.inComment = false; + // Peek into the file to look for DOCTYPE. try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { boolean isDtdValidated = false; @@ -125,9 +127,11 @@ public class XmlValidationModeDetector { } /** - * Does the supplied content contain an XML opening tag. If the parse state is currently - * in an XML comment then this method always returns false. It is expected that all comment - * tokens will have consumed for the supplied content before passing the remainder to this method. + * Determine if the supplied content contains an XML opening tag. + *
It is expected that all comment tokens will have been consumed for the + * supplied content before passing the remainder to this method. However, as + * a sanity check, if the parse state is currently in an XML comment this + * method always returns {@code false}. */ private boolean hasOpeningTag(String content) { if (this.inComment) { @@ -166,7 +170,7 @@ public class XmlValidationModeDetector { } /** - * Consume the next comment token, update the "inComment" flag + * Consume the next comment token, update the "inComment" flag, * and return the remaining content. */ @Nullable @@ -183,14 +187,19 @@ public class XmlValidationModeDetector { return commentToken(line, START_COMMENT, true); } + /** + * Try to consume the {@link #END_COMMENT} token. + * @see #commentToken(String, String, boolean) + */ private int endComment(String line) { return commentToken(line, END_COMMENT, false); } /** * Try to consume the supplied token against the supplied content and update the - * in comment parse state to the supplied value. Returns the index into the content - * which is after the token or -1 if the token is not found. + * "in comment" parse state to the supplied value. + *
Returns the index into the content which is after the token or -1 if the + * token is not found. */ private int commentToken(String line, String token, boolean inCommentIfPresent) { int index = line.indexOf(token); diff --git a/spring-core/src/test/java/org/springframework/util/xml/XmlValidationModeDetectorTests.java b/spring-core/src/test/java/org/springframework/util/xml/XmlValidationModeDetectorTests.java index 631a61d4f7..5951d29830 100644 --- a/spring-core/src/test/java/org/springframework/util/xml/XmlValidationModeDetectorTests.java +++ b/spring-core/src/test/java/org/springframework/util/xml/XmlValidationModeDetectorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2022 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.util.xml; +import java.io.IOException; import java.io.InputStream; import org.junit.jupiter.params.ParameterizedTest; @@ -39,8 +40,16 @@ class XmlValidationModeDetectorTests { @ValueSource(strings = { "dtdWithTrailingComment.xml", "dtdWithLeadingComment.xml", "dtdWithCommentOnNextLine.xml", "dtdWithMultipleComments.xml" }) void dtdDetection(String fileName) throws Exception { - InputStream inputStream = getClass().getResourceAsStream(fileName); - assertThat(xmlValidationModeDetector.detectValidationMode(inputStream)).isEqualTo(VALIDATION_DTD); + assertValidationMode(fileName, VALIDATION_DTD); + } + + + private void assertValidationMode(String fileName, int expectedValidationMode) throws IOException { + try (InputStream inputStream = getClass().getResourceAsStream(fileName)) { + assertThat(xmlValidationModeDetector.detectValidationMode(inputStream)) + .as("Validation Mode") + .isEqualTo(expectedValidationMode); + } } }