Skip to content

Commit c32924f

Browse files
committed
Don't emit an error on the ? ending an XML declaration
Fixes #2298
1 parent df34774 commit c32924f

File tree

3 files changed

+22
-0
lines changed

3 files changed

+22
-0
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
gets a declaration of `xmlns:prefix="undefined"`. This allows subsequent serializations to XML via `W3CDom.asString()`
2424
to succeed. [#2087](https://github.com/jhy/jsoup/issues/2087).
2525
* The `StreamParser` could emit the final elements of a document twice, due to how `onNodeCompleted` was fired when closing out the stack. [#2295](https://github.com/jhy/jsoup/issues/2295).
26+
* When parsing with the XML parser and error tracking enabled, the trailing `?` in `<?xml version="1.0"?>` would
27+
incorrectly emit an error. [#2298](https://github.com/jhy/jsoup/issues/2298).
2628

2729
## 1.19.1 (2025-03-04)
2830

src/main/java/org/jsoup/parser/TokeniserState.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jsoup.parser;
22

33
import org.jsoup.nodes.DocumentType;
4+
import org.jsoup.nodes.XmlDeclaration;
45

56
import static org.jsoup.nodes.Document.OutputSettings.Syntax.xml;
67

@@ -891,6 +892,10 @@ private void anythingElse(Tokeniser t, CharacterReader r) {
891892
t.eofError(this);
892893
t.transition(Data);
893894
break;
895+
case '?': // Handle trailing ? in <?xml...?>
896+
if (t.tagPending instanceof Token.XmlDecl)
897+
break;
898+
// otherwise fall through to default
894899
default:
895900
r.unconsume();
896901
t.error(this);

src/test/java/org/jsoup/parser/XmlTreeBuilderTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,4 +394,19 @@ private static void assertXmlNamespace(Element el) {
394394
assertEquals("<val2>", decl.attr("att2"));
395395
}
396396

397+
@Test void xmlHeaderIsValid() {
398+
// https://github.com/jhy/jsoup/issues/2298
399+
String xml = "<?xml version=\"1.0\"?>\n<root></root>";
400+
String expect = xml;
401+
402+
Document doc = Jsoup.parse(xml, Parser.xmlParser().setTrackErrors(10));
403+
assertEquals(0, doc.parser().getErrors().size());
404+
assertEquals(expect, doc.html());
405+
406+
xml = "<?xml version=\"1.0\" ?>\n<root></root>";
407+
doc = Jsoup.parse(xml, Parser.xmlParser().setTrackErrors(10));
408+
assertEquals(0, doc.parser().getErrors().size());
409+
assertEquals(expect, doc.html());
410+
}
411+
397412
}

0 commit comments

Comments
 (0)