From a820dbeac29d330bae4be05d9ecd939ad6b4aa33 Mon Sep 17 00:00:00 2001
From: Pranjal Jumde <pjumde@apple.com>
Date: Tue, 1 Mar 2016 11:34:04 -0800
Subject: [PATCH] Bug 758605: Heap-based buffer overread in xmlDictAddString
 <https://bugzilla.gnome.org/show_bug.cgi?id=758605>

Reviewed by David Kilzer.

* HTMLparser.c:
(htmlParseName): Add bounds check.
(htmlParseNameComplex): Ditto.
* result/HTML/758605.html: Added.
* result/HTML/758605.html.err: Added.
* result/HTML/758605.html.sax: Added.
* runtest.c:
(pushParseTest): The input for the new test case was so small
(4 bytes) that htmlParseChunk() was never called after
htmlCreatePushParserCtxt(), thereby creating a false positive
test failure.  Fixed by using a do-while loop so we always call
htmlParseChunk() at least once.
* test/HTML/758605.html: Added.

Upstream-Status: Backport
CVE: CVE-2016-1839

Signed-off-by: Armin Kuster <akuster@mvista.com>
---
 HTMLparser.c                |  8 ++++++++
 result/HTML/758605.html     |  3 +++
 result/HTML/758605.html.err |  3 +++
 result/HTML/758605.html.sax | 13 +++++++++++++
 runtest.c                   |  4 ++--
 test/HTML/758605.html       |  1 +
 6 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 result/HTML/758605.html
 create mode 100644 result/HTML/758605.html.err
 create mode 100644 result/HTML/758605.html.sax
 create mode 100644 test/HTML/758605.html

Index: libxml2-2.9.2/HTMLparser.c
===================================================================
--- libxml2-2.9.2.orig/HTMLparser.c
+++ libxml2-2.9.2/HTMLparser.c
@@ -2471,6 +2471,10 @@ htmlParseName(htmlParserCtxtPtr ctxt) {
 	       (*in == '_') || (*in == '-') ||
 	       (*in == ':') || (*in == '.'))
 	    in++;
+
+	if (in == ctxt->input->end)
+	    return(NULL);
+
 	if ((*in > 0) && (*in < 0x80)) {
 	    count = in - ctxt->input->cur;
 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
@@ -2514,6 +2518,10 @@ htmlParseNameComplex(xmlParserCtxtPtr ct
 	NEXTL(l);
 	c = CUR_CHAR(l);
     }
+
+    if (ctxt->input->base > ctxt->input->cur - len)
+	return(NULL);
+
     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 }
 
Index: libxml2-2.9.2/result/HTML/758605.html
===================================================================
--- /dev/null
+++ libxml2-2.9.2/result/HTML/758605.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html><body><p>&amp;
+</p></body></html>
Index: libxml2-2.9.2/result/HTML/758605.html.err
===================================================================
--- /dev/null
+++ libxml2-2.9.2/result/HTML/758605.html.err
@@ -0,0 +1,3 @@
+./test/HTML/758605.html:1: HTML parser error : htmlParseEntityRef: no name
+Ãª
+  ^
Index: libxml2-2.9.2/result/HTML/758605.html.sax
===================================================================
--- /dev/null
+++ libxml2-2.9.2/result/HTML/758605.html.sax
@@ -0,0 +1,13 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.error: htmlParseEntityRef: no name
+SAX.startElement(html)
+SAX.startElement(body)
+SAX.startElement(p)
+SAX.characters(&amp;, 1)
+SAX.ignorableWhitespace(
+, 1)
+SAX.endElement(p)
+SAX.endElement(body)
+SAX.endElement(html)
+SAX.endDocument()
Index: libxml2-2.9.2/runtest.c
===================================================================
--- libxml2-2.9.2.orig/runtest.c
+++ libxml2-2.9.2/runtest.c
@@ -1827,7 +1827,7 @@ pushParseTest(const char *filename, cons
     ctxt = xmlCreatePushParserCtxt(NULL, NULL, base + cur, 4, filename);
     xmlCtxtUseOptions(ctxt, options);
     cur += 4;
-    while (cur < size) {
+    do {
         if (cur + 1024 >= size) {
 #ifdef LIBXML_HTML_ENABLED
 	    if (options & XML_PARSE_HTML)
@@ -1845,7 +1845,7 @@ pushParseTest(const char *filename, cons
 	    xmlParseChunk(ctxt, base + cur, 1024, 0);
 	    cur += 1024;
 	}
-    }
+    } while (cur < size);
     doc = ctxt->myDoc;
 #ifdef LIBXML_HTML_ENABLED
     if (options & XML_PARSE_HTML)
Index: libxml2-2.9.2/test/HTML/758605.html
===================================================================
--- /dev/null
+++ libxml2-2.9.2/test/HTML/758605.html
@@ -0,0 +1 @@
+&:ê
