Merge branch '5.3.x'
This commit is contained in:
@@ -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,20 +82,22 @@ 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.
|
||||
* <p>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;
|
||||
String content;
|
||||
while ((content = reader.readLine()) != null) {
|
||||
content = consumeCommentTokens(content);
|
||||
if (this.inComment || !StringUtils.hasText(content)) {
|
||||
if (!StringUtils.hasText(content)) {
|
||||
continue;
|
||||
}
|
||||
if (hasDoctype(content)) {
|
||||
@@ -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.
|
||||
* <p>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) {
|
||||
@@ -139,11 +143,10 @@ public class XmlValidationModeDetector {
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume all leading and trailing comments in the given String and return
|
||||
* the remaining content, which may be empty since the supplied content might
|
||||
* be all comment data.
|
||||
* Consume all comments in the given String and return the remaining content,
|
||||
* which may be empty since the supplied content might be all comment data.
|
||||
* <p>This method takes the current "in comment" parsing state into account.
|
||||
*/
|
||||
@Nullable
|
||||
private String consumeCommentTokens(String line) {
|
||||
int indexOfStartComment = line.indexOf(START_COMMENT);
|
||||
if (indexOfStartComment == -1 && !line.contains(END_COMMENT)) {
|
||||
@@ -152,21 +155,19 @@ public class XmlValidationModeDetector {
|
||||
|
||||
String result = "";
|
||||
String currLine = line;
|
||||
if (indexOfStartComment >= 0) {
|
||||
if (!this.inComment && (indexOfStartComment >= 0)) {
|
||||
result = line.substring(0, indexOfStartComment);
|
||||
currLine = line.substring(indexOfStartComment);
|
||||
}
|
||||
|
||||
while ((currLine = consume(currLine)) != null) {
|
||||
if (!this.inComment && !currLine.trim().startsWith(START_COMMENT)) {
|
||||
return result + currLine;
|
||||
}
|
||||
if ((currLine = consume(currLine)) != null) {
|
||||
result += consumeCommentTokens(currLine);
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 +184,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.
|
||||
* <p>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);
|
||||
|
||||
@@ -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;
|
||||
@@ -23,6 +24,7 @@ import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.util.xml.XmlValidationModeDetector.VALIDATION_DTD;
|
||||
import static org.springframework.util.xml.XmlValidationModeDetector.VALIDATION_XSD;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link XmlValidationModeDetector}.
|
||||
@@ -36,11 +38,36 @@ class XmlValidationModeDetectorTests {
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "dtdWithTrailingComment.xml", "dtdWithLeadingComment.xml", "dtdWithCommentOnNextLine.xml",
|
||||
"dtdWithMultipleComments.xml" })
|
||||
@ValueSource(strings = {
|
||||
"dtdWithNoComments.xml",
|
||||
"dtdWithLeadingComment.xml",
|
||||
"dtdWithTrailingComment.xml",
|
||||
"dtdWithTrailingCommentAcrossMultipleLines.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);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"xsdWithNoComments.xml",
|
||||
"xsdWithMultipleComments.xml",
|
||||
"xsdWithDoctypeInComment.xml",
|
||||
"xsdWithDoctypeInOpenCommentWithAdditionalCommentOnSameLine.xml"
|
||||
})
|
||||
void xsdDetection(String fileName) throws Exception {
|
||||
assertValidationMode(fileName, VALIDATION_XSD);
|
||||
}
|
||||
|
||||
|
||||
private void assertValidationMode(String fileName, int expectedValidationMode) throws IOException {
|
||||
try (InputStream inputStream = getClass().getResourceAsStream(fileName)) {
|
||||
assertThat(xmlValidationModeDetector.detectValidationMode(inputStream))
|
||||
.as("Validation Mode")
|
||||
.isEqualTo(expectedValidationMode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"><!-- comment --><beans><!--
|
||||
trailing comment across multiple lines -->
|
||||
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"> -->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"> --> <!-- additional comment on same line -->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- comment #1 --> <!-- comment #2 --> <beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd"><!--
|
||||
trailing
|
||||
comment
|
||||
-->
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user