!36 fix problems detected by oss-fuzz test
From: @liquor1 Reviewed-by: @xiezhipeng1 Signed-off-by: @xiezhipeng1
This commit is contained in:
commit
4424750024
@ -0,0 +1,306 @@
|
||||
From 32cb5dccda6d9c72aaa1717d7100277b755cca94 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 11 Feb 2020 13:16:10 +0100
|
||||
Subject: [PATCH] Add test case for recursive external parsed entities
|
||||
|
||||
---
|
||||
result/errors/rec_ext_ent.xml | 5 +
|
||||
result/errors/rec_ext_ent.xml.ent | 243 ++++++++++++++++++++++++++++++
|
||||
result/errors/rec_ext_ent.xml.err | 0
|
||||
result/errors/rec_ext_ent.xml.str | 0
|
||||
test/errors/rec_ext.ent | 1 +
|
||||
test/errors/rec_ext_ent.xml | 4 +
|
||||
6 files changed, 253 insertions(+)
|
||||
create mode 100644 result/errors/rec_ext_ent.xml
|
||||
create mode 100644 result/errors/rec_ext_ent.xml.ent
|
||||
create mode 100644 result/errors/rec_ext_ent.xml.err
|
||||
create mode 100644 result/errors/rec_ext_ent.xml.str
|
||||
create mode 100644 test/errors/rec_ext.ent
|
||||
create mode 100644 test/errors/rec_ext_ent.xml
|
||||
|
||||
diff --git a/result/errors/rec_ext_ent.xml b/result/errors/rec_ext_ent.xml
|
||||
new file mode 100644
|
||||
index 00000000..6a196cb5
|
||||
--- /dev/null
|
||||
+++ b/result/errors/rec_ext_ent.xml
|
||||
@@ -0,0 +1,5 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!DOCTYPE doc [
|
||||
+<!ENTITY e SYSTEM "rec_ext.ent">
|
||||
+]>
|
||||
+<doc>&e; &e; &e; &e;</doc>
|
||||
diff --git a/result/errors/rec_ext_ent.xml.ent b/result/errors/rec_ext_ent.xml.ent
|
||||
new file mode 100644
|
||||
index 00000000..30dd2854
|
||||
--- /dev/null
|
||||
+++ b/result/errors/rec_ext_ent.xml.ent
|
||||
@@ -0,0 +1,243 @@
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
+ ^
|
||||
+test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
+
|
||||
+^
|
||||
+./test/errors/rec_ext_ent.xml:4: parser error : Entity 'e' failed to parse
|
||||
+<doc>&e; &e; &e; &e;</doc>
|
||||
+ ^
|
||||
diff --git a/result/errors/rec_ext_ent.xml.err b/result/errors/rec_ext_ent.xml.err
|
||||
new file mode 100644
|
||||
index 00000000..e69de29b
|
||||
diff --git a/result/errors/rec_ext_ent.xml.str b/result/errors/rec_ext_ent.xml.str
|
||||
new file mode 100644
|
||||
index 00000000..e69de29b
|
||||
diff --git a/test/errors/rec_ext.ent b/test/errors/rec_ext.ent
|
||||
new file mode 100644
|
||||
index 00000000..345f836f
|
||||
--- /dev/null
|
||||
+++ b/test/errors/rec_ext.ent
|
||||
@@ -0,0 +1 @@
|
||||
+<ent>&e; &e; &e; &e;</ent>
|
||||
diff --git a/test/errors/rec_ext_ent.xml b/test/errors/rec_ext_ent.xml
|
||||
new file mode 100644
|
||||
index 00000000..b4e7e749
|
||||
--- /dev/null
|
||||
+++ b/test/errors/rec_ext_ent.xml
|
||||
@@ -0,0 +1,4 @@
|
||||
+<!DOCTYPE doc [
|
||||
+ <!ENTITY e SYSTEM "rec_ext.ent">
|
||||
+]>
|
||||
+<doc>&e; &e; &e; &e;</doc>
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From 31c6ce3b63f8a494ad9e31ca65187a73d8ad3508 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 9 Nov 2020 17:55:44 +0100
|
||||
Subject: [PATCH] Avoid call stack overflow with XML reader and recursive
|
||||
XIncludes
|
||||
|
||||
Don't process XIncludes in the result of another inclusion to avoid
|
||||
infinite recursion resulting in a call stack overflow.
|
||||
|
||||
This is something the XInclude engine shouldn't allow but correct
|
||||
handling of intra-document includes would require major changes.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 01adf74f..72e40b03 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -1585,7 +1585,8 @@ node_found:
|
||||
/*
|
||||
* Handle XInclude if asked for
|
||||
*/
|
||||
- if ((reader->xinclude) && (reader->node != NULL) &&
|
||||
+ if ((reader->xinclude) && (reader->in_xinclude == 0) &&
|
||||
+ (reader->node != NULL) &&
|
||||
(reader->node->type == XML_ELEMENT_NODE) &&
|
||||
(reader->node->ns != NULL) &&
|
||||
((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
286
backport-Fix-HTML-push-parser-lookahead.patch
Normal file
286
backport-Fix-HTML-push-parser-lookahead.patch
Normal file
@ -0,0 +1,286 @@
|
||||
From 8e219b154e9b938af84c4b009aefa692020103f9 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 12 Jul 2020 21:43:44 +0200
|
||||
Subject: [PATCH] Fix HTML push parser lookahead
|
||||
|
||||
The parsing rules when looking for terminating chars or sequences in
|
||||
the push parser differed from the actual parsing code. This could
|
||||
result in the lookahead to overshoot and data being rescanned,
|
||||
potentially leading to quadratic runtime.
|
||||
|
||||
Comments must never be handled during lookahead. Attribute values must
|
||||
only be skipped for start tags and doctype declarations, not for end
|
||||
tags, comments, PIs and script content.
|
||||
---
|
||||
HTMLparser.c | 88 +++++++++++++---------------------------------------
|
||||
1 file changed, 21 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 06d8c602..d10cf11f 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5136,7 +5136,7 @@ htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) {
|
||||
* @first: the first char to lookup
|
||||
* @next: the next char to lookup or zero
|
||||
* @third: the next char to lookup or zero
|
||||
- * @comment: flag to force checking inside comments
|
||||
+ * @ignoreattrval: skip over attribute values
|
||||
*
|
||||
* Try to find if a sequence (first, next, third) or just (first next) or
|
||||
* (first) is available in the input stream.
|
||||
@@ -5150,13 +5150,11 @@ htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) {
|
||||
*/
|
||||
static int
|
||||
htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
- xmlChar next, xmlChar third, int iscomment,
|
||||
- int ignoreattrval)
|
||||
+ xmlChar next, xmlChar third, int ignoreattrval)
|
||||
{
|
||||
int base, len;
|
||||
htmlParserInputPtr in;
|
||||
const xmlChar *buf;
|
||||
- int incomment = 0;
|
||||
int invalue = 0;
|
||||
char valdellim = 0x0;
|
||||
|
||||
@@ -5171,8 +5169,7 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
if (ctxt->checkIndex > base) {
|
||||
base = ctxt->checkIndex;
|
||||
/* Abuse hasPErefs member to restore current state. */
|
||||
- incomment = ctxt->hasPErefs & 1 ? 1 : 0;
|
||||
- invalue = ctxt->hasPErefs & 2 ? 1 : 0;
|
||||
+ invalue = ctxt->hasPErefs & 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
if (in->buf == NULL) {
|
||||
@@ -5189,14 +5186,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
else if (next)
|
||||
len--;
|
||||
for (; base < len; base++) {
|
||||
- if ((!incomment) && (base + 4 < len) && (!iscomment)) {
|
||||
- if ((buf[base] == '<') && (buf[base + 1] == '!') &&
|
||||
- (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
|
||||
- incomment = 1;
|
||||
- /* do not increment past <! - some people use <!--> */
|
||||
- base += 2;
|
||||
- }
|
||||
- }
|
||||
if (ignoreattrval) {
|
||||
if (buf[base] == '"' || buf[base] == '\'') {
|
||||
if (invalue) {
|
||||
@@ -5213,16 +5202,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
- if (incomment) {
|
||||
- if (base + 3 > len)
|
||||
- break;
|
||||
- if ((buf[base] == '-') && (buf[base + 1] == '-') &&
|
||||
- (buf[base + 2] == '>')) {
|
||||
- incomment = 0;
|
||||
- base += 2;
|
||||
- }
|
||||
- continue;
|
||||
- }
|
||||
if (buf[base] == first) {
|
||||
if (third != 0) {
|
||||
if ((buf[base + 1] != next) || (buf[base + 2] != third))
|
||||
@@ -5251,11 +5230,10 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
}
|
||||
ctxt->checkIndex = base;
|
||||
/* Abuse hasPErefs member to track current state. */
|
||||
- ctxt->hasPErefs = 0;
|
||||
- if (incomment)
|
||||
- ctxt->hasPErefs |= 1;
|
||||
if (invalue)
|
||||
- ctxt->hasPErefs |= 2;
|
||||
+ ctxt->hasPErefs |= 1;
|
||||
+ else
|
||||
+ ctxt->hasPErefs &= ~1;
|
||||
#ifdef DEBUG_PUSH
|
||||
if (next == 0)
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5293,7 +5271,6 @@ htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
|
||||
int base, len;
|
||||
htmlParserInputPtr in;
|
||||
const xmlChar *buf;
|
||||
- int incomment = 0;
|
||||
int i;
|
||||
|
||||
in = ctxt->input;
|
||||
@@ -5304,11 +5281,8 @@ htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
|
||||
if (base < 0)
|
||||
return (-1);
|
||||
|
||||
- if (ctxt->checkIndex > base) {
|
||||
+ if (ctxt->checkIndex > base)
|
||||
base = ctxt->checkIndex;
|
||||
- /* Abuse hasPErefs member to restore current state. */
|
||||
- incomment = ctxt->hasPErefs & 1 ? 1 : 0;
|
||||
- }
|
||||
|
||||
if (in->buf == NULL) {
|
||||
buf = in->base;
|
||||
@@ -5319,24 +5293,6 @@ htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
|
||||
}
|
||||
|
||||
for (; base < len; base++) {
|
||||
- if (!incomment && (base + 4 < len)) {
|
||||
- if ((buf[base] == '<') && (buf[base + 1] == '!') &&
|
||||
- (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
|
||||
- incomment = 1;
|
||||
- /* do not increment past <! - some people use <!--> */
|
||||
- base += 2;
|
||||
- }
|
||||
- }
|
||||
- if (incomment) {
|
||||
- if (base + 3 > len)
|
||||
- break;
|
||||
- if ((buf[base] == '-') && (buf[base + 1] == '-') &&
|
||||
- (buf[base + 2] == '>')) {
|
||||
- incomment = 0;
|
||||
- base += 2;
|
||||
- }
|
||||
- continue;
|
||||
- }
|
||||
for (i = 0; i < stopLen; ++i) {
|
||||
if (buf[base] == stop[i]) {
|
||||
ctxt->checkIndex = 0;
|
||||
@@ -5345,8 +5301,6 @@ htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
|
||||
}
|
||||
}
|
||||
ctxt->checkIndex = base;
|
||||
- /* Abuse hasPErefs member to track current state. */
|
||||
- ctxt->hasPErefs = incomment;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -5489,7 +5443,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
|
||||
(UPP(8) == 'E')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5536,7 +5490,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
if ((cur == '<') && (next == '!') &&
|
||||
(in->cur[2] == '-') && (in->cur[3] == '-')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5546,7 +5500,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
ctxt->instate = XML_PARSER_MISC;
|
||||
} else if ((cur == '<') && (next == '?')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5560,7 +5514,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
|
||||
(UPP(8) == 'E')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5597,7 +5551,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
if ((cur == '<') && (next == '!') &&
|
||||
(in->cur[2] == '-') && (in->cur[3] == '-')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5607,7 +5561,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
ctxt->instate = XML_PARSER_PROLOG;
|
||||
} else if ((cur == '<') && (next == '?')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5645,7 +5599,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
if ((cur == '<') && (next == '!') &&
|
||||
(in->cur[2] == '-') && (in->cur[3] == '-')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5655,7 +5609,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
ctxt->instate = XML_PARSER_EPILOG;
|
||||
} else if ((cur == '<') && (next == '?')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5719,7 +5673,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
break;
|
||||
}
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
|
||||
goto done;
|
||||
|
||||
/* Capture start position */
|
||||
@@ -5866,7 +5820,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
int idx;
|
||||
xmlChar val;
|
||||
|
||||
- idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0, 0);
|
||||
+ idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0);
|
||||
if (idx < 0)
|
||||
goto done;
|
||||
val = in->cur[idx + 2];
|
||||
@@ -5893,7 +5847,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
|
||||
(UPP(8) == 'E')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
|
||||
goto done;
|
||||
htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
|
||||
"Misplaced DOCTYPE declaration\n",
|
||||
@@ -5903,7 +5857,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
(in->cur[2] == '-') && (in->cur[3] == '-')) {
|
||||
if ((!terminate) &&
|
||||
(htmlParseLookupSequence(
|
||||
- ctxt, '-', '-', '>', 1, 1) < 0))
|
||||
+ ctxt, '-', '-', '>', 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5913,7 +5867,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
ctxt->instate = XML_PARSER_CONTENT;
|
||||
} else if ((cur == '<') && (next == '?')) {
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
@@ -5984,7 +5938,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
if (avail < 2)
|
||||
goto done;
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
htmlParseEndTag(ctxt);
|
||||
if (ctxt->nameNr == 0) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
From 954696e7cf236c3aa71dc0b7f9e70d3f51e5cb07 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 7 Feb 2021 13:23:09 +0100
|
||||
Subject: [PATCH] Fix infinite loop in HTML parser introduced with recent
|
||||
commits
|
||||
|
||||
Check for XML_PARSER_EOF to avoid an infinite loop introduced with
|
||||
recent changes to the HTML push parser.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
HTMLparser.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 2877f4b7..14cc56fa 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5872,7 +5872,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"HPP: Parsing char data\n");
|
||||
#endif
|
||||
- while ((cur != '<') && (in->cur < in->end)) {
|
||||
+ while ((ctxt->instate != XML_PARSER_EOF) &&
|
||||
+ (cur != '<') && (in->cur < in->end)) {
|
||||
if (cur == '&') {
|
||||
htmlParseReference(ctxt);
|
||||
} else {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
From 8ca3a59b2ee57e2f30272272bb232c84d03b9edc Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 15 Dec 2020 20:14:28 +0100
|
||||
Subject: [PATCH] Fix integer overflow in xmlSchemaGetParticleTotalRangeMin
|
||||
|
||||
The function is only used once and its return value is only checked for
|
||||
zero. Disable the function like its Max counterpart and add an
|
||||
implementation for the special case.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlschemas.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 45 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index c455b4a3..1efd0962 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -14721,6 +14721,7 @@ xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
+#if 0
|
||||
/**
|
||||
* xmlSchemaGetParticleTotalRangeMin:
|
||||
* @particle: the particle
|
||||
@@ -14776,7 +14777,6 @@ xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
|
||||
}
|
||||
}
|
||||
|
||||
-#if 0
|
||||
/**
|
||||
* xmlSchemaGetParticleTotalRangeMax:
|
||||
* @particle: the particle
|
||||
@@ -14838,6 +14838,48 @@ xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
|
||||
}
|
||||
#endif
|
||||
|
||||
+/**
|
||||
+ * xmlSchemaGetParticleEmptiable:
|
||||
+ * @particle: the particle
|
||||
+ *
|
||||
+ * Returns 1 if emptiable, 0 otherwise.
|
||||
+ */
|
||||
+static int
|
||||
+xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle)
|
||||
+{
|
||||
+ xmlSchemaParticlePtr part;
|
||||
+ int emptiable;
|
||||
+
|
||||
+ if ((particle->children == NULL) || (particle->minOccurs == 0))
|
||||
+ return (1);
|
||||
+
|
||||
+ part = (xmlSchemaParticlePtr) particle->children->children;
|
||||
+ if (part == NULL)
|
||||
+ return (1);
|
||||
+
|
||||
+ while (part != NULL) {
|
||||
+ if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
|
||||
+ (part->children->type == XML_SCHEMA_TYPE_ANY))
|
||||
+ emptiable = (part->minOccurs == 0);
|
||||
+ else
|
||||
+ emptiable = xmlSchemaGetParticleEmptiable(part);
|
||||
+ if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
|
||||
+ if (emptiable)
|
||||
+ return (1);
|
||||
+ } else {
|
||||
+ /* <all> and <sequence> */
|
||||
+ if (!emptiable)
|
||||
+ return (0);
|
||||
+ }
|
||||
+ part = (xmlSchemaParticlePtr) part->next;
|
||||
+ }
|
||||
+
|
||||
+ if (particle->children->type == XML_SCHEMA_TYPE_CHOICE)
|
||||
+ return (0);
|
||||
+ else
|
||||
+ return (1);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* xmlSchemaIsParticleEmptiable:
|
||||
* @particle: the particle
|
||||
@@ -14860,10 +14902,8 @@ xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
|
||||
* SPEC (2) "Its {term} is a group and the minimum part of the
|
||||
* effective total range of that group, [...] is 0."
|
||||
*/
|
||||
- if (WXS_IS_MODEL_GROUP(particle->children)) {
|
||||
- if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
|
||||
- return (1);
|
||||
- }
|
||||
+ if (WXS_IS_MODEL_GROUP(particle->children))
|
||||
+ return (xmlSchemaGetParticleEmptiable(particle));
|
||||
return (0);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
225
backport-Fix-quadratic-runtime-in-HTML-parser.patch
Normal file
225
backport-Fix-quadratic-runtime-in-HTML-parser.patch
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,33 @@
|
||||
From 94c2e415a9bc1b9e7b7210a9c73817106bb1f175 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 6 Dec 2020 16:38:00 +0100
|
||||
Subject: [PATCH] Fix quadratic runtime in HTML push parser with null bytes
|
||||
|
||||
Null bytes in the input stream do not necessarily signal an EOF
|
||||
condition. Check the stream pointers for EOF to avoid quadratic
|
||||
rescanning of input data.
|
||||
|
||||
Note that the CUR_CHAR macro used in functions like htmlParseCharData
|
||||
calls htmlCurrentChar which translates null bytes.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index de624f8d..26a1cdc2 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5832,7 +5832,7 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"HPP: Parsing char data\n");
|
||||
#endif
|
||||
- while ((cur != '<') && (cur != 0)) {
|
||||
+ while ((cur != '<') && (in->cur < in->end)) {
|
||||
if (cur == '&') {
|
||||
htmlParseReference(ctxt);
|
||||
} else {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,128 @@
|
||||
From 6995eed077899c64d34fe8f0d0b34d214cf586af Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 19 Jul 2020 13:54:52 +0200
|
||||
Subject: [PATCH] Fix quadratic runtime when push parsing HTML entity refs
|
||||
|
||||
The HTML push parser would look ahead for characters in "; >/" to
|
||||
terminate an entity reference but actual parsing could stop earlier,
|
||||
potentially resulting in quadratic runtime.
|
||||
|
||||
Parse char data and references alternately in htmlParseTryOrFinish
|
||||
and only look ahead once for a terminating '<' character.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
HTMLparser.c | 77 ++++++----------------------------------------------
|
||||
1 file changed, 9 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index d10cf11f..ad9d7ccc 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5249,61 +5249,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * htmlParseLookupChars:
|
||||
- * @ctxt: an HTML parser context
|
||||
- * @stop: Array of chars, which stop the lookup.
|
||||
- * @stopLen: Length of stop-Array
|
||||
- *
|
||||
- * Try to find if any char of the stop-Array is available in the input
|
||||
- * stream.
|
||||
- * This function has a side effect of (possibly) incrementing ctxt->checkIndex
|
||||
- * to avoid rescanning sequences of bytes, it DOES change the state of the
|
||||
- * parser, do not use liberally.
|
||||
- *
|
||||
- * Returns the index to the current parsing point if a stopChar
|
||||
- * is available, -1 otherwise.
|
||||
- */
|
||||
-static int
|
||||
-htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
|
||||
- int stopLen)
|
||||
-{
|
||||
- int base, len;
|
||||
- htmlParserInputPtr in;
|
||||
- const xmlChar *buf;
|
||||
- int i;
|
||||
-
|
||||
- in = ctxt->input;
|
||||
- if (in == NULL)
|
||||
- return (-1);
|
||||
-
|
||||
- base = in->cur - in->base;
|
||||
- if (base < 0)
|
||||
- return (-1);
|
||||
-
|
||||
- if (ctxt->checkIndex > base)
|
||||
- base = ctxt->checkIndex;
|
||||
-
|
||||
- if (in->buf == NULL) {
|
||||
- buf = in->base;
|
||||
- len = in->length;
|
||||
- } else {
|
||||
- buf = xmlBufContent(in->buf->buffer);
|
||||
- len = xmlBufUse(in->buf->buffer);
|
||||
- }
|
||||
-
|
||||
- for (; base < len; base++) {
|
||||
- for (i = 0; i < stopLen; ++i) {
|
||||
- if (buf[base] == stop[i]) {
|
||||
- ctxt->checkIndex = 0;
|
||||
- return (base - (in->cur - in->base));
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- ctxt->checkIndex = base;
|
||||
- return (-1);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* htmlParseTryOrFinish:
|
||||
* @ctxt: an HTML parser context
|
||||
@@ -5893,17 +5838,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
"HPP: entering START_TAG\n");
|
||||
#endif
|
||||
break;
|
||||
- } else if (cur == '&') {
|
||||
- if ((!terminate) &&
|
||||
- (htmlParseLookupChars(ctxt,
|
||||
- BAD_CAST "; >/", 4) < 0))
|
||||
- goto done;
|
||||
-#ifdef DEBUG_PUSH
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "HPP: Parsing Reference\n");
|
||||
-#endif
|
||||
- /* TODO: check generation of subtrees if noent !!! */
|
||||
- htmlParseReference(ctxt);
|
||||
} else {
|
||||
/*
|
||||
* check that the text sequence is complete
|
||||
@@ -5912,14 +5846,21 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
||||
* data detection.
|
||||
*/
|
||||
if ((!terminate) &&
|
||||
- (htmlParseLookupChars(ctxt, BAD_CAST "<&", 2) < 0))
|
||||
+ (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
|
||||
goto done;
|
||||
ctxt->checkIndex = 0;
|
||||
#ifdef DEBUG_PUSH
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
"HPP: Parsing char data\n");
|
||||
#endif
|
||||
- htmlParseCharData(ctxt);
|
||||
+ while ((cur != '<') && (cur != 0)) {
|
||||
+ if (cur == '&') {
|
||||
+ htmlParseReference(ctxt);
|
||||
+ } else {
|
||||
+ htmlParseCharData(ctxt);
|
||||
+ }
|
||||
+ cur = in->cur[0];
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (cons == ctxt->nbChars) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
48
backport-Fix-regression-introduced-with-477c7f6a.patch
Normal file
48
backport-Fix-regression-introduced-with-477c7f6a.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 741b0d0a8b9bbee67d68af022cb3137c74e9cd0f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 7 Jul 2020 12:54:34 +0200
|
||||
Subject: [PATCH] Fix regression introduced with 477c7f6a
|
||||
|
||||
The 'inSubset' member is actually used by the SAX2 handlers. Store
|
||||
extra parser state in 'hasPErefs'.
|
||||
---
|
||||
HTMLparser.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 468db107..366c19b3 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5160,9 +5160,9 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
|
||||
if (ctxt->checkIndex > base) {
|
||||
base = ctxt->checkIndex;
|
||||
- /* Abuse inSubset member to restore current state. */
|
||||
- incomment = ctxt->inSubset & 1 ? 1 : 0;
|
||||
- invalue = ctxt->inSubset & 2 ? 1 : 0;
|
||||
+ /* Abuse hasPErefs member to restore current state. */
|
||||
+ incomment = ctxt->hasPErefs & 1 ? 1 : 0;
|
||||
+ invalue = ctxt->hasPErefs & 2 ? 1 : 0;
|
||||
}
|
||||
|
||||
if (in->buf == NULL) {
|
||||
@@ -5240,12 +5240,12 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
|
||||
}
|
||||
}
|
||||
ctxt->checkIndex = base;
|
||||
- /* Abuse inSubset member to track current state. */
|
||||
- ctxt->inSubset = 0;
|
||||
+ /* Abuse hasPErefs member to track current state. */
|
||||
+ ctxt->hasPErefs = 0;
|
||||
if (incomment)
|
||||
- ctxt->inSubset |= 1;
|
||||
+ ctxt->hasPErefs |= 1;
|
||||
if (invalue)
|
||||
- ctxt->inSubset |= 2;
|
||||
+ ctxt->hasPErefs |= 2;
|
||||
#ifdef DEBUG_PUSH
|
||||
if (next == 0)
|
||||
xmlGenericError(xmlGenericErrorContext,
|
||||
--
|
||||
2.27.0
|
||||
|
||||
306
backport-Fix-timeout-when-handling-recursive-entities.patch
Normal file
306
backport-Fix-timeout-when-handling-recursive-entities.patch
Normal file
@ -0,0 +1,306 @@
|
||||
From 79301d3d5e553d46fc3201f48dcec3a93068c5a2 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Fri, 18 Dec 2020 12:50:21 +0100
|
||||
Subject: [PATCH] Fix timeout when handling recursive entities
|
||||
|
||||
Abort parsing early to avoid an almost infinite loop in certain error
|
||||
cases involving recursive entities.
|
||||
|
||||
Found with libFuzzer.
|
||||
---
|
||||
parser.c | 1 +
|
||||
result/errors/rec_ext_ent.xml.ent | 178 +++++-------------------------
|
||||
2 files changed, 30 insertions(+), 149 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 43b88358..a7bdc7f3 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -7158,6 +7158,7 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
|
||||
ent->checked |= 1;
|
||||
if (ret == XML_ERR_ENTITY_LOOP) {
|
||||
xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
|
||||
+ xmlHaltParser(ctxt);
|
||||
xmlFreeNodeList(list);
|
||||
return;
|
||||
}
|
||||
diff --git a/result/errors/rec_ext_ent.xml.ent b/result/errors/rec_ext_ent.xml.ent
|
||||
index 30dd2854..d8ccec14 100644
|
||||
--- a/result/errors/rec_ext_ent.xml.ent
|
||||
+++ b/result/errors/rec_ext_ent.xml.ent
|
||||
@@ -1,243 +1,123 @@
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-test/errors/rec_ext.ent:1: parser error : Entity 'e' failed to parse
|
||||
+test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
test/errors/rec_ext.ent:1: parser error : Detected an entity reference loop
|
||||
<ent>&e; &e; &e; &e;</ent>
|
||||
^
|
||||
-test/errors/rec_ext.ent:2: parser error : chunk is not well balanced
|
||||
-
|
||||
-^
|
||||
-./test/errors/rec_ext_ent.xml:4: parser error : Entity 'e' failed to parse
|
||||
+./test/errors/rec_ext_ent.xml:4: parser error : Detected an entity reference loop
|
||||
<doc>&e; &e; &e; &e;</doc>
|
||||
^
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From 13ba5b619a153f240320eb92b59158d657bdeb3a Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 28 Jun 2020 13:16:46 +0200
|
||||
Subject: [PATCH] Reset HTML parser input before reporting encoding error
|
||||
|
||||
If charset conversion fails, reset the input pointers before reporting
|
||||
the error and bailing out. Otherwise, the input pointers are left in an
|
||||
invalid state which could lead to use-after-free and other memory
|
||||
errors.
|
||||
|
||||
Similar to f9e7997e. Found by OSS-Fuzz.
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 9ade6635..7fba9429 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -6160,12 +6160,12 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
|
||||
size_t current = ctxt->input->cur - ctxt->input->base;
|
||||
|
||||
nbchars = xmlCharEncInput(in, terminate);
|
||||
+ xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
|
||||
if (nbchars < 0) {
|
||||
htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
|
||||
"encoder error\n", NULL, NULL);
|
||||
return(XML_ERR_INVALID_ENCODING);
|
||||
}
|
||||
- xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
17
libxml2.spec
17
libxml2.spec
@ -1,7 +1,7 @@
|
||||
Summary: Library providing XML and HTML support
|
||||
Name: libxml2
|
||||
Version: 2.9.10
|
||||
Release: 10
|
||||
Release: 11
|
||||
License: MIT
|
||||
Group: Development/Libraries
|
||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
||||
@ -57,6 +57,18 @@ Patch47: Fix-cleanup-of-attributes-in-XML-reader.patch
|
||||
Patch48: Fix-null-deref-in-XPointer-expression-error-path.patch
|
||||
Patch49: Fix-use-after-free-when-XIncluding-text-from-Reader.patch
|
||||
|
||||
Patch50: backport-Add-test-case-for-recursive-external-parsed-entities.patch
|
||||
Patch51: backport-Fix-timeout-when-handling-recursive-entities.patch
|
||||
Patch52: backport-Avoid-call-stack-overflow-with-XML-reader-and-recurs.patch
|
||||
Patch53: backport-Reset-HTML-parser-input-before-reporting-encoding-er.patch
|
||||
Patch54: backport-Fix-quadratic-runtime-in-HTML-parser.patch
|
||||
Patch55: backport-Fix-regression-introduced-with-477c7f6a.patch
|
||||
Patch56: backport-Fix-HTML-push-parser-lookahead.patch
|
||||
Patch57: backport-Fix-quadratic-runtime-when-push-parsing-HTML-entity-.patch
|
||||
Patch58: backport-Fix-quadratic-runtime-in-HTML-push-parser-with-null-.patch
|
||||
Patch59: backport-Fix-infinite-loop-in-HTML-parser-introduced-with-rec.patch
|
||||
Patch60: backport-Fix-integer-overflow-in-xmlSchemaGetParticleTotalRan.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: zlib-devel
|
||||
@ -216,6 +228,9 @@ rm -fr %{buildroot}
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Mar 2 2020 Lirui <lirui130@huawei.com> - 2.9.10-11
|
||||
- fix problems detected by oss-fuzz test
|
||||
|
||||
* Thu Nov 12 2020 Liquor <lirui130@huawei.com> - 2.9.10-10
|
||||
- fix problems detected by oss-fuzz test
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user