1
1
/*
2
- * Copyright 2002-2020 the original author or authors.
2
+ * Copyright 2002-2022 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -58,7 +58,7 @@ public class XmlValidationModeDetector {
58
58
59
59
60
60
/**
61
- * The token in a XML document that declares the DTD to use for validation
61
+ * The token in an XML document that declares the DTD to use for validation
62
62
* and thus that DTD validation is being used.
63
63
*/
64
64
private static final String DOCTYPE = "DOCTYPE" ;
@@ -82,20 +82,22 @@ public class XmlValidationModeDetector {
82
82
83
83
/**
84
84
* Detect the validation mode for the XML document in the supplied {@link InputStream}.
85
- * Note that the supplied {@link InputStream} is closed by this method before returning.
85
+ * <p> Note that the supplied {@link InputStream} is closed by this method before returning.
86
86
* @param inputStream the InputStream to parse
87
87
* @throws IOException in case of I/O failure
88
88
* @see #VALIDATION_DTD
89
89
* @see #VALIDATION_XSD
90
90
*/
91
91
public int detectValidationMode (InputStream inputStream ) throws IOException {
92
+ this .inComment = false ;
93
+
92
94
// Peek into the file to look for DOCTYPE.
93
95
try (BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream ))) {
94
96
boolean isDtdValidated = false ;
95
97
String content ;
96
98
while ((content = reader .readLine ()) != null ) {
97
99
content = consumeCommentTokens (content );
98
- if (this . inComment || !StringUtils .hasText (content )) {
100
+ if (!StringUtils .hasText (content )) {
99
101
continue ;
100
102
}
101
103
if (hasDoctype (content )) {
@@ -125,9 +127,11 @@ private boolean hasDoctype(String content) {
125
127
}
126
128
127
129
/**
128
- * Does the supplied content contain an XML opening tag. If the parse state is currently
129
- * in an XML comment then this method always returns false. It is expected that all comment
130
- * tokens will have consumed for the supplied content before passing the remainder to this method.
130
+ * Determine if the supplied content contains an XML opening tag.
131
+ * <p>It is expected that all comment tokens will have been consumed for the
132
+ * supplied content before passing the remainder to this method. However, as
133
+ * a sanity check, if the parse state is currently in an XML comment this
134
+ * method always returns {@code false}.
131
135
*/
132
136
private boolean hasOpeningTag (String content ) {
133
137
if (this .inComment ) {
@@ -139,11 +143,10 @@ private boolean hasOpeningTag(String content) {
139
143
}
140
144
141
145
/**
142
- * Consume all leading and trailing comments in the given String and return
143
- * the remaining content, which may be empty since the supplied content might
144
- * be all comment data .
146
+ * Consume all comments in the given String and return the remaining content,
147
+ * which may be empty since the supplied content might be all comment data.
148
+ * <p>This method takes the current "in comment" parsing state into account .
145
149
*/
146
- @ Nullable
147
150
private String consumeCommentTokens (String line ) {
148
151
int indexOfStartComment = line .indexOf (START_COMMENT );
149
152
if (indexOfStartComment == -1 && !line .contains (END_COMMENT )) {
@@ -152,21 +155,19 @@ private String consumeCommentTokens(String line) {
152
155
153
156
String result = "" ;
154
157
String currLine = line ;
155
- if (indexOfStartComment >= 0 ) {
158
+ if (! this . inComment && ( indexOfStartComment >= 0 ) ) {
156
159
result = line .substring (0 , indexOfStartComment );
157
160
currLine = line .substring (indexOfStartComment );
158
161
}
159
162
160
- while ((currLine = consume (currLine )) != null ) {
161
- if (!this .inComment && !currLine .trim ().startsWith (START_COMMENT )) {
162
- return result + currLine ;
163
- }
163
+ if ((currLine = consume (currLine )) != null ) {
164
+ result += consumeCommentTokens (currLine );
164
165
}
165
- return null ;
166
+ return result ;
166
167
}
167
168
168
169
/**
169
- * Consume the next comment token, update the "inComment" flag
170
+ * Consume the next comment token, update the "inComment" flag,
170
171
* and return the remaining content.
171
172
*/
172
173
@ Nullable
@@ -183,14 +184,19 @@ private int startComment(String line) {
183
184
return commentToken (line , START_COMMENT , true );
184
185
}
185
186
187
+ /**
188
+ * Try to consume the {@link #END_COMMENT} token.
189
+ * @see #commentToken(String, String, boolean)
190
+ */
186
191
private int endComment (String line ) {
187
192
return commentToken (line , END_COMMENT , false );
188
193
}
189
194
190
195
/**
191
196
* Try to consume the supplied token against the supplied content and update the
192
- * in comment parse state to the supplied value. Returns the index into the content
193
- * which is after the token or -1 if the token is not found.
197
+ * "in comment" parse state to the supplied value.
198
+ * <p>Returns the index into the content which is after the token or -1 if the
199
+ * token is not found.
194
200
*/
195
201
private int commentToken (String line , String token , boolean inCommentIfPresent ) {
196
202
int index = line .indexOf (token );
0 commit comments