Skip to content

Commit 9610100

Browse files
committed
Support trailing comment in DTD declaration in XML config
Prior to this commit, Spring failed to determine that an XML config file was DTD-based if the DTD declaration was followed by a comment. This commit fixes this by modifying the consumeCommentTokens(String) algorithm in XmlValidationModeDetector so that both leading and trailing comments are properly consumed without losing any XML content. Closes gh-23605
1 parent a7aecbb commit 9610100

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

spring-core/src/main/java/org/springframework/util/xml/XmlValidationModeDetector.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-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.
@@ -30,6 +30,7 @@
3030
*
3131
* @author Rob Harrop
3232
* @author Juergen Hoeller
33+
* @author Sam Brannen
3334
* @since 2.0
3435
*/
3536
public class XmlValidationModeDetector {
@@ -142,20 +143,27 @@ private boolean hasOpeningTag(String content) {
142143
}
143144

144145
/**
145-
* Consumes all the leading comment data in the given String and returns the remaining content, which
146-
* may be empty since the supplied content might be all comment data. For our purposes it is only important
147-
* to strip leading comment content on a line since the first piece of non comment content will be either
148-
* the DOCTYPE declaration or the root element of the document.
146+
* Consume all leading and trailing comments in the given String and return
147+
* the remaining content, which may be empty since the supplied content might
148+
* be all comment data.
149149
*/
150150
@Nullable
151151
private String consumeCommentTokens(String line) {
152-
if (!line.contains(START_COMMENT) && !line.contains(END_COMMENT)) {
152+
int indexOfStartComment = line.indexOf(START_COMMENT);
153+
if (indexOfStartComment == -1 && !line.contains(END_COMMENT)) {
153154
return line;
154155
}
156+
157+
String result = "";
155158
String currLine = line;
159+
if (indexOfStartComment >= 0) {
160+
result = line.substring(0, indexOfStartComment);
161+
currLine = line.substring(indexOfStartComment);
162+
}
163+
156164
while ((currLine = consume(currLine)) != null) {
157165
if (!this.inComment && !currLine.trim().startsWith(START_COMMENT)) {
158-
return currLine;
166+
return result + currLine;
159167
}
160168
}
161169
return null;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2002-2019 the original author or authors.
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+
* https://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.springframework.util.xml;
18+
19+
import java.io.InputStream;
20+
21+
import org.junit.Test;
22+
23+
import static org.junit.Assert.assertEquals;
24+
import static org.springframework.util.xml.XmlValidationModeDetector.VALIDATION_DTD;
25+
26+
/**
27+
* Unit tests for {@link XmlValidationModeDetector}.
28+
*
29+
* @author Sam Brannen
30+
* @since 5.1.10
31+
*/
32+
public class XmlValidationModeDetectorTests {
33+
34+
private final XmlValidationModeDetector xmlValidationModeDetector = new XmlValidationModeDetector();
35+
36+
37+
@Test
38+
public void dtdWithTrailingComment() throws Exception {
39+
dtdDetection("dtdWithTrailingComment.xml");
40+
}
41+
42+
@Test
43+
public void dtdWithLeadingComment() throws Exception {
44+
dtdDetection("dtdWithLeadingComment.xml");
45+
}
46+
47+
@Test
48+
public void dtdWithCommentOnNextLine() throws Exception {
49+
dtdDetection("dtdWithCommentOnNextLine.xml");
50+
}
51+
52+
@Test
53+
public void dtdWithMultipleComments() throws Exception {
54+
dtdDetection("dtdWithMultipleComments.xml");
55+
}
56+
57+
private void dtdDetection(String fileName) throws Exception {
58+
InputStream inputStream = getClass().getResourceAsStream(fileName);
59+
assertEquals(VALIDATION_DTD, xmlValidationModeDetector.detectValidationMode(inputStream));
60+
}
61+
62+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
3+
<!-- comment on next line -->
4+
5+
<beans>
6+
7+
</beans>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- leading comment --><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">
3+
4+
<beans>
5+
6+
</beans>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- comment #1 --> <!-- comment #2 --> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"><!--
3+
trailing
4+
comment
5+
-->
6+
7+
<beans>
8+
9+
</beans>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd"><!-- trailing comment -->
3+
4+
<beans>
5+
6+
</beans>

0 commit comments

Comments
 (0)