From eba3e39a0d4c6e55295b565511873f81a751dde2 Mon Sep 17 00:00:00 2001 From: Jonathan Hedley Date: Sat, 14 Aug 2021 14:32:34 +1000 Subject: [PATCH] Fix an IOOB when HTML root cleared and then attributes added Fixes #1611 --- CHANGES | 3 +++ .../org/jsoup/parser/HtmlTreeBuilderState.java | 15 +++++++++------ .../org/jsoup/integration/FuzzFixesTest.java | 12 ++++++++++++ src/test/resources/fuzztests/1611.html.gz | Bin 0 -> 817 bytes 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/fuzztests/1611.html.gz diff --git a/CHANGES b/CHANGES index 638ca4a369..26522f4c70 100644 --- a/CHANGES +++ b/CHANGES @@ -74,6 +74,9 @@ jsoup changelog * Bugfix [Fuzz]: Fix a potential stack-overflow in the parser given crafted HTML, when the parser looped in the InSelectInTable state. + * Bugfix [Fuzz]: Fix an IOOB when the HTML root was cleared from the stack and then attributes were merged onto it. + + *** Release 1.14.1 [2021-Jul-10] * Change: updated the minimum supported Java version from Java 7 to Java 8. diff --git a/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java b/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java index e932a4a88b..7f63ea2dab 100644 --- a/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java +++ b/src/main/java/org/jsoup/parser/HtmlTreeBuilderState.java @@ -340,12 +340,15 @@ private boolean inBodyStartTag(Token t, HtmlTreeBuilder tb) { break; case "html": tb.error(this); - // merge attributes onto real html - Element html = tb.getStack().get(0); - if (startTag.hasAttributes()) { - for (Attribute attribute : startTag.attributes) { - if (!html.hasAttr(attribute.getKey())) - html.attributes().put(attribute); + // merge attributes onto real html (if present) + stack = tb.getStack(); + if (stack.size() > 0) { + Element html = tb.getStack().get(0); + if (startTag.hasAttributes()) { + for (Attribute attribute : startTag.attributes) { + if (!html.hasAttr(attribute.getKey())) + html.attributes().put(attribute); + } } } break; diff --git a/src/test/java/org/jsoup/integration/FuzzFixesTest.java b/src/test/java/org/jsoup/integration/FuzzFixesTest.java index c203b1f79c..5d7bcc8576 100644 --- a/src/test/java/org/jsoup/integration/FuzzFixesTest.java +++ b/src/test/java/org/jsoup/integration/FuzzFixesTest.java @@ -193,4 +193,16 @@ public void overflow1607() throws IOException { Document docXml = Jsoup.parse(new FileInputStream(in), "UTF-8", "https://example.com", Parser.xmlParser()); assertNotNull(docXml); } + + @Test + public void oob() throws IOException { + // https://github.com/jhy/jsoup/issues/1611 + File in = ParseTest.getFile("/fuzztests/1611.html.gz"); + + Document doc = Jsoup.parse(in, "UTF-8"); + assertNotNull(doc); + + Document docXml = Jsoup.parse(new FileInputStream(in), "UTF-8", "https://example.com", Parser.xmlParser()); + assertNotNull(docXml); + } } diff --git a/src/test/resources/fuzztests/1611.html.gz b/src/test/resources/fuzztests/1611.html.gz new file mode 100644 index 0000000000000000000000000000000000000000..90215d0a84846de1b61ba9473cd61debd96f4a75 GIT binary patch literal 817 zcmV-11J3*(iwFq%L>FNI3o$k^F)nCyZEOJT7qM>BK-3jwV~F^Ipg=05APa#CQeRFo zLcbz>cq~35DIs`xV4?wq@jgY zr)Hc!Ch zZ$LmL;xQ1+Yf@~+J_k=AxJw3%(4CL!hFYQE6oK%QeiprbRlxae;A-YAFhNC4w;5RI zaBQPaG!>Z^@SDeHHmf15U4(N5rG~3brj*Y3t3EOZ47IuTSt$kGk^xp`Rb81B zu#PrM$UIP8P<1!f%P(!Xywi}ra zo^&jthMxZE<*d%qqMJ4$>R1ypdfvvHkpBiJ_GfH2w;*kwmxd%C!^~h^=9aUQ1iFnS zkC`kkT@JZ78@-L8Htj^6r_jo?_3wO&_hp&MY2QKNpO&r|O&0wG3}qPWN~9v&zt0~0 zUMYahi>xR;L)7jh)p+&!2(8n-xy6tVtXhm35vyeD!{cpnipj%_6boN=K(M01 znH%;4;puLN0)-i<{v7vInI^4&ji*T~S*A&AnzRlIV%Q`cegF%Sphp|NO_9l4z`zv( zl148Fr1|F|*MMN&YJvvh6(D&&KxkT=p#y=I=bhIbx|k$SikobKv4tXImlO?<3inDt zd;C%(;u~1vCbV~DfGXe%@f{C8B7(pPj)(f6h z84}rz!!(OTc5tQ%FU?H#V0Pj}*KC%M+GF7^Xh=Rb*$`mN(JgMV{v)sC%a6RvvQ vM%Q#}E&q@ftlN;;HRmJsFwJ1f^3CN&n$7XL=KzhB(WZX^efBe?;}ie@h?0w7 literal 0 HcmV?d00001