Skip to content

Commit c4bf5ba

Browse files
committed
Fix IOOB on crafted fragment input
1 parent 62d042a commit c4bf5ba

File tree

3 files changed

+9
-3
lines changed

3 files changed

+9
-3
lines changed

CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
### Improvements
66
* Added an instance method `Parser#unescape(String, boolean)` that unescapes HTML entities using the parser’s configuration (e.g. to support error tracking), complementing the existing static utility `Parser.unescapeEntities(String, boolean)`. [#2396](https://github.com/jhy/jsoup/pull/2396)
77
* Build: added CI coverage for JDK 25 [#2403](https://github.com/jhy/jsoup/pull/2403)
8+
* Build: added a CI fuzzer for contextual fragment parsing (in addition to existing full body HTML and XML fuzzers). [oss-fuzz #14041](https://github.com/google/oss-fuzz/pull/14041)
89

910
### Bug Fixes
1011
* Previously cached child Elements of an Element were not correctly invalidated in `Node#replaceWith(Node)`, which could lead to incorrect results when subsequently calling `Element#children()`. [#2391](https://github.com/jhy/jsoup/issues/2391)
1112
* Attribute selector values are now compared literally without trimming. Previously, jsoup trimmed whitespace from selector values and from element attribute values, which could cause mismatches with browser behavior (e.g. `[attr=" foo "]`). Now matches align with the CSS specification and browser engines. [#2380](https://github.com/jhy/jsoup/issues/2380)
1213
* When using the JDK HttpClient, any system default proxy (`ProxySelector.getDefault()`) was ignored. Now, the system proxy is used if a per-request proxy is not set. [#2388](https://github.com/jhy/jsoup/issues/2388), [#2390](https://github.com/jhy/jsoup/pull/2390)
1314
* A ValidationException could be thrown in the adoption agency algorithm with particularly broken input. Now logged as a parse error. [#2393](https://github.com/jhy/jsoup/issues/2393)
1415
* Null characters in the HTML body were not consistently removed; and in foreign content were not correctly replaced. [#2395](https://github.com/jhy/jsoup/issues/2395)
15-
* An IndexOutOfBoundsException could be thrown when parsing a body fragment with crafted input. Now logged as a parse error. [#2397](https://github.com/jhy/jsoup/issues/2397)
16+
* An IndexOutOfBoundsException could be thrown when parsing a body fragment with crafted input. Now logged as a parse error. [#2397](https://github.com/jhy/jsoup/issues/2397), [#2406](https://github.com/jhy/jsoup/issues/2406)
1617

1718

1819
## 1.21.2 (2025-Aug-25)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ private boolean inBodyStartTag(Token t, HtmlTreeBuilder tb) {
379379
case "body":
380380
tb.error(this);
381381
stack = tb.getStack();
382-
if (stack.size() == 1 || (stack.size() > 2 && !stack.get(1).nameIs("body")) || tb.onStack("template")) {
382+
if (stack.size() < 2 || (stack.size() > 2 && !stack.get(1).nameIs("body")) || tb.onStack("template")) {
383383
// only in fragment case
384384
return false; // ignore
385385
} else {
@@ -392,7 +392,7 @@ private boolean inBodyStartTag(Token t, HtmlTreeBuilder tb) {
392392
case "frameset":
393393
tb.error(this);
394394
stack = tb.getStack();
395-
if (stack.size() == 1 || (stack.size() > 2 && !stack.get(1).nameIs("body"))) {
395+
if (stack.size() < 2|| (stack.size() > 2 && !stack.get(1).nameIs("body"))) {
396396
// only in fragment case
397397
return false; // ignore
398398
} else if (!tb.framesetOk()) {

src/test/java/org/jsoup/integration/FuzzFixesTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.jsoup.Jsoup;
44
import org.jsoup.nodes.Document;
5+
import org.jsoup.nodes.Element;
56
import org.jsoup.parser.Parser;
67
import org.junit.jupiter.api.Test;
78
import org.junit.jupiter.params.ParameterizedTest;
@@ -47,6 +48,10 @@ public void bookmark() {
4748
assertNotNull(xmlDoc);
4849
}
4950

51+
@Test void fragment() {
52+
Parser.htmlParser().parseFragmentInput("<frameset>>l\u0000<\u0000<ditl>\u0000< \\", new Element("colgroup"), "");
53+
}
54+
5055
@ParameterizedTest
5156
@MethodSource("testFiles")
5257
void testHtmlParse(File file) throws IOException {

0 commit comments

Comments
 (0)