!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
|
Summary: Library providing XML and HTML support
|
||||||
Name: libxml2
|
Name: libxml2
|
||||||
Version: 2.9.10
|
Version: 2.9.10
|
||||||
Release: 10
|
Release: 11
|
||||||
License: MIT
|
License: MIT
|
||||||
Group: Development/Libraries
|
Group: Development/Libraries
|
||||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
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
|
Patch48: Fix-null-deref-in-XPointer-expression-error-path.patch
|
||||||
Patch49: Fix-use-after-free-when-XIncluding-text-from-Reader.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
|
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||||
BuildRequires: python3-devel
|
BuildRequires: python3-devel
|
||||||
BuildRequires: zlib-devel
|
BuildRequires: zlib-devel
|
||||||
@ -216,6 +228,9 @@ rm -fr %{buildroot}
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%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
|
* Thu Nov 12 2020 Liquor <lirui130@huawei.com> - 2.9.10-10
|
||||||
- fix problems detected by oss-fuzz test
|
- fix problems detected by oss-fuzz test
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user