Fix integer overflow in xmlFAParseQuantExact
This commit is contained in:
parent
919545d0cf
commit
57fff5b42d
@ -1,61 +0,0 @@
|
||||
From 7abec671473b837f99181442d59edd0cc2ee01d1 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 15 Mar 2018 19:33:52 +0100
|
||||
Subject: [PATCH 01/13] NaN and Inf fixes for pre-C99 compilers
|
||||
|
||||
On some pre-C99 compilers, the NAN and INFINITY macros don't expand to
|
||||
constant expressions.
|
||||
|
||||
Some MSVC versions complain about floating point division by zero in
|
||||
constants.
|
||||
|
||||
Thanks to Fabrice Manfroi for the report.
|
||||
---
|
||||
xpath.c | 19 ++++++++++---------
|
||||
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index f4406967..89fab588 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -477,27 +477,28 @@ int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
-#ifndef NAN
|
||||
-#define NAN (0.0 / 0.0)
|
||||
+#ifndef INFINITY
|
||||
+#define INFINITY (DBL_MAX * DBL_MAX)
|
||||
#endif
|
||||
|
||||
-#ifndef INFINITY
|
||||
-#define INFINITY HUGE_VAL
|
||||
+#ifndef NAN
|
||||
+#define NAN (INFINITY / INFINITY)
|
||||
#endif
|
||||
|
||||
-double xmlXPathNAN = NAN;
|
||||
-double xmlXPathPINF = INFINITY;
|
||||
-double xmlXPathNINF = -INFINITY;
|
||||
+double xmlXPathNAN;
|
||||
+double xmlXPathPINF;
|
||||
+double xmlXPathNINF;
|
||||
|
||||
/**
|
||||
* xmlXPathInit:
|
||||
*
|
||||
* Initialize the XPath environment
|
||||
- *
|
||||
- * Does nothing but must be kept as public function.
|
||||
*/
|
||||
void
|
||||
xmlXPathInit(void) {
|
||||
+ xmlXPathNAN = NAN;
|
||||
+ xmlXPathPINF = INFINITY;
|
||||
+ xmlXPathNINF = -INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
From 7a1bd7f6497ac33a9023d556f6f47a48f01deac0 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 17 Mar 2018 00:03:24 +0100
|
||||
Subject: [PATCH 02/13] Revert "Change calls to xmlCharEncInput to set flush
|
||||
false"
|
||||
|
||||
This reverts commit 6e6ae5daa6cd9640c9a83c1070896273e9b30d14 which
|
||||
broke decoding of larger documents with ICU.
|
||||
|
||||
See https://bugs.chromium.org/p/chromium/issues/detail?id=820163
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
parserInternals.c | 2 +-
|
||||
xmlIO.c | 4 ++--
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 9adeb174..7e243e60 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -3635,7 +3635,7 @@ htmlCheckEncodingDirect(htmlParserCtxtPtr ctxt, const xmlChar *encoding) {
|
||||
*/
|
||||
processed = ctxt->input->cur - ctxt->input->base;
|
||||
xmlBufShrink(ctxt->input->buf->buffer, processed);
|
||||
- nbchars = xmlCharEncInput(ctxt->input->buf, 0);
|
||||
+ nbchars = xmlCharEncInput(ctxt->input->buf, 1);
|
||||
if (nbchars < 0) {
|
||||
htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
|
||||
"htmlCheckEncoding: encoder error\n",
|
||||
diff --git a/parserInternals.c b/parserInternals.c
|
||||
index 8c0cd57a..09876ab4 100644
|
||||
--- a/parserInternals.c
|
||||
+++ b/parserInternals.c
|
||||
@@ -1214,7 +1214,7 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
||||
/*
|
||||
* convert as much as possible of the buffer
|
||||
*/
|
||||
- nbchars = xmlCharEncInput(input->buf, 0);
|
||||
+ nbchars = xmlCharEncInput(input->buf, 1);
|
||||
} else {
|
||||
/*
|
||||
* convert just enough to get
|
||||
diff --git a/xmlIO.c b/xmlIO.c
|
||||
index 82543477..f61dd05a 100644
|
||||
--- a/xmlIO.c
|
||||
+++ b/xmlIO.c
|
||||
@@ -3157,7 +3157,7 @@ xmlParserInputBufferPush(xmlParserInputBufferPtr in,
|
||||
* convert as much as possible to the parser reading buffer.
|
||||
*/
|
||||
use = xmlBufUse(in->raw);
|
||||
- nbchars = xmlCharEncInput(in, 0);
|
||||
+ nbchars = xmlCharEncInput(in, 1);
|
||||
if (nbchars < 0) {
|
||||
xmlIOErr(XML_IO_ENCODER, NULL);
|
||||
in->error = XML_IO_ENCODER;
|
||||
@@ -3273,7 +3273,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
|
||||
* convert as much as possible to the parser reading buffer.
|
||||
*/
|
||||
use = xmlBufUse(in->raw);
|
||||
- nbchars = xmlCharEncInput(in, 0);
|
||||
+ nbchars = xmlCharEncInput(in, 1);
|
||||
if (nbchars < 0) {
|
||||
xmlIOErr(XML_IO_ENCODER, NULL);
|
||||
in->error = XML_IO_ENCODER;
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From ebe12882ee7e14fa6463bb07d7de5f5388f09573 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 16 Apr 2018 18:18:11 +0200
|
||||
Subject: [PATCH 03/13] Fix inconsistency in xmlXPathIsInf
|
||||
|
||||
We don't use HUGE_VAL for INFINITY after the most recent fix.
|
||||
---
|
||||
xpath.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 89fab588..bd093643 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -527,9 +527,9 @@ xmlXPathIsInf(double val) {
|
||||
#ifdef isinf
|
||||
return isinf(val) ? (val > 0 ? 1 : -1) : 0;
|
||||
#else
|
||||
- if (val >= HUGE_VAL)
|
||||
+ if (val >= INFINITY)
|
||||
return 1;
|
||||
- if (val <= -HUGE_VAL)
|
||||
+ if (val <= -INFINITY)
|
||||
return -1;
|
||||
return 0;
|
||||
#endif
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
From e22a83b1d095dac25ce05e1a2d9f263f41d11c68 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 May 2017 01:18:36 +0200
|
||||
Subject: [PATCH 04/13] Stop using XPATH_OP_RESET
|
||||
|
||||
It only sets the context node to NULL which doesn't seem useful and can
|
||||
even cause bugs like bug #795299:
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=795299
|
||||
---
|
||||
xpath.c | 37 +++----------------------------------
|
||||
1 file changed, 3 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index bd093643..601763ee 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -868,15 +868,14 @@ typedef enum {
|
||||
XPATH_OP_UNION,
|
||||
XPATH_OP_ROOT,
|
||||
XPATH_OP_NODE,
|
||||
- XPATH_OP_RESET, /* 10 */
|
||||
XPATH_OP_COLLECT,
|
||||
- XPATH_OP_VALUE, /* 12 */
|
||||
+ XPATH_OP_VALUE, /* 11 */
|
||||
XPATH_OP_VARIABLE,
|
||||
XPATH_OP_FUNCTION,
|
||||
XPATH_OP_ARG,
|
||||
XPATH_OP_PREDICATE,
|
||||
- XPATH_OP_FILTER, /* 17 */
|
||||
- XPATH_OP_SORT /* 18 */
|
||||
+ XPATH_OP_FILTER, /* 16 */
|
||||
+ XPATH_OP_SORT /* 17 */
|
||||
#ifdef LIBXML_XPTR_ENABLED
|
||||
,XPATH_OP_RANGETO
|
||||
#endif
|
||||
@@ -1526,8 +1525,6 @@ xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
|
||||
fprintf(output, "ROOT"); break;
|
||||
case XPATH_OP_NODE:
|
||||
fprintf(output, "NODE"); break;
|
||||
- case XPATH_OP_RESET:
|
||||
- fprintf(output, "RESET"); break;
|
||||
case XPATH_OP_SORT:
|
||||
fprintf(output, "SORT"); break;
|
||||
case XPATH_OP_COLLECT: {
|
||||
@@ -10735,7 +10732,6 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
|
||||
|
||||
PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
|
||||
NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
|
||||
- PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
|
||||
|
||||
xmlXPathCompRelativeLocationPath(ctxt);
|
||||
} else if (CUR == '/') {
|
||||
@@ -12779,15 +12775,6 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
|
||||
valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
|
||||
ctxt->context->node));
|
||||
return (total);
|
||||
- case XPATH_OP_RESET:
|
||||
- if (op->ch1 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
- CHECK_ERROR0;
|
||||
- if (op->ch2 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
- CHECK_ERROR0;
|
||||
- ctxt->context->node = NULL;
|
||||
- return (total);
|
||||
case XPATH_OP_COLLECT:{
|
||||
if (op->ch1 == -1)
|
||||
return (total);
|
||||
@@ -12918,15 +12905,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
|
||||
ctxt->context->node));
|
||||
return (total);
|
||||
- case XPATH_OP_RESET:
|
||||
- if (op->ch1 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
- CHECK_ERROR0;
|
||||
- if (op->ch2 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
- CHECK_ERROR0;
|
||||
- ctxt->context->node = NULL;
|
||||
- return (total);
|
||||
case XPATH_OP_COLLECT:{
|
||||
if (op->ch1 == -1)
|
||||
return (0);
|
||||
@@ -13457,15 +13435,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
|
||||
ctxt->context->node));
|
||||
return (total);
|
||||
- case XPATH_OP_RESET:
|
||||
- if (op->ch1 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
- CHECK_ERROR0;
|
||||
- if (op->ch2 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
- CHECK_ERROR0;
|
||||
- ctxt->context->node = NULL;
|
||||
- return (total);
|
||||
case XPATH_OP_COLLECT:{
|
||||
if (op->ch1 == -1)
|
||||
return (total);
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From 938835e763277684274ac31afc08fc40fa419aae Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 May 2017 01:21:57 +0200
|
||||
Subject: [PATCH 05/13] Don't change context node in xmlXPathRoot
|
||||
|
||||
---
|
||||
xpath.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 601763ee..1e98ddc2 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -8477,9 +8477,8 @@ void
|
||||
xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
|
||||
if ((ctxt == NULL) || (ctxt->context == NULL))
|
||||
return;
|
||||
- ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
|
||||
valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
|
||||
- ctxt->context->node));
|
||||
+ (xmlNodePtr) ctxt->context->doc));
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,189 +0,0 @@
|
||||
From 029d0e960c02d83111acb5ab057ee055821943f7 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 May 2017 01:28:27 +0200
|
||||
Subject: [PATCH 06/13] Avoid unnecessary backups of the context node
|
||||
|
||||
---
|
||||
xpath.c | 42 ------------------------------------------
|
||||
1 file changed, 42 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 1e98ddc2..b1bd7e07 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -12829,8 +12829,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
int total = 0, cur;
|
||||
xmlXPathCompExprPtr comp;
|
||||
xmlXPathObjectPtr arg1, arg2;
|
||||
- xmlNodePtr bak;
|
||||
- xmlDocPtr bakd;
|
||||
int pp;
|
||||
int cs;
|
||||
|
||||
@@ -12840,8 +12838,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
case XPATH_OP_END:
|
||||
return (0);
|
||||
case XPATH_OP_UNION:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total =
|
||||
@@ -12861,8 +12857,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
nodesetval->nodeNr -
|
||||
1];
|
||||
}
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
cur =
|
||||
@@ -13244,8 +13238,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
int equal, ret;
|
||||
xmlXPathCompExprPtr comp;
|
||||
xmlXPathObjectPtr arg1, arg2;
|
||||
- xmlNodePtr bak;
|
||||
- xmlDocPtr bakd;
|
||||
int pp;
|
||||
int cs;
|
||||
|
||||
@@ -13255,8 +13247,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
case XPATH_OP_END:
|
||||
return (0);
|
||||
case XPATH_OP_AND:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
@@ -13265,8 +13255,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
|
||||
return (total);
|
||||
arg2 = valuePop(ctxt);
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13281,8 +13269,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_OR:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
@@ -13291,8 +13277,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
|
||||
return (total);
|
||||
arg2 = valuePop(ctxt);
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13307,14 +13291,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_EQUAL:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13326,14 +13306,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
|
||||
return (total);
|
||||
case XPATH_OP_CMP:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13342,15 +13318,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
|
||||
return (total);
|
||||
case XPATH_OP_PLUS:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
if (op->ch2 != -1) {
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13368,14 +13340,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
}
|
||||
return (total);
|
||||
case XPATH_OP_MULT:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13388,14 +13356,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathModValues(ctxt);
|
||||
return (total);
|
||||
case XPATH_OP_UNION:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->doc = bakd;
|
||||
- ctxt->context->node = bak;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
@@ -13552,24 +13516,18 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
return (total);
|
||||
}
|
||||
case XPATH_OP_ARG:
|
||||
- bakd = ctxt->context->doc;
|
||||
- bak = ctxt->context->node;
|
||||
pp = ctxt->context->proximityPosition;
|
||||
cs = ctxt->context->contextSize;
|
||||
if (op->ch1 != -1) {
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
ctxt->context->contextSize = cs;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->node = bak;
|
||||
- ctxt->context->doc = bakd;
|
||||
CHECK_ERROR0;
|
||||
}
|
||||
if (op->ch2 != -1) {
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
ctxt->context->contextSize = cs;
|
||||
ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->node = bak;
|
||||
- ctxt->context->doc = bakd;
|
||||
CHECK_ERROR0;
|
||||
}
|
||||
return (total);
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,378 +0,0 @@
|
||||
From 665df41dcc6c4c3a609907c979b6c16472593d0d Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 16 Apr 2018 19:37:34 +0200
|
||||
Subject: [PATCH 07/13] Simplify and harden nodeset filtering
|
||||
|
||||
If a nodeset to be filtered is empty, it can be returned without popping
|
||||
it from the stack.
|
||||
|
||||
Make sure to restore the context node in all error paths and never set
|
||||
it to NULL.
|
||||
|
||||
Save and restore the context node in RANGETO operations.
|
||||
---
|
||||
xpath.c | 152 +++++++++++++++-----------------------------------------
|
||||
1 file changed, 41 insertions(+), 111 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index b1bd7e07..4b9faaf6 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -12993,7 +12993,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
return (total);
|
||||
|
||||
#ifdef LIBXML_XPTR_ENABLED
|
||||
- oldnode = ctxt->context->node;
|
||||
/*
|
||||
* Hum are we filtering the result of an XPointer expression
|
||||
*/
|
||||
@@ -13008,23 +13007,15 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
* up a new locset.
|
||||
*/
|
||||
CHECK_TYPE0(XPATH_LOCATIONSET);
|
||||
+
|
||||
+ if ((ctxt->value->user == NULL) ||
|
||||
+ (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
|
||||
+ return (total);
|
||||
+
|
||||
obj = valuePop(ctxt);
|
||||
oldlocset = obj->user;
|
||||
- ctxt->context->node = NULL;
|
||||
+ oldnode = ctxt->context->node;
|
||||
|
||||
- if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
|
||||
- ctxt->context->contextSize = 0;
|
||||
- ctxt->context->proximityPosition = 0;
|
||||
- if (op->ch2 != -1)
|
||||
- total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
- res = valuePop(ctxt);
|
||||
- if (res != NULL) {
|
||||
- xmlXPathReleaseObject(ctxt->context, res);
|
||||
- }
|
||||
- valuePush(ctxt, obj);
|
||||
- CHECK_ERROR0;
|
||||
- return (total);
|
||||
- }
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
for (i = 0; i < oldlocset->locNr; i++) {
|
||||
@@ -13049,6 +13040,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
@@ -13077,7 +13069,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
/* OLD: xmlXPathFreeObject(res); */
|
||||
} else
|
||||
tmp = NULL;
|
||||
- ctxt->context->node = NULL;
|
||||
/*
|
||||
* Only put the first node in the result, then leave.
|
||||
*/
|
||||
@@ -13093,7 +13084,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
* The result is used as the new evaluation locset.
|
||||
*/
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->node = NULL;
|
||||
ctxt->context->contextSize = -1;
|
||||
ctxt->context->proximityPosition = -1;
|
||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
@@ -13108,32 +13098,17 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
* up a new set.
|
||||
*/
|
||||
CHECK_TYPE0(XPATH_NODESET);
|
||||
- obj = valuePop(ctxt);
|
||||
- oldset = obj->nodesetval;
|
||||
|
||||
- oldnode = ctxt->context->node;
|
||||
- oldDoc = ctxt->context->doc;
|
||||
- ctxt->context->node = NULL;
|
||||
-
|
||||
- if ((oldset == NULL) || (oldset->nodeNr == 0)) {
|
||||
- ctxt->context->contextSize = 0;
|
||||
- ctxt->context->proximityPosition = 0;
|
||||
- /* QUESTION TODO: Why was this code commented out?
|
||||
- if (op->ch2 != -1)
|
||||
- total +=
|
||||
- xmlXPathCompOpEval(ctxt,
|
||||
- &comp->steps[op->ch2]);
|
||||
- CHECK_ERROR0;
|
||||
- res = valuePop(ctxt);
|
||||
- if (res != NULL)
|
||||
- xmlXPathFreeObject(res);
|
||||
- */
|
||||
- valuePush(ctxt, obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- CHECK_ERROR0;
|
||||
- } else {
|
||||
+ if ((ctxt->value->nodesetval != NULL) &&
|
||||
+ (ctxt->value->nodesetval->nodeNr != 0)) {
|
||||
xmlNodeSetPtr newset;
|
||||
xmlXPathObjectPtr tmp = NULL;
|
||||
+
|
||||
+ obj = valuePop(ctxt);
|
||||
+ oldset = obj->nodesetval;
|
||||
+ oldnode = ctxt->context->node;
|
||||
+ oldDoc = ctxt->context->doc;
|
||||
+
|
||||
/*
|
||||
* Initialize the new set.
|
||||
* Also set the xpath document in case things like
|
||||
@@ -13168,6 +13143,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeNodeSet(newset);
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
@@ -13195,7 +13171,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
xmlXPathNodeSetClear(tmp->nodesetval, 1);
|
||||
} else
|
||||
tmp = NULL;
|
||||
- ctxt->context->node = NULL;
|
||||
/*
|
||||
* Only put the first node in the result, then leave.
|
||||
*/
|
||||
@@ -13211,14 +13186,12 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->node = NULL;
|
||||
ctxt->context->contextSize = -1;
|
||||
ctxt->context->proximityPosition = -1;
|
||||
- /* may want to move this past the '}' later */
|
||||
+ ctxt->context->node = oldnode;
|
||||
ctxt->context->doc = oldDoc;
|
||||
valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
}
|
||||
- ctxt->context->node = oldnode;
|
||||
return(total);
|
||||
}
|
||||
#endif /* XP_OPTIMIZED_FILTER_FIRST */
|
||||
@@ -13641,8 +13614,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
if (ctxt->value == NULL)
|
||||
return (total);
|
||||
|
||||
- oldnode = ctxt->context->node;
|
||||
-
|
||||
#ifdef LIBXML_XPTR_ENABLED
|
||||
/*
|
||||
* Hum are we filtering the result of an XPointer expression
|
||||
@@ -13657,25 +13628,15 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
* up a new locset.
|
||||
*/
|
||||
CHECK_TYPE0(XPATH_LOCATIONSET);
|
||||
+
|
||||
+ if ((ctxt->value->user == NULL) ||
|
||||
+ (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
|
||||
+ return (total);
|
||||
+
|
||||
obj = valuePop(ctxt);
|
||||
oldlocset = obj->user;
|
||||
- ctxt->context->node = NULL;
|
||||
+ oldnode = ctxt->context->node;
|
||||
|
||||
- if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
|
||||
- ctxt->context->contextSize = 0;
|
||||
- ctxt->context->proximityPosition = 0;
|
||||
- if (op->ch2 != -1)
|
||||
- total +=
|
||||
- xmlXPathCompOpEval(ctxt,
|
||||
- &comp->steps[op->ch2]);
|
||||
- res = valuePop(ctxt);
|
||||
- if (res != NULL) {
|
||||
- xmlXPathReleaseObject(ctxt->context, res);
|
||||
- }
|
||||
- valuePush(ctxt, obj);
|
||||
- CHECK_ERROR0;
|
||||
- return (total);
|
||||
- }
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
for (i = 0; i < oldlocset->locNr; i++) {
|
||||
@@ -13696,6 +13657,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -13720,15 +13682,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
res = valuePop(ctxt);
|
||||
xmlXPathReleaseObject(ctxt->context, res);
|
||||
}
|
||||
-
|
||||
- ctxt->context->node = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The result is used as the new evaluation locset.
|
||||
*/
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->node = NULL;
|
||||
ctxt->context->contextSize = -1;
|
||||
ctxt->context->proximityPosition = -1;
|
||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
@@ -13743,30 +13702,13 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
* up a new set.
|
||||
*/
|
||||
CHECK_TYPE0(XPATH_NODESET);
|
||||
- obj = valuePop(ctxt);
|
||||
- oldset = obj->nodesetval;
|
||||
-
|
||||
- oldnode = ctxt->context->node;
|
||||
- oldDoc = ctxt->context->doc;
|
||||
- ctxt->context->node = NULL;
|
||||
|
||||
- if ((oldset == NULL) || (oldset->nodeNr == 0)) {
|
||||
- ctxt->context->contextSize = 0;
|
||||
- ctxt->context->proximityPosition = 0;
|
||||
-/*
|
||||
- if (op->ch2 != -1)
|
||||
- total +=
|
||||
- xmlXPathCompOpEval(ctxt,
|
||||
- &comp->steps[op->ch2]);
|
||||
- CHECK_ERROR0;
|
||||
- res = valuePop(ctxt);
|
||||
- if (res != NULL)
|
||||
- xmlXPathFreeObject(res);
|
||||
-*/
|
||||
- valuePush(ctxt, obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- CHECK_ERROR0;
|
||||
- } else {
|
||||
+ if ((ctxt->value->nodesetval != NULL) &&
|
||||
+ (ctxt->value->nodesetval->nodeNr != 0)) {
|
||||
+ obj = valuePop(ctxt);
|
||||
+ oldset = obj->nodesetval;
|
||||
+ oldnode = ctxt->context->node;
|
||||
+ oldDoc = ctxt->context->doc;
|
||||
tmp = NULL;
|
||||
/*
|
||||
* Initialize the new set.
|
||||
@@ -13833,6 +13775,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeNodeSet(newset);
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -13867,7 +13810,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
*/
|
||||
} else
|
||||
tmp = NULL;
|
||||
- ctxt->context->node = NULL;
|
||||
}
|
||||
if (tmp != NULL)
|
||||
xmlXPathReleaseObject(ctxt->context, tmp);
|
||||
@@ -13875,15 +13817,13 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->node = NULL;
|
||||
ctxt->context->contextSize = -1;
|
||||
ctxt->context->proximityPosition = -1;
|
||||
- /* may want to move this past the '}' later */
|
||||
+ ctxt->context->node = oldnode;
|
||||
ctxt->context->doc = oldDoc;
|
||||
valuePush(ctxt,
|
||||
xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
}
|
||||
- ctxt->context->node = oldnode;
|
||||
return (total);
|
||||
}
|
||||
case XPATH_OP_SORT:
|
||||
@@ -13906,6 +13846,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlLocationSetPtr newlocset = NULL;
|
||||
xmlLocationSetPtr oldlocset;
|
||||
xmlNodeSetPtr oldset;
|
||||
+ xmlNodePtr oldnode = ctxt->context->node;
|
||||
int i, j;
|
||||
|
||||
if (op->ch1 != -1) {
|
||||
@@ -13926,22 +13867,14 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
* up a new locset.
|
||||
*/
|
||||
CHECK_TYPE0(XPATH_LOCATIONSET);
|
||||
+
|
||||
+ if ((ctxt->value->user == NULL) ||
|
||||
+ (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
|
||||
+ return (total);
|
||||
+
|
||||
obj = valuePop(ctxt);
|
||||
oldlocset = obj->user;
|
||||
|
||||
- if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
|
||||
- ctxt->context->node = NULL;
|
||||
- ctxt->context->contextSize = 0;
|
||||
- ctxt->context->proximityPosition = 0;
|
||||
- total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]);
|
||||
- res = valuePop(ctxt);
|
||||
- if (res != NULL) {
|
||||
- xmlXPathReleaseObject(ctxt->context, res);
|
||||
- }
|
||||
- valuePush(ctxt, obj);
|
||||
- CHECK_ERROR0;
|
||||
- return (total);
|
||||
- }
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
for (i = 0; i < oldlocset->locNr; i++) {
|
||||
@@ -13962,6 +13895,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -13997,14 +13931,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
res = valuePop(ctxt);
|
||||
xmlXPathReleaseObject(ctxt->context, res);
|
||||
}
|
||||
-
|
||||
- ctxt->context->node = NULL;
|
||||
}
|
||||
} else { /* Not a location set */
|
||||
CHECK_TYPE0(XPATH_NODESET);
|
||||
obj = valuePop(ctxt);
|
||||
oldset = obj->nodesetval;
|
||||
- ctxt->context->node = NULL;
|
||||
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
@@ -14028,6 +13959,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeObject(obj);
|
||||
+ ctxt->context->node = oldnode;
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -14049,8 +13981,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
res = valuePop(ctxt);
|
||||
xmlXPathReleaseObject(ctxt->context, res);
|
||||
}
|
||||
-
|
||||
- ctxt->context->node = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14059,7 +13989,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->node = NULL;
|
||||
+ ctxt->context->node = oldnode;
|
||||
ctxt->context->contextSize = -1;
|
||||
ctxt->context->proximityPosition = -1;
|
||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,443 +0,0 @@
|
||||
From fa33bf317aa9b455e08b211252092dd9110c49fb Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 May 2017 00:45:10 +0200
|
||||
Subject: [PATCH 08/13] Improve restoring of context size and position
|
||||
|
||||
Restore context size and position where it is modified, not in
|
||||
seemingly random places.
|
||||
---
|
||||
xpath.c | 133 ++++++++++++++++++++++----------------------------------
|
||||
1 file changed, 53 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 4b9faaf6..9d223977 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -11661,6 +11661,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
|
||||
xmlXPathContextPtr xpctxt = ctxt->context;
|
||||
xmlNodePtr contextNode, oldContextNode;
|
||||
xmlDocPtr oldContextDoc;
|
||||
+ int oldcs, oldpp;
|
||||
int i, res, contextPos = 0, newContextSize;
|
||||
xmlXPathStepOpPtr exprOp;
|
||||
xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
|
||||
@@ -11697,6 +11698,8 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
|
||||
*/
|
||||
oldContextNode = xpctxt->node;
|
||||
oldContextDoc = xpctxt->doc;
|
||||
+ oldcs = xpctxt->contextSize;
|
||||
+ oldpp = xpctxt->proximityPosition;
|
||||
/*
|
||||
* Get the expression of this predicate.
|
||||
*/
|
||||
@@ -11783,8 +11786,8 @@ evaluation_exit:
|
||||
*/
|
||||
xpctxt->node = oldContextNode;
|
||||
xpctxt->doc = oldContextDoc;
|
||||
- xpctxt->contextSize = -1;
|
||||
- xpctxt->proximityPosition = -1;
|
||||
+ xpctxt->contextSize = oldcs;
|
||||
+ xpctxt->proximityPosition = oldpp;
|
||||
return(newContextSize);
|
||||
}
|
||||
return(contextSize);
|
||||
@@ -11827,6 +11830,7 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
|
||||
return (contextSize);
|
||||
} else {
|
||||
xmlDocPtr oldContextDoc;
|
||||
+ int oldcs, oldpp;
|
||||
int i, pos = 0, newContextSize = 0, contextPos = 0, res;
|
||||
xmlXPathStepOpPtr exprOp;
|
||||
xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
|
||||
@@ -11847,6 +11851,8 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
|
||||
*/
|
||||
oldContextNode = xpctxt->node;
|
||||
oldContextDoc = xpctxt->doc;
|
||||
+ oldcs = xpctxt->contextSize;
|
||||
+ oldpp = xpctxt->proximityPosition;
|
||||
/*
|
||||
* Get the expression of this predicate.
|
||||
*/
|
||||
@@ -11983,8 +11989,8 @@ evaluation_exit:
|
||||
*/
|
||||
xpctxt->node = oldContextNode;
|
||||
xpctxt->doc = oldContextDoc;
|
||||
- xpctxt->contextSize = -1;
|
||||
- xpctxt->proximityPosition = -1;
|
||||
+ xpctxt->contextSize = oldcs;
|
||||
+ xpctxt->proximityPosition = oldpp;
|
||||
return(newContextSize);
|
||||
}
|
||||
return(contextSize);
|
||||
@@ -12829,8 +12835,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
int total = 0, cur;
|
||||
xmlXPathCompExprPtr comp;
|
||||
xmlXPathObjectPtr arg1, arg2;
|
||||
- int pp;
|
||||
- int cs;
|
||||
|
||||
CHECK_ERROR0;
|
||||
comp = ctxt->comp;
|
||||
@@ -12838,8 +12842,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
case XPATH_OP_END:
|
||||
return (0);
|
||||
case XPATH_OP_UNION:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total =
|
||||
xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
|
||||
CHECK_ERROR0;
|
||||
@@ -12857,8 +12859,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op,
|
||||
nodesetval->nodeNr -
|
||||
1];
|
||||
}
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
cur =
|
||||
xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
|
||||
CHECK_ERROR0;
|
||||
@@ -12942,6 +12942,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
xmlNodeSetPtr oldset;
|
||||
xmlNodePtr oldnode;
|
||||
xmlDocPtr oldDoc;
|
||||
+ int oldcs, oldpp;
|
||||
int i;
|
||||
|
||||
CHECK_ERROR0;
|
||||
@@ -13015,6 +13016,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
obj = valuePop(ctxt);
|
||||
oldlocset = obj->user;
|
||||
oldnode = ctxt->context->node;
|
||||
+ oldcs = ctxt->context->contextSize;
|
||||
+ oldpp = ctxt->context->proximityPosition;
|
||||
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
@@ -13039,9 +13042,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
if (op->ch2 != -1)
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ xmlXPtrFreeLocationSet(newlocset);
|
||||
+ goto xptr_error;
|
||||
}
|
||||
/*
|
||||
* The result of the evaluation need to be tested to
|
||||
@@ -13083,11 +13085,12 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
/*
|
||||
* The result is used as the new evaluation locset.
|
||||
*/
|
||||
- xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->contextSize = -1;
|
||||
- ctxt->context->proximityPosition = -1;
|
||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
+xptr_error:
|
||||
+ xmlXPathReleaseObject(ctxt->context, obj);
|
||||
ctxt->context->node = oldnode;
|
||||
+ ctxt->context->contextSize = oldcs;
|
||||
+ ctxt->context->proximityPosition = oldpp;
|
||||
return (total);
|
||||
}
|
||||
#endif /* LIBXML_XPTR_ENABLED */
|
||||
@@ -13108,6 +13111,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
oldset = obj->nodesetval;
|
||||
oldnode = ctxt->context->node;
|
||||
oldDoc = ctxt->context->doc;
|
||||
+ oldcs = ctxt->context->contextSize;
|
||||
+ oldpp = ctxt->context->proximityPosition;
|
||||
|
||||
/*
|
||||
* Initialize the new set.
|
||||
@@ -13142,9 +13147,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeNodeSet(newset);
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ goto error;
|
||||
}
|
||||
/*
|
||||
* The result of the evaluation needs to be tested to
|
||||
@@ -13185,12 +13188,13 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
|
||||
/*
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
+ valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
+error:
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->contextSize = -1;
|
||||
- ctxt->context->proximityPosition = -1;
|
||||
ctxt->context->node = oldnode;
|
||||
ctxt->context->doc = oldDoc;
|
||||
- valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
+ ctxt->context->contextSize = oldcs;
|
||||
+ ctxt->context->proximityPosition = oldpp;
|
||||
}
|
||||
return(total);
|
||||
}
|
||||
@@ -13211,8 +13215,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
int equal, ret;
|
||||
xmlXPathCompExprPtr comp;
|
||||
xmlXPathObjectPtr arg1, arg2;
|
||||
- int pp;
|
||||
- int cs;
|
||||
|
||||
CHECK_ERROR0;
|
||||
comp = ctxt->comp;
|
||||
@@ -13220,16 +13222,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
case XPATH_OP_END:
|
||||
return (0);
|
||||
case XPATH_OP_AND:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
xmlXPathBooleanFunction(ctxt, 1);
|
||||
if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
|
||||
return (total);
|
||||
arg2 = valuePop(ctxt);
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
if (ctxt->error) {
|
||||
xmlXPathFreeObject(arg2);
|
||||
@@ -13242,16 +13240,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_OR:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
xmlXPathBooleanFunction(ctxt, 1);
|
||||
if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
|
||||
return (total);
|
||||
arg2 = valuePop(ctxt);
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
if (ctxt->error) {
|
||||
xmlXPathFreeObject(arg2);
|
||||
@@ -13264,12 +13258,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_EQUAL:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
CHECK_ERROR0;
|
||||
if (op->value)
|
||||
@@ -13279,25 +13269,17 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
|
||||
return (total);
|
||||
case XPATH_OP_CMP:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
CHECK_ERROR0;
|
||||
ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
|
||||
valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
|
||||
return (total);
|
||||
case XPATH_OP_PLUS:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
if (op->ch2 != -1) {
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
}
|
||||
CHECK_ERROR0;
|
||||
@@ -13313,12 +13295,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
}
|
||||
return (total);
|
||||
case XPATH_OP_MULT:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
CHECK_ERROR0;
|
||||
if (op->value == 0)
|
||||
@@ -13329,12 +13307,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathModValues(ctxt);
|
||||
return (total);
|
||||
case XPATH_OP_UNION:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
CHECK_ERROR0;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
- ctxt->context->contextSize = cs;
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
CHECK_ERROR0;
|
||||
|
||||
@@ -13489,18 +13463,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
return (total);
|
||||
}
|
||||
case XPATH_OP_ARG:
|
||||
- pp = ctxt->context->proximityPosition;
|
||||
- cs = ctxt->context->contextSize;
|
||||
if (op->ch1 != -1) {
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||
- ctxt->context->contextSize = cs;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
CHECK_ERROR0;
|
||||
}
|
||||
if (op->ch2 != -1) {
|
||||
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||
- ctxt->context->contextSize = cs;
|
||||
- ctxt->context->proximityPosition = pp;
|
||||
CHECK_ERROR0;
|
||||
}
|
||||
return (total);
|
||||
@@ -13512,6 +13480,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlNodeSetPtr oldset;
|
||||
xmlNodePtr oldnode;
|
||||
xmlDocPtr oldDoc;
|
||||
+ int oldcs, oldpp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -13636,6 +13605,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
obj = valuePop(ctxt);
|
||||
oldlocset = obj->user;
|
||||
oldnode = ctxt->context->node;
|
||||
+ oldcs = ctxt->context->contextSize;
|
||||
+ oldpp = ctxt->context->proximityPosition;
|
||||
|
||||
newlocset = xmlXPtrLocationSetCreate(NULL);
|
||||
|
||||
@@ -13656,9 +13627,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathCompOpEval(ctxt,
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ xmlXPtrFreeLocationSet(newlocset);
|
||||
+ goto filter_xptr_error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -13687,11 +13657,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
/*
|
||||
* The result is used as the new evaluation locset.
|
||||
*/
|
||||
- xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->contextSize = -1;
|
||||
- ctxt->context->proximityPosition = -1;
|
||||
valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
+filter_xptr_error:
|
||||
+ xmlXPathReleaseObject(ctxt->context, obj);
|
||||
ctxt->context->node = oldnode;
|
||||
+ ctxt->context->contextSize = oldcs;
|
||||
+ ctxt->context->proximityPosition = oldpp;
|
||||
return (total);
|
||||
}
|
||||
#endif /* LIBXML_XPTR_ENABLED */
|
||||
@@ -13709,6 +13680,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
oldset = obj->nodesetval;
|
||||
oldnode = ctxt->context->node;
|
||||
oldDoc = ctxt->context->doc;
|
||||
+ oldcs = ctxt->context->contextSize;
|
||||
+ oldpp = ctxt->context->proximityPosition;
|
||||
tmp = NULL;
|
||||
/*
|
||||
* Initialize the new set.
|
||||
@@ -13774,9 +13747,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
xmlXPathFreeNodeSet(newset);
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ goto filter_error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -13816,13 +13787,14 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
/*
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
+ valuePush(ctxt,
|
||||
+ xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
+filter_error:
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
- ctxt->context->contextSize = -1;
|
||||
- ctxt->context->proximityPosition = -1;
|
||||
ctxt->context->node = oldnode;
|
||||
ctxt->context->doc = oldDoc;
|
||||
- valuePush(ctxt,
|
||||
- xmlXPathCacheWrapNodeSet(ctxt->context, newset));
|
||||
+ ctxt->context->contextSize = oldcs;
|
||||
+ ctxt->context->proximityPosition = oldpp;
|
||||
}
|
||||
return (total);
|
||||
}
|
||||
@@ -13847,6 +13819,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlLocationSetPtr oldlocset;
|
||||
xmlNodeSetPtr oldset;
|
||||
xmlNodePtr oldnode = ctxt->context->node;
|
||||
+ int oldcs = ctxt->context->contextSize;
|
||||
+ int oldpp = ctxt->context->proximityPosition;
|
||||
int i, j;
|
||||
|
||||
if (op->ch1 != -1) {
|
||||
@@ -13894,9 +13868,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathCompOpEval(ctxt,
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ xmlXPtrFreeLocationSet(newlocset);
|
||||
+ goto rangeto_error;
|
||||
}
|
||||
|
||||
res = valuePop(ctxt);
|
||||
@@ -13958,9 +13931,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
xmlXPathCompOpEval(ctxt,
|
||||
&comp->steps[op->ch2]);
|
||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
||||
- xmlXPathFreeObject(obj);
|
||||
- ctxt->context->node = oldnode;
|
||||
- return(0);
|
||||
+ xmlXPtrFreeLocationSet(newlocset);
|
||||
+ goto rangeto_error;
|
||||
}
|
||||
|
||||
res = valuePop(ctxt);
|
||||
@@ -13988,11 +13960,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
/*
|
||||
* The result is used as the new evaluation set.
|
||||
*/
|
||||
+ valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
+rangeto_error:
|
||||
xmlXPathReleaseObject(ctxt->context, obj);
|
||||
ctxt->context->node = oldnode;
|
||||
- ctxt->context->contextSize = -1;
|
||||
- ctxt->context->proximityPosition = -1;
|
||||
- valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
|
||||
+ ctxt->context->contextSize = oldcs;
|
||||
+ ctxt->context->proximityPosition = oldpp;
|
||||
return (total);
|
||||
}
|
||||
#endif /* LIBXML_XPTR_ENABLED */
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
From 09797c139e5b0168c87f41b2cea1078d7244638d Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 5 Mar 2019 15:14:34 +0100
|
||||
Subject: [PATCH 09/37] Fix null deref in xmlregexp error path
|
||||
|
||||
Thanks to Shaobo He for the report.
|
||||
---
|
||||
xmlregexp.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||
index d255fbf..9e9c375 100644
|
||||
--- a/xmlregexp.c
|
||||
+++ b/xmlregexp.c
|
||||
@@ -5537,6 +5537,8 @@ xmlRegexpIsDeterminist(xmlRegexpPtr comp) {
|
||||
return(comp->determinist);
|
||||
|
||||
am = xmlNewAutomata();
|
||||
+ if (am == NULL)
|
||||
+ return(-1);
|
||||
if (am->states != NULL) {
|
||||
int i;
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From 35e83488505d501864826125cfe6a7950d6cba78 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Veillard <veillard@redhat.com>
|
||||
Date: Wed, 18 Apr 2018 15:58:42 +0200
|
||||
Subject: [PATCH 09/13] HTML noscript should not close p
|
||||
|
||||
For https://bugzilla.gnome.org/show_bug.cgi?id=795343
|
||||
|
||||
- HTMLparser.c: noscript should not close <p> but it should close <script>
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 7e243e60..96a1bf40 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -1084,7 +1084,7 @@ static const char * const htmlStartClose[] = {
|
||||
"menu", "p", "head", "ul", NULL,
|
||||
"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", FONTSTYLE, NULL,
|
||||
"div", "p", "head", NULL,
|
||||
-"noscript", "p", NULL,
|
||||
+"noscript", "script", NULL,
|
||||
"center", "font", "b", "i", "p", "head", NULL,
|
||||
"a", "a", "head", NULL,
|
||||
"caption", "p", NULL,
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
From d2293cdbc83b3ca79b9d7132c5a62dfd7e3751be Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Bienkowski <abenkovskii@gmail.com>
|
||||
Date: Tue, 30 Jan 2018 15:04:11 +0300
|
||||
Subject: [PATCH 10/13] Remove a misleading line from xmlCharEncOutput
|
||||
|
||||
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=793028
|
||||
|
||||
It seams this line was accidentally copied over from xmlCharEncOutFunc.
|
||||
In xmlCharEncOutput output is a pointer so incrementing it by ret can
|
||||
point it where it wasn't supposed to be pointing. Luckily the current
|
||||
implementation doesn't dereference the pointer after advancing it.
|
||||
|
||||
Signed-off-by: Daniel Veillard <veillard@redhat.com>
|
||||
---
|
||||
encoding.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/encoding.c b/encoding.c
|
||||
index de7b511a..a3aaf10e 100644
|
||||
--- a/encoding.c
|
||||
+++ b/encoding.c
|
||||
@@ -2460,8 +2460,6 @@ retry:
|
||||
ret = -3;
|
||||
}
|
||||
|
||||
- if (ret >= 0) output += ret;
|
||||
-
|
||||
/*
|
||||
* Attempt to handle error cases
|
||||
*/
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From b7c50b8ddeae4662c639369360f34b832b6b2e49 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 17 Apr 2018 12:07:08 +0200
|
||||
Subject: [PATCH 11/13] Remove stray character from comment
|
||||
|
||||
Fixes bug #795316:
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=795316
|
||||
---
|
||||
xpath.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 9d223977..3fae0bf4 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -2,7 +2,7 @@
|
||||
* xpath.c: XML Path Language implementation
|
||||
* XPath is a language for addressing parts of an XML document,
|
||||
* designed to be used by both XSLT and XPointer
|
||||
- *f
|
||||
+ *
|
||||
* Reference: W3C Recommendation 16 November 1999
|
||||
* http://www.w3.org/TR/1999/REC-xpath-19991116
|
||||
* Public reference:
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 236dd6ab2e6129ece366117070c7c014500a00c1 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 13 Mar 2019 18:21:02 +0100
|
||||
Subject: [PATCH 12/37] Check XPath stack after calling functions
|
||||
|
||||
Check that there's exactly one return value on the stack after calling
|
||||
XPath functions. Otherwise, functions that corrupt the stack without
|
||||
signaling an error could lead to memory errors.
|
||||
|
||||
Found with libFuzzer and UBSan.
|
||||
---
|
||||
xpath.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 72c6338..facd641 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -13431,6 +13431,9 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
func(ctxt, op->value);
|
||||
ctxt->context->function = oldFunc;
|
||||
ctxt->context->functionURI = oldFuncURI;
|
||||
+ if ((ctxt->error == XPATH_EXPRESSION_OK) &&
|
||||
+ (ctxt->valueNr != ctxt->valueFrame + 1))
|
||||
+ XP_ERROR0(XPATH_STACK_ERROR);
|
||||
xmlXPathPopFrame(ctxt, frame);
|
||||
return (total);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
From a436374994c47b12d5de1b8b1d191a098fa23594 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 30 Jul 2018 12:54:38 +0200
|
||||
Subject: [PATCH 12/13] Fix nullptr deref with XPath logic ops
|
||||
|
||||
If the XPath stack is corrupted, for example by a misbehaving extension
|
||||
function, the "and" and "or" XPath operators could dereference NULL
|
||||
pointers. Check that the XPath stack isn't empty and optimize the
|
||||
logic operators slightly.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/libxml2/issues/5
|
||||
|
||||
Also see
|
||||
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901817
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1595985
|
||||
|
||||
This is CVE-2018-14404.
|
||||
|
||||
Thanks to Guy Inbar for the report.
|
||||
---
|
||||
xpath.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 3fae0bf4..5e3bb9ff 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -13234,9 +13234,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
return(0);
|
||||
}
|
||||
xmlXPathBooleanFunction(ctxt, 1);
|
||||
- arg1 = valuePop(ctxt);
|
||||
- arg1->boolval &= arg2->boolval;
|
||||
- valuePush(ctxt, arg1);
|
||||
+ if (ctxt->value != NULL)
|
||||
+ ctxt->value->boolval &= arg2->boolval;
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_OR:
|
||||
@@ -13252,9 +13251,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
|
||||
return(0);
|
||||
}
|
||||
xmlXPathBooleanFunction(ctxt, 1);
|
||||
- arg1 = valuePop(ctxt);
|
||||
- arg1->boolval |= arg2->boolval;
|
||||
- valuePush(ctxt, arg1);
|
||||
+ if (ctxt->value != NULL)
|
||||
+ ctxt->value->boolval |= arg2->boolval;
|
||||
xmlXPathReleaseObject(ctxt->context, arg2);
|
||||
return (total);
|
||||
case XPATH_OP_EQUAL:
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From b9bdb9dbfda8f591f1797ad90f900bf44ad39d45 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 19 Mar 2019 17:44:51 +0100
|
||||
Subject: [PATCH 13/37] Check for integer overflow in xmlXPtrEvalChildSeq
|
||||
|
||||
Found with libFuzzer and UBSan.
|
||||
---
|
||||
xpointer.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xpointer.c b/xpointer.c
|
||||
index 6a41f07..0467411 100644
|
||||
--- a/xpointer.c
|
||||
+++ b/xpointer.c
|
||||
@@ -1202,13 +1202,23 @@ xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
|
||||
}
|
||||
|
||||
while (CUR == '/') {
|
||||
- int child = 0;
|
||||
+ int child = 0, overflow = 0;
|
||||
NEXT;
|
||||
|
||||
while ((CUR >= '0') && (CUR <= '9')) {
|
||||
- child = child * 10 + (CUR - '0');
|
||||
+ int d = CUR - '0';
|
||||
+ if (child > INT_MAX / 10)
|
||||
+ overflow = 1;
|
||||
+ else
|
||||
+ child *= 10;
|
||||
+ if (child > INT_MAX - d)
|
||||
+ overflow = 1;
|
||||
+ else
|
||||
+ child += d;
|
||||
NEXT;
|
||||
}
|
||||
+ if (overflow)
|
||||
+ child = 0;
|
||||
xmlXPtrGetChildNo(ctxt, child);
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
From 2240fbf5912054af025fb6e01e26375100275e74 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 30 Jul 2018 13:14:11 +0200
|
||||
Subject: [PATCH 13/13] Fix infinite loop in LZMA decompression
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Check the liblzma error code more thoroughly to avoid infinite loops.
|
||||
|
||||
Closes: https://gitlab.gnome.org/GNOME/libxml2/issues/13
|
||||
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=794914
|
||||
|
||||
This is CVE-2018-9251 and CVE-2018-14567.
|
||||
|
||||
Thanks to Dongliang Mu and Simon Wörner for the reports.
|
||||
---
|
||||
xzlib.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/xzlib.c b/xzlib.c
|
||||
index a839169e..0ba88cfa 100644
|
||||
--- a/xzlib.c
|
||||
+++ b/xzlib.c
|
||||
@@ -562,6 +562,10 @@ xz_decomp(xz_statep state)
|
||||
"internal error: inflate stream corrupt");
|
||||
return -1;
|
||||
}
|
||||
+ /*
|
||||
+ * FIXME: Remapping a couple of error codes and falling through
|
||||
+ * to the LZMA error handling looks fragile.
|
||||
+ */
|
||||
if (ret == Z_MEM_ERROR)
|
||||
ret = LZMA_MEM_ERROR;
|
||||
if (ret == Z_DATA_ERROR)
|
||||
@@ -587,6 +591,11 @@ xz_decomp(xz_statep state)
|
||||
xz_error(state, LZMA_PROG_ERROR, "compression error");
|
||||
return -1;
|
||||
}
|
||||
+ if ((state->how != GZIP) &&
|
||||
+ (ret != LZMA_OK) && (ret != LZMA_STREAM_END)) {
|
||||
+ xz_error(state, ret, "lzma error");
|
||||
+ return -1;
|
||||
+ }
|
||||
} while (strm->avail_out && ret != LZMA_STREAM_END);
|
||||
|
||||
/* update available output and crc check value */
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
From 93a1d2238087c3acc650ba741067f34fb94905fc Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 16 Apr 2019 13:37:47 +0200
|
||||
Subject: [PATCH 21/37] Fix memory leaks in xmlXPathParseNameComplex error
|
||||
paths
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xpath.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index a3a2aa6..1c567d7 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -10004,15 +10004,19 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
|
||||
(IS_COMBINING(c)) ||
|
||||
(IS_EXTENDER(c))) {
|
||||
if (len + 10 > max) {
|
||||
+ xmlChar *tmp;
|
||||
if (max > XML_MAX_NAME_LENGTH) {
|
||||
+ xmlFree(buffer);
|
||||
XP_ERRORNULL(XPATH_EXPR_ERROR);
|
||||
}
|
||||
max *= 2;
|
||||
- buffer = (xmlChar *) xmlRealloc(buffer,
|
||||
- max * sizeof(xmlChar));
|
||||
- if (buffer == NULL) {
|
||||
+ tmp = (xmlChar *) xmlRealloc(buffer,
|
||||
+ max * sizeof(xmlChar));
|
||||
+ if (tmp == NULL) {
|
||||
+ xmlFree(buffer);
|
||||
XP_ERRORNULL(XPATH_MEMORY_ERROR);
|
||||
}
|
||||
+ buffer = tmp;
|
||||
}
|
||||
COPY_BUF(l,buffer,len,c);
|
||||
NEXTL(l);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From 346febc6abbd63d1fa6a532c7429d2c11b5c269b Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 Apr 2019 11:34:08 +0200
|
||||
Subject: [PATCH 26/37] Fix call stack overflow in xmlFreePattern
|
||||
|
||||
Since xmlFreePattern tried to free the next pattern recursively, its
|
||||
behavior is identical to xmlFreePatternList. Make it call
|
||||
xmlFreePatternList to avoid call stack overflows.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
pattern.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/pattern.c b/pattern.c
|
||||
index 0eb8d81..fdf5c79 100644
|
||||
--- a/pattern.c
|
||||
+++ b/pattern.c
|
||||
@@ -229,13 +229,16 @@ xmlNewPattern(void) {
|
||||
*/
|
||||
void
|
||||
xmlFreePattern(xmlPatternPtr comp) {
|
||||
+ xmlFreePatternList(comp);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+xmlFreePatternInternal(xmlPatternPtr comp) {
|
||||
xmlStepOpPtr op;
|
||||
int i;
|
||||
|
||||
if (comp == NULL)
|
||||
return;
|
||||
- if (comp->next != NULL)
|
||||
- xmlFreePattern(comp->next);
|
||||
if (comp->stream != NULL)
|
||||
xmlFreeStreamComp(comp->stream);
|
||||
if (comp->pattern != NULL)
|
||||
@@ -273,7 +276,7 @@ xmlFreePatternList(xmlPatternPtr comp) {
|
||||
cur = comp;
|
||||
comp = comp->next;
|
||||
cur->next = NULL;
|
||||
- xmlFreePattern(cur);
|
||||
+ xmlFreePatternInternal(cur);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
From 3c0d62b4193c5c1fe15a143a138f76ffa1278779 Mon Sep 17 00:00:00 2001
|
||||
From: David Warring <david.warring@gmail.com>
|
||||
Date: Mon, 13 May 2019 07:15:44 +1200
|
||||
Subject: [PATCH 31/37] Fix parser termination from "Double hyphen within
|
||||
comment" error
|
||||
|
||||
The patch fixes the parser not halting immediately when the error
|
||||
handler attempts to stop the parser.
|
||||
|
||||
Rather it was running on and continuing to reference the freed buffer
|
||||
in the while loop termination test.
|
||||
|
||||
This is only a problem if xmlStopParser is called from an error
|
||||
handler. Probably caused by commit 123234f2. Fixes #58.
|
||||
---
|
||||
parser.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 5879d3b..2cab92c 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -4955,6 +4955,10 @@ get_more:
|
||||
} else
|
||||
xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
|
||||
"Double hyphen within comment\n", NULL);
|
||||
+ if (ctxt->instate == XML_PARSER_EOF) {
|
||||
+ xmlFree(buf);
|
||||
+ return;
|
||||
+ }
|
||||
in++;
|
||||
ctxt->input->col++;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
From 407b393d8023a6f20422fb3bf5806cf15ab750ad Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 15 May 2019 12:47:28 +0200
|
||||
Subject: [PATCH 32/37] Fix return value of xmlOutputBufferWrite
|
||||
|
||||
When using memory buffers, the total size of the buffer was added
|
||||
again and again, potentially leading to an integer overflow.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlIO.c | 32 ++++++++++++++++++++++----------
|
||||
1 file changed, 22 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/xmlIO.c b/xmlIO.c
|
||||
index f61dd05..a0b4532 100644
|
||||
--- a/xmlIO.c
|
||||
+++ b/xmlIO.c
|
||||
@@ -3372,20 +3372,26 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
|
||||
out->error = XML_IO_ENCODER;
|
||||
return(-1);
|
||||
}
|
||||
- nbchars = xmlBufUse(out->conv);
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->conv);
|
||||
+ else
|
||||
+ nbchars = ret;
|
||||
} else {
|
||||
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
|
||||
if (ret != 0)
|
||||
return(-1);
|
||||
- nbchars = xmlBufUse(out->buffer);
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->buffer);
|
||||
+ else
|
||||
+ nbchars = chunk;
|
||||
}
|
||||
buf += chunk;
|
||||
len -= chunk;
|
||||
|
||||
- if ((nbchars < MINLEN) && (len <= 0))
|
||||
- goto done;
|
||||
-
|
||||
if (out->writecallback) {
|
||||
+ if ((nbchars < MINLEN) && (len <= 0))
|
||||
+ goto done;
|
||||
+
|
||||
/*
|
||||
* second write the stuff to the I/O channel
|
||||
*/
|
||||
@@ -3561,21 +3567,27 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
|
||||
out->error = XML_IO_ENCODER;
|
||||
return(-1);
|
||||
}
|
||||
- nbchars = xmlBufUse(out->conv);
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->conv);
|
||||
+ else
|
||||
+ nbchars = ret;
|
||||
} else {
|
||||
ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
|
||||
if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
|
||||
return(-1);
|
||||
xmlBufAddLen(out->buffer, chunk);
|
||||
- nbchars = xmlBufUse(out->buffer);
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->buffer);
|
||||
+ else
|
||||
+ nbchars = chunk;
|
||||
}
|
||||
str += cons;
|
||||
len -= cons;
|
||||
|
||||
- if ((nbchars < MINLEN) && (len <= 0))
|
||||
- goto done;
|
||||
-
|
||||
if (out->writecallback) {
|
||||
+ if ((nbchars < MINLEN) && (len <= 0))
|
||||
+ goto done;
|
||||
+
|
||||
/*
|
||||
* second write the stuff to the I/O channel
|
||||
*/
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,171 +0,0 @@
|
||||
From f9fce963132b2a56a0f91bc19223a5c60f9786cb Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 16 May 2019 21:16:01 +0200
|
||||
Subject: [PATCH 34/37] Fix unsigned integer overflow
|
||||
|
||||
It's defined behavior but -fsanitize=unsigned-integer-overflow is
|
||||
useful to discover bugs.
|
||||
---
|
||||
parser.c | 34 ++++++++++++++++++++--------------
|
||||
result/errors/charref1.xml.err | 2 +-
|
||||
result/errors/charref1.xml.str | 2 +-
|
||||
timsort.h | 3 ++-
|
||||
uri.c | 6 ++++--
|
||||
5 files changed, 28 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 2cab92c..459502b 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -2281,9 +2281,8 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
|
||||
*/
|
||||
int
|
||||
xmlParseCharRef(xmlParserCtxtPtr ctxt) {
|
||||
- unsigned int val = 0;
|
||||
+ int val = 0;
|
||||
int count = 0;
|
||||
- unsigned int outofrange = 0;
|
||||
|
||||
/*
|
||||
* Using RAW/CUR/NEXT is okay since we are working on ASCII range here
|
||||
@@ -2310,8 +2309,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
- if (val > 0x10FFFF)
|
||||
- outofrange = val;
|
||||
+ if (val > 0x110000)
|
||||
+ val = 0x110000;
|
||||
|
||||
NEXT;
|
||||
count++;
|
||||
@@ -2339,8 +2338,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
- if (val > 0x10FFFF)
|
||||
- outofrange = val;
|
||||
+ if (val > 0x110000)
|
||||
+ val = 0x110000;
|
||||
|
||||
NEXT;
|
||||
count++;
|
||||
@@ -2360,7 +2359,11 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
|
||||
* Characters referred to using character references must match the
|
||||
* production for Char.
|
||||
*/
|
||||
- if ((IS_CHAR(val) && (outofrange == 0))) {
|
||||
+ if (val >= 0x110000) {
|
||||
+ xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
|
||||
+ "xmlParseCharRef: character reference out of bounds\n",
|
||||
+ val);
|
||||
+ } else if (IS_CHAR(val)) {
|
||||
return(val);
|
||||
} else {
|
||||
xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
|
||||
@@ -2392,8 +2395,7 @@ static int
|
||||
xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
|
||||
const xmlChar *ptr;
|
||||
xmlChar cur;
|
||||
- unsigned int val = 0;
|
||||
- unsigned int outofrange = 0;
|
||||
+ int val = 0;
|
||||
|
||||
if ((str == NULL) || (*str == NULL)) return(0);
|
||||
ptr = *str;
|
||||
@@ -2413,8 +2415,8 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
- if (val > 0x10FFFF)
|
||||
- outofrange = val;
|
||||
+ if (val > 0x110000)
|
||||
+ val = 0x110000;
|
||||
|
||||
ptr++;
|
||||
cur = *ptr;
|
||||
@@ -2432,8 +2434,8 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
|
||||
val = 0;
|
||||
break;
|
||||
}
|
||||
- if (val > 0x10FFFF)
|
||||
- outofrange = val;
|
||||
+ if (val > 0x110000)
|
||||
+ val = 0x110000;
|
||||
|
||||
ptr++;
|
||||
cur = *ptr;
|
||||
@@ -2451,7 +2453,11 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
|
||||
* Characters referred to using character references must match the
|
||||
* production for Char.
|
||||
*/
|
||||
- if ((IS_CHAR(val) && (outofrange == 0))) {
|
||||
+ if (val >= 0x110000) {
|
||||
+ xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
|
||||
+ "xmlParseStringCharRef: character reference out of bounds\n",
|
||||
+ val);
|
||||
+ } else if (IS_CHAR(val)) {
|
||||
return(val);
|
||||
} else {
|
||||
xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
|
||||
diff --git a/result/errors/charref1.xml.err b/result/errors/charref1.xml.err
|
||||
index aa43bcf..dbf3005 100644
|
||||
--- a/result/errors/charref1.xml.err
|
||||
+++ b/result/errors/charref1.xml.err
|
||||
@@ -1,3 +1,3 @@
|
||||
-./test/errors/charref1.xml:1: parser error : xmlParseCharRef: invalid xmlChar value 60
|
||||
+./test/errors/charref1.xml:1: parser error : xmlParseCharRef: character reference out of bounds
|
||||
<bla>�</bla>
|
||||
^
|
||||
diff --git a/result/errors/charref1.xml.str b/result/errors/charref1.xml.str
|
||||
index 467b4f6..692f614 100644
|
||||
--- a/result/errors/charref1.xml.str
|
||||
+++ b/result/errors/charref1.xml.str
|
||||
@@ -1,4 +1,4 @@
|
||||
-./test/errors/charref1.xml:1: parser error : xmlParseCharRef: invalid xmlChar value 60
|
||||
+./test/errors/charref1.xml:1: parser error : xmlParseCharRef: character reference out of bounds
|
||||
<bla>�</bla>
|
||||
^
|
||||
./test/errors/charref1.xml : failed to parse
|
||||
diff --git a/timsort.h b/timsort.h
|
||||
index e841bd9..622705b 100644
|
||||
--- a/timsort.h
|
||||
+++ b/timsort.h
|
||||
@@ -404,7 +404,8 @@ static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const in
|
||||
j = curr + A;
|
||||
k = curr + A + B;
|
||||
|
||||
- while (k-- > curr) {
|
||||
+ while (k > curr) {
|
||||
+ k--;
|
||||
if ((i > 0) && (j > curr)) {
|
||||
if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) {
|
||||
dst[k] = dst[--j];
|
||||
diff --git a/uri.c b/uri.c
|
||||
index 2cf8d9f..9772aaf 100644
|
||||
--- a/uri.c
|
||||
+++ b/uri.c
|
||||
@@ -325,16 +325,18 @@ static int
|
||||
xmlParse3986Port(xmlURIPtr uri, const char **str)
|
||||
{
|
||||
const char *cur = *str;
|
||||
- unsigned port = 0; /* unsigned for defined overflow behavior */
|
||||
+ int port = 0;
|
||||
|
||||
if (ISA_DIGIT(cur)) {
|
||||
while (ISA_DIGIT(cur)) {
|
||||
port = port * 10 + (*cur - '0');
|
||||
+ if (port > 99999999)
|
||||
+ port = 99999999;
|
||||
|
||||
cur++;
|
||||
}
|
||||
if (uri != NULL)
|
||||
- uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */
|
||||
+ uri->port = port;
|
||||
*str = cur;
|
||||
return(0);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
From f824a4bd4d341d765a0fb6102a03a733faa15cbb Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 20 May 2019 13:26:08 +0200
|
||||
Subject: [PATCH 37/37] Fix memory leak in xmlAllocOutputBufferInternal error
|
||||
path
|
||||
|
||||
Thanks to Anish K Kurian for the report. Closes #60.
|
||||
---
|
||||
xmlIO.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/xmlIO.c b/xmlIO.c
|
||||
index a0b4532..299b6d2 100644
|
||||
--- a/xmlIO.c
|
||||
+++ b/xmlIO.c
|
||||
@@ -2435,6 +2435,7 @@ xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) {
|
||||
if (encoder != NULL) {
|
||||
ret->conv = xmlBufCreateSize(4000);
|
||||
if (ret->conv == NULL) {
|
||||
+ xmlBufFree(ret->buffer);
|
||||
xmlFree(ret);
|
||||
return(NULL);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
110
Add-regexp-regression-tests.patch
Normal file
110
Add-regexp-regression-tests.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From 6b4717d61ddd8499872ff7249b6712732c8b11cb Mon Sep 17 00:00:00 2001
|
||||
From: David Kilzer <ddkilzer@apple.com>
|
||||
Date: Mon, 6 Jul 2020 12:36:27 +0200
|
||||
Subject: [PATCH] Add regexp regression tests
|
||||
|
||||
- Bug 757711: heap-buffer-overflow in xmlFAParsePosCharGroup
|
||||
<https://bugzilla.gnome.org/show_bug.cgi?id=757711>
|
||||
- Bug 783015 - Integer-overflow in xmlFAParseQuantExact
|
||||
<https://bugzilla.gnome.org/show_bug.cgi?id=783015>
|
||||
|
||||
(Regexptests): Add support for checking stderr output when
|
||||
running regexp tests. This makes it possible to check in test
|
||||
cases that fail and not see false-positive error output when
|
||||
running the tests. Unlike other libxml2 test suites, if there
|
||||
is no stderr output, no *.err file needs to be created.
|
||||
---
|
||||
Makefile.am | 12 +++++++-----
|
||||
result/regexp/bug757711 | 2 ++
|
||||
result/regexp/bug757711.err | 2 ++
|
||||
result/regexp/bug783015 | 4 ++++
|
||||
result/regexp/bug783015.err | 1 +
|
||||
test/regexp/bug757711 | 1 +
|
||||
test/regexp/bug783015 | 4 ++++
|
||||
7 files changed, 21 insertions(+), 5 deletions(-)
|
||||
create mode 100644 result/regexp/bug757711
|
||||
create mode 100644 result/regexp/bug757711.err
|
||||
create mode 100644 result/regexp/bug783015
|
||||
create mode 100644 result/regexp/bug783015.err
|
||||
create mode 100644 test/regexp/bug757711
|
||||
create mode 100644 test/regexp/bug783015
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 2a9d4709..76a834ef 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -907,14 +907,16 @@ Regexptests: testRegexp$(EXEEXT)
|
||||
if [ ! -d $$i ] ; then \
|
||||
if [ ! -f $(srcdir)/result/regexp/$$name ] ; then \
|
||||
echo New test file $$name ; \
|
||||
- $(CHECKER) $(top_builddir)/testRegexp -i $$i > $(srcdir)/result/regexp/$$name; \
|
||||
+ $(CHECKER) $(top_builddir)/testRegexp -i $$i > $(srcdir)/result/regexp/$$name 2> $(srcdir)/result/regexp/$$name.err ; \
|
||||
+ if [ ! -s "$(srcdir)/result/regexp/$$name.err" ] ; then rm $(srcdir)/result/regexp/$$name.err; fi ; \
|
||||
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
|
||||
else \
|
||||
- log=`$(CHECKER) $(top_builddir)/testRegexp -i $$i 2>&1 > result.$$name ; \
|
||||
+ log=`$(CHECKER) $(top_builddir)/testRegexp -i $$i > result.$$name 2> error.$$name ; \
|
||||
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
|
||||
- diff $(srcdir)/result/regexp/$$name result.$$name` ; \
|
||||
- if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
|
||||
- rm result.$$name ; \
|
||||
+ diff $(srcdir)/result/regexp/$$name result.$$name ; \
|
||||
+ if [ -s "$(srcdir)/result/regexp/$$name.err" -o -s "error.$$name" ] ; then diff $(srcdir)/result/regexp/$$name.err error.$$name ; fi` ; \
|
||||
+ if [ -n "$$log" ] ; then echo $$name result ; echo $$log ; fi ; \
|
||||
+ rm result.$$name error.$$name ; \
|
||||
fi ; fi ; done)
|
||||
|
||||
# Disabled for now
|
||||
diff --git a/result/regexp/bug757711 b/result/regexp/bug757711
|
||||
new file mode 100644
|
||||
index 00000000..0991e4e2
|
||||
--- /dev/null
|
||||
+++ b/result/regexp/bug757711
|
||||
@@ -0,0 +1,2 @@
|
||||
+Regexp: [;^((-
|
||||
+ failed to compile
|
||||
diff --git a/result/regexp/bug757711.err b/result/regexp/bug757711.err
|
||||
new file mode 100644
|
||||
index 00000000..f1cae806
|
||||
--- /dev/null
|
||||
+++ b/result/regexp/bug757711.err
|
||||
@@ -0,0 +1,2 @@
|
||||
+regexp error : failed to compile: Expecting the end of a char range
|
||||
+regexp error : failed to compile: xmlFAParseCharClass: ']' expected
|
||||
diff --git a/result/regexp/bug783015 b/result/regexp/bug783015
|
||||
new file mode 100644
|
||||
index 00000000..653f6f09
|
||||
--- /dev/null
|
||||
+++ b/result/regexp/bug783015
|
||||
@@ -0,0 +1,4 @@
|
||||
+Regexp: .{2147483647}
|
||||
+input: Fail
|
||||
+Regexp: .{2147483648}
|
||||
+ failed to compile
|
||||
diff --git a/result/regexp/bug783015.err b/result/regexp/bug783015.err
|
||||
new file mode 100644
|
||||
index 00000000..a00edc98
|
||||
--- /dev/null
|
||||
+++ b/result/regexp/bug783015.err
|
||||
@@ -0,0 +1 @@
|
||||
+regexp error : failed to compile: Improper quantifier
|
||||
diff --git a/test/regexp/bug757711 b/test/regexp/bug757711
|
||||
new file mode 100644
|
||||
index 00000000..29098354
|
||||
--- /dev/null
|
||||
+++ b/test/regexp/bug757711
|
||||
@@ -0,0 +1 @@
|
||||
+=>[;^((-
|
||||
diff --git a/test/regexp/bug783015 b/test/regexp/bug783015
|
||||
new file mode 100644
|
||||
index 00000000..5c91a0f1
|
||||
--- /dev/null
|
||||
+++ b/test/regexp/bug783015
|
||||
@@ -0,0 +1,4 @@
|
||||
+# This assumes 32-bit ints.
|
||||
+=>.{2147483647}
|
||||
+input
|
||||
+=>.{2147483648}
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,150 +0,0 @@
|
||||
From d459831c1b308c2095a1b73800e0238269d4106a Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 13 Oct 2018 16:12:14 +0200
|
||||
Subject: [PATCH 32/62] Fix HTML serialization with UTF-8 encoding
|
||||
|
||||
If the encoding is specified as UTF-8, make sure to use a NULL encoding
|
||||
handler.
|
||||
---
|
||||
HTMLtree.c | 84 ++++++++++++++++++++++++++++++--------------------------------
|
||||
1 file changed, 40 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/HTMLtree.c b/HTMLtree.c
|
||||
index 6a2f43d..21cfcfe 100644
|
||||
--- a/HTMLtree.c
|
||||
+++ b/HTMLtree.c
|
||||
@@ -502,17 +502,17 @@ htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc,
|
||||
if (handler == NULL)
|
||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
||||
}
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
+ */
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("HTML");
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("ascii");
|
||||
}
|
||||
|
||||
/*
|
||||
- * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
- */
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("HTML");
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("ascii");
|
||||
-
|
||||
- /*
|
||||
* save the content to a temp buffer.
|
||||
*/
|
||||
buf = xmlOutputBufferCreateFile(out, handler);
|
||||
@@ -575,19 +575,17 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) {
|
||||
if (handler == NULL)
|
||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
||||
|
||||
- } else {
|
||||
- handler = xmlFindCharEncodingHandler(encoding);
|
||||
}
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
+ */
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("HTML");
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("ascii");
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
- */
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("HTML");
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("ascii");
|
||||
-
|
||||
buf = xmlAllocOutputBufferInternal(handler);
|
||||
if (buf == NULL) {
|
||||
*mem = NULL;
|
||||
@@ -1096,19 +1094,17 @@ htmlDocDump(FILE *f, xmlDocPtr cur) {
|
||||
handler = xmlFindCharEncodingHandler(encoding);
|
||||
if (handler == NULL)
|
||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
||||
- } else {
|
||||
- handler = xmlFindCharEncodingHandler(encoding);
|
||||
}
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
+ */
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("HTML");
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("ascii");
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
- */
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("HTML");
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("ascii");
|
||||
-
|
||||
buf = xmlOutputBufferCreateFile(f, handler);
|
||||
if (buf == NULL) return(-1);
|
||||
htmlDocContentDumpOutput(buf, cur, NULL);
|
||||
@@ -1149,17 +1145,17 @@ htmlSaveFile(const char *filename, xmlDocPtr cur) {
|
||||
if (handler == NULL)
|
||||
htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
|
||||
}
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
+ */
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("HTML");
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("ascii");
|
||||
}
|
||||
|
||||
/*
|
||||
- * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
- */
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("HTML");
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("ascii");
|
||||
-
|
||||
- /*
|
||||
* save the content to a temp buffer.
|
||||
*/
|
||||
buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
|
||||
@@ -1206,15 +1202,15 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur,
|
||||
htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
|
||||
} else {
|
||||
htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
|
||||
- }
|
||||
|
||||
- /*
|
||||
- * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
- */
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("HTML");
|
||||
- if (handler == NULL)
|
||||
- handler = xmlFindCharEncodingHandler("ascii");
|
||||
+ /*
|
||||
+ * Fallback to HTML or ASCII when the encoding is unspecified
|
||||
+ */
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("HTML");
|
||||
+ if (handler == NULL)
|
||||
+ handler = xmlFindCharEncodingHandler("ascii");
|
||||
+ }
|
||||
|
||||
/*
|
||||
* save the content to a temp buffer.
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
From 157cd3aed70845564e2ecc9754f3f826a3c9c65e Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 24 Nov 2018 15:46:00 +0100
|
||||
Subject: [PATCH 50/62] Fix NULL pointer deref in xmlTextReaderValidateEntity
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 4461b36..3acec75 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -1114,11 +1114,11 @@ xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
|
||||
continue;
|
||||
} else {
|
||||
/*
|
||||
- * The error has probably be raised already.
|
||||
+ * The error has probably been raised already.
|
||||
*/
|
||||
if (node == oldnode)
|
||||
break;
|
||||
- node = node->next;
|
||||
+ goto skip_children;
|
||||
}
|
||||
#ifdef LIBXML_REGEXP_ENABLED
|
||||
} else if (node->type == XML_ELEMENT_NODE) {
|
||||
@@ -1140,6 +1140,7 @@ xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
|
||||
} else if (node->type == XML_ELEMENT_NODE) {
|
||||
xmlTextReaderValidatePop(reader);
|
||||
}
|
||||
+skip_children:
|
||||
if (node->next != NULL) {
|
||||
node = node->next;
|
||||
continue;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
From 26828cb3a1294e09e42064f4769d4b3c0a8623b3 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 7 Jan 2019 16:52:42 +0100
|
||||
Subject: [PATCH 59/62] Fix commit "Memory leak in xmlFreeID (xmlreader.c)"
|
||||
|
||||
The recent commit "Memory leak in xmlFreeID (xmlreader.c)" introduced
|
||||
a double-free.
|
||||
---
|
||||
xmlreader.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 3acec75..cd1fb5f 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -273,6 +273,7 @@ xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
|
||||
return(-1);
|
||||
}
|
||||
id->name = attr->name;
|
||||
+ attr->name = NULL;
|
||||
id->attr = NULL;
|
||||
return(0);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
44
Fix-integer-overflow-in-xmlFAParseQuantExact.patch
Normal file
44
Fix-integer-overflow-in-xmlFAParseQuantExact.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 1e7851b5aea4b2d8b9a6b6c02187fc4786f7a8b7 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 Jun 2020 12:17:50 +0200
|
||||
Subject: [PATCH] Fix integer overflow in xmlFAParseQuantExact
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlregexp.c | 15 +++++++++++++--
|
||||
1 file changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||
index 53fa145c..0272dcab 100644
|
||||
--- a/xmlregexp.c
|
||||
+++ b/xmlregexp.c
|
||||
@@ -5211,13 +5211,24 @@ static int
|
||||
xmlFAParseQuantExact(xmlRegParserCtxtPtr ctxt) {
|
||||
int ret = 0;
|
||||
int ok = 0;
|
||||
+ int overflow = 0;
|
||||
|
||||
while ((CUR >= '0') && (CUR <= '9')) {
|
||||
- ret = ret * 10 + (CUR - '0');
|
||||
+ if (ret > INT_MAX / 10) {
|
||||
+ overflow = 1;
|
||||
+ } else {
|
||||
+ int digit = CUR - '0';
|
||||
+
|
||||
+ ret *= 10;
|
||||
+ if (ret > INT_MAX - digit)
|
||||
+ overflow = 1;
|
||||
+ else
|
||||
+ ret += digit;
|
||||
+ }
|
||||
ok = 1;
|
||||
NEXT;
|
||||
}
|
||||
- if (ok != 1) {
|
||||
+ if ((ok != 1) || (overflow == 1)) {
|
||||
return(-1);
|
||||
}
|
||||
return(ret);
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
From f2bbca92d9dddca8807f6402b8fe0ac162a29269 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Wed, 7 Aug 2019 17:39:17 +0800
|
||||
Subject: [PATCH] Fix memory leak in xmlParseBalancedChunkMemoryRecover
|
||||
|
||||
When doc is NULL, namespace created in xmlTreeEnsureXMLDecl
|
||||
is bind to newDoc->oldNs, in this case, set newDoc->oldNs to
|
||||
NULL and free newDoc will cause a memory leak.
|
||||
|
||||
Found with libFuzzer.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
parser.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 1ce1ccf..73b96ca 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -13894,7 +13894,8 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
|
||||
xmlFreeParserCtxt(ctxt);
|
||||
newDoc->intSubset = NULL;
|
||||
newDoc->extSubset = NULL;
|
||||
- newDoc->oldNs = NULL;
|
||||
+ if(doc != NULL)
|
||||
+ newDoc->oldNs = NULL;
|
||||
xmlFreeDoc(newDoc);
|
||||
|
||||
return(ret);
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From b7520f8a61b48a9f265f711fa7a0bebf2175bed7 Mon Sep 17 00:00:00 2001
|
||||
From: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
Date: Tue, 20 Aug 2019 16:33:06 +0800
|
||||
Subject: [PATCH] Fix memory leak in xmlSchemaValidateStream
|
||||
|
||||
When ctxt->schema is NULL, xmlSchemaSAXPlug->xmlSchemaPreRun
|
||||
alloc a new schema for ctxt->schema and set vctxt->xsiAssemble
|
||||
to 1. Then xmlSchemaVStart->xmlSchemaPreRun initialize
|
||||
vctxt->xsiAssemble to 0 again which cause the alloced schema
|
||||
can not be freed anymore.
|
||||
|
||||
Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com>
|
||||
---
|
||||
xmlschemas.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index 019988a..005d8f1 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -28111,7 +28111,6 @@ xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
|
||||
vctxt->nberrors = 0;
|
||||
vctxt->depth = -1;
|
||||
vctxt->skipDepth = -1;
|
||||
- vctxt->xsiAssemble = 0;
|
||||
vctxt->hasKeyrefs = 0;
|
||||
#ifdef ENABLE_IDC_NODE_TABLES_TEST
|
||||
vctxt->createIDCNodeTables = 1;
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
From 3776cb4745cecd8f477b45857c9033a908f25cf3 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 22 Nov 2018 15:27:28 +0100
|
||||
Subject: [PATCH 35/62] Fix memory leak in xmlSwitchInputEncodingInt error path
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
parserInternals.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/parserInternals.c b/parserInternals.c
|
||||
index 09876ab..0f015de 100644
|
||||
--- a/parserInternals.c
|
||||
+++ b/parserInternals.c
|
||||
@@ -1240,8 +1240,18 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
|
||||
* size to be able to convert the buffer.
|
||||
*/
|
||||
xmlErrInternal(ctxt, "switching encoding : no input\n", NULL);
|
||||
+ /*
|
||||
+ * Callers assume that the input buffer takes ownership of the
|
||||
+ * encoding handler. xmlCharEncCloseFunc frees unregistered
|
||||
+ * handlers and avoids a memory leak.
|
||||
+ */
|
||||
+ xmlCharEncCloseFunc(handler);
|
||||
return (-1);
|
||||
}
|
||||
+ /*
|
||||
+ * We should actually raise an error here, see issue #34.
|
||||
+ */
|
||||
+ xmlCharEncCloseFunc(handler);
|
||||
return (0);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From b48226f78c626a0fdbaed65793f1a6138de8558f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 7 Jan 2019 17:58:32 +0100
|
||||
Subject: [PATCH 61/62] Fix memory leaks in xmlParseStartTag2 error paths
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
parser.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index c424412..5879d3b 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -9247,7 +9247,8 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
|
||||
xmlErrMemory(ctxt, "dictionary allocation failure");
|
||||
if ((attvalue != NULL) && (alloc != 0))
|
||||
xmlFree(attvalue);
|
||||
- return(NULL);
|
||||
+ localname = NULL;
|
||||
+ goto done;
|
||||
}
|
||||
if (*URL != 0) {
|
||||
uri = xmlParseURI((const char *) URL);
|
||||
@@ -9497,7 +9498,8 @@ next_attr:
|
||||
|
||||
if ((atts == NULL) || (nbatts + 5 > maxatts)) {
|
||||
if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
|
||||
- return(NULL);
|
||||
+ localname = NULL;
|
||||
+ goto done;
|
||||
}
|
||||
maxatts = ctxt->maxatts;
|
||||
atts = ctxt->atts;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
From b697d7bb5953faa2e699aafcca4058f4caffe734 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hildstrom <ghildstrom@forcepoint.com>
|
||||
Date: Tue, 4 Sep 2018 16:48:15 +0200
|
||||
Subject: [PATCH 22/62] Fix xmlSchemaValidCtxtPtr reuse memory leak
|
||||
|
||||
When reusing an xmlSchemaValidCtxtPtr to validate multiple xml documents
|
||||
against the same schema, there is a memory leak in xmlschemas.c in
|
||||
xmlSchemaClearValidCtxt(). The vctxt->idcKeys and associated counters
|
||||
are not cleaned up in xmlSchemaClearValidCtxt() as they are in
|
||||
xmlSchemaFreeValidCtxt(). As a result, vctxt->idcKeys grows with each
|
||||
xmlValidateDoc() call that uses the same context and that memory is
|
||||
never freed. Similarly, vctxt->nbIdcKeys and vctxt->sizeIdcKeys
|
||||
increment and are never reset.
|
||||
|
||||
Closes: #23
|
||||
---
|
||||
xmlschemas.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index 405f72a..019988a 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -27653,6 +27653,17 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
|
||||
vctxt->nbIdcNodes = 0;
|
||||
vctxt->sizeIdcNodes = 0;
|
||||
}
|
||||
+
|
||||
+ if (vctxt->idcKeys != NULL) {
|
||||
+ int i;
|
||||
+ for (i = 0; i < vctxt->nbIdcKeys; i++)
|
||||
+ xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
|
||||
+ xmlFree(vctxt->idcKeys);
|
||||
+ vctxt->idcKeys = NULL;
|
||||
+ vctxt->nbIdcKeys = 0;
|
||||
+ vctxt->sizeIdcKeys = 0;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Note that we won't delete the XPath state pool here.
|
||||
*/
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From efe8c093c408311ddbb6995c92a9e077386a57bf Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 24 Nov 2018 11:39:32 +0100
|
||||
Subject: [PATCH 48/62] Memory leak in xmlFreeID (xmlreader.c)
|
||||
|
||||
Fix a memory leak in xmlReader's private copy of xmlFreeID. Only
|
||||
affects validation with NODICT.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index db310c8..5e486c6 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -238,6 +238,8 @@ xmlFreeID(xmlIDPtr id) {
|
||||
|
||||
if (id->value != NULL)
|
||||
DICT_FREE(id->value)
|
||||
+ if (id->name != NULL)
|
||||
+ DICT_FREE(id->name)
|
||||
xmlFree(id);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
From 57a3af56f4ee4418948dfbff8c02ae1d79de565e Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 24 Nov 2018 12:14:55 +0100
|
||||
Subject: [PATCH 49/62] Memory leak in xmlFreeTextReader
|
||||
|
||||
In error cases, there might still be elements in the vstate table.
|
||||
Since vstateVPop in valid.c is private, we have to pop the elements
|
||||
with xmlValidatePopElement. This inspects nodes of the document, so
|
||||
the reader doc must be freed after the clearing the vstate table.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 12 +++++++-----
|
||||
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 5e486c6..4461b36 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -2264,17 +2264,19 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
|
||||
if (reader->ctxt != NULL) {
|
||||
if (reader->dict == reader->ctxt->dict)
|
||||
reader->dict = NULL;
|
||||
- if (reader->ctxt->myDoc != NULL) {
|
||||
- if (reader->preserve == 0)
|
||||
- xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
|
||||
- reader->ctxt->myDoc = NULL;
|
||||
- }
|
||||
if ((reader->ctxt->vctxt.vstateTab != NULL) &&
|
||||
(reader->ctxt->vctxt.vstateMax > 0)){
|
||||
+ while (reader->ctxt->vctxt.vstateNr > 0)
|
||||
+ xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
|
||||
xmlFree(reader->ctxt->vctxt.vstateTab);
|
||||
reader->ctxt->vctxt.vstateTab = NULL;
|
||||
reader->ctxt->vctxt.vstateMax = 0;
|
||||
}
|
||||
+ if (reader->ctxt->myDoc != NULL) {
|
||||
+ if (reader->preserve == 0)
|
||||
+ xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
|
||||
+ reader->ctxt->myDoc = NULL;
|
||||
+ }
|
||||
if (reader->allocs & XML_TEXTREADER_CTXT)
|
||||
xmlFreeParserCtxt(reader->ctxt);
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
From d2293cdbc83b3ca79b9d7132c5a62dfd7e3751be Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Bienkowski <abenkovskii@gmail.com>
|
||||
Date: Tue, 30 Jan 2018 15:04:11 +0300
|
||||
Subject: [PATCH 11/62] Remove a misleading line from xmlCharEncOutput
|
||||
|
||||
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=793028
|
||||
|
||||
It seams this line was accidentally copied over from xmlCharEncOutFunc.
|
||||
In xmlCharEncOutput output is a pointer so incrementing it by ret can
|
||||
point it where it wasn't supposed to be pointing. Luckily the current
|
||||
implementation doesn't dereference the pointer after advancing it.
|
||||
|
||||
Signed-off-by: Daniel Veillard <veillard@redhat.com>
|
||||
---
|
||||
encoding.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
diff --git a/encoding.c b/encoding.c
|
||||
index de7b511..a3aaf10 100644
|
||||
--- a/encoding.c
|
||||
+++ b/encoding.c
|
||||
@@ -2460,8 +2460,6 @@ retry:
|
||||
ret = -3;
|
||||
}
|
||||
|
||||
- if (ret >= 0) output += ret;
|
||||
-
|
||||
/*
|
||||
* Attempt to handle error cases
|
||||
*/
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
26
Report-error-for-invalid-regexp-quantifiers.patch
Normal file
26
Report-error-for-invalid-regexp-quantifiers.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From f8329fdc234a43b858271acc75ea70881e35fcae Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 2 Jul 2020 11:51:31 +0200
|
||||
Subject: [PATCH] Report error for invalid regexp quantifiers
|
||||
|
||||
---
|
||||
xmlregexp.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||
index 0272dcab..687290e2 100644
|
||||
--- a/xmlregexp.c
|
||||
+++ b/xmlregexp.c
|
||||
@@ -5268,6 +5268,9 @@ xmlFAParseQuantifier(xmlRegParserCtxtPtr ctxt) {
|
||||
cur = xmlFAParseQuantExact(ctxt);
|
||||
if (cur >= 0)
|
||||
min = cur;
|
||||
+ else {
|
||||
+ ERROR("Improper quantifier");
|
||||
+ }
|
||||
if (CUR == ',') {
|
||||
NEXT;
|
||||
if (CUR == '}')
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
From 60173c821eff9e01f1b8bab4f722150a4c3cf82f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 11 Sep 2018 14:08:39 +0200
|
||||
Subject: [PATCH 24/62] Reset HTML parser input pointers on encoding failure
|
||||
|
||||
Call xmlBufResetInput before bailing out if switching the encoding
|
||||
fails. Otherwise, the input pointers could be left in an invalid state.
|
||||
|
||||
Similar to commit f9e7997e803457b714352c4d51a96104ae298d94 for the
|
||||
XML parser.
|
||||
|
||||
Thanks to Yunho Kim for the report.
|
||||
|
||||
Closes: #27
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 96a1bf4..9e60e27 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -3636,12 +3636,12 @@ htmlCheckEncodingDirect(htmlParserCtxtPtr ctxt, const xmlChar *encoding) {
|
||||
processed = ctxt->input->cur - ctxt->input->base;
|
||||
xmlBufShrink(ctxt->input->buf->buffer, processed);
|
||||
nbchars = xmlCharEncInput(ctxt->input->buf, 1);
|
||||
+ xmlBufResetInput(ctxt->input->buf->buffer, ctxt->input);
|
||||
if (nbchars < 0) {
|
||||
htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
|
||||
"htmlCheckEncoding: encoder error\n",
|
||||
NULL, NULL);
|
||||
}
|
||||
- xmlBufResetInput(ctxt->input->buf->buffer, ctxt->input);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
From 44e7a0d5f7a7e2c167a8a4196a5358830f695ab0 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 16 May 2019 21:17:28 +0200
|
||||
Subject: [PATCH] Annotate functions with __attribute__((no_sanitize))
|
||||
|
||||
---
|
||||
dict.c | 2 ++
|
||||
hash.c | 2 ++
|
||||
libxml.h | 7 +++++++
|
||||
xpath.c | 1 +
|
||||
4 files changed, 12 insertions(+)
|
||||
|
||||
diff --git a/dict.c b/dict.c
|
||||
index 14fe398..13a7b93 100644
|
||||
--- a/dict.c
|
||||
+++ b/dict.c
|
||||
@@ -372,6 +372,7 @@ found_pool:
|
||||
* http://burtleburtle.net/bob/hash/doobs.html
|
||||
*/
|
||||
|
||||
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
static uint32_t
|
||||
xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
||||
uint32_t hash;
|
||||
@@ -404,6 +405,7 @@ xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
||||
*
|
||||
* Neither of the two strings must be NULL.
|
||||
*/
|
||||
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
static unsigned long
|
||||
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
|
||||
const xmlChar *name, int len, int seed)
|
||||
diff --git a/hash.c b/hash.c
|
||||
index 1145cb9..f037af6 100644
|
||||
--- a/hash.c
|
||||
+++ b/hash.c
|
||||
@@ -79,6 +79,7 @@ struct _xmlHashTable {
|
||||
* xmlHashComputeKey:
|
||||
* Calculate the hash key
|
||||
*/
|
||||
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
static unsigned long
|
||||
xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
|
||||
const xmlChar *name2, const xmlChar *name3) {
|
||||
@@ -109,6 +110,7 @@ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
|
||||
return (value % table->size);
|
||||
}
|
||||
|
||||
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
static unsigned long
|
||||
xmlHashComputeQKey(xmlHashTablePtr table,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
diff --git a/libxml.h b/libxml.h
|
||||
index 64e30f7..7762331 100644
|
||||
--- a/libxml.h
|
||||
+++ b/libxml.h
|
||||
@@ -72,6 +72,13 @@ int vfprintf(FILE *, const char *, va_list);
|
||||
#define XML_POP_WARNINGS
|
||||
#endif
|
||||
|
||||
+#if defined(__clang__) || \
|
||||
+ (defined(__GNUC__) && (__GNUC__ >= 8))
|
||||
+#define ATTRIBUTE_NO_SANITIZE(arg) __attribute__((no_sanitize(arg)))
|
||||
+#else
|
||||
+#define ATTRIBUTE_NO_SANITIZE(arg)
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Internal variable indicating if a callback has been registered for
|
||||
* node creation/destruction. It avoids spending a lot of time in locking
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 031772c..e68975e 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -7497,6 +7497,7 @@ xmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
|
||||
* The numeric operators convert their operands to numbers as if
|
||||
* by calling the number function.
|
||||
*/
|
||||
+ATTRIBUTE_NO_SANITIZE("float-divide-by-zero")
|
||||
void
|
||||
xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
|
||||
xmlXPathObjectPtr arg;
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From 443fd9665e9471b8083e2b5770f14f200b880381 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 29 Oct 2019 16:19:37 +0100
|
||||
Subject: [PATCH 3/3] Another fix for conditional sections at end of document
|
||||
|
||||
The previous fix introduced an uninitialized read.
|
||||
|
||||
backport from https://gitlab.gnome.org/GNOME/libxml2/commit/9737ec071786c29788b9aa0971156f9e19a9c6a0
|
||||
---
|
||||
parser.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index f188c9d..84f1723 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -6725,6 +6725,7 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
|
||||
|
||||
if (RAW == 0) {
|
||||
xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
|
||||
+ goto error;
|
||||
}
|
||||
if (ctxt->input->id != id) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
--
|
||||
2.18.1
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
From b88ae6d2e1c9f22931f59ff1ec490befe201fb26 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 14 Oct 2019 15:38:28 +0200
|
||||
Subject: [PATCH] Avoid ignored attribute warnings under GCC
|
||||
|
||||
GCC doesn't support the unsigned-integer-overflow sanitizer.
|
||||
---
|
||||
dict.c | 4 ++++
|
||||
hash.c | 4 ++++
|
||||
2 files changed, 8 insertions(+)
|
||||
|
||||
diff --git a/dict.c b/dict.c
|
||||
index fb0773b..336e046 100644
|
||||
--- a/dict.c
|
||||
+++ b/dict.c
|
||||
@@ -372,7 +372,9 @@ found_pool:
|
||||
* http://burtleburtle.net/bob/hash/doobs.html
|
||||
*/
|
||||
|
||||
+#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
+#endif
|
||||
static uint32_t
|
||||
xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
||||
uint32_t hash;
|
||||
@@ -405,7 +407,9 @@ xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
|
||||
*
|
||||
* Neither of the two strings must be NULL.
|
||||
*/
|
||||
+#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
+#endif
|
||||
static unsigned long
|
||||
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
|
||||
const xmlChar *name, int len, int seed)
|
||||
diff --git a/hash.c b/hash.c
|
||||
index f037af6..a83d979 100644
|
||||
--- a/hash.c
|
||||
+++ b/hash.c
|
||||
@@ -79,7 +79,9 @@ struct _xmlHashTable {
|
||||
* xmlHashComputeKey:
|
||||
* Calculate the hash key
|
||||
*/
|
||||
+#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
+#endif
|
||||
static unsigned long
|
||||
xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
|
||||
const xmlChar *name2, const xmlChar *name3) {
|
||||
@@ -110,7 +112,9 @@ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
|
||||
return (value % table->size);
|
||||
}
|
||||
|
||||
+#ifdef __clang__
|
||||
ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
|
||||
+#endif
|
||||
static unsigned long
|
||||
xmlHashComputeQKey(xmlHashTablePtr table,
|
||||
const xmlChar *prefix, const xmlChar *name,
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
From 2b9fee2b0baf675b38b5e11756e9339d14c27a3a Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 23 Oct 2019 11:40:34 +0200
|
||||
Subject: [PATCH 2/3] Fix for conditional sections at end of document
|
||||
|
||||
Parsing conditional sections would fail if the final ']]>' was at the
|
||||
end of the document. Short-lived regression caused by commit c51e38cb.
|
||||
|
||||
backport from https://gitlab.gnome.org/GNOME/libxml2/commit/c1035664f989c2ac7ca31407bc6f0b48396db42c
|
||||
---
|
||||
parser.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index bfa6585..f188c9d 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -6723,6 +6723,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
|
||||
ctxt->disableSAX = state;
|
||||
ctxt->instate = instate;
|
||||
|
||||
+ if (RAW == 0) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
|
||||
+ }
|
||||
if (ctxt->input->id != id) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
"All markup of the conditional section is"
|
||||
@@ -6763,10 +6766,6 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
|
||||
GROW;
|
||||
}
|
||||
|
||||
- if (RAW == 0) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
|
||||
- }
|
||||
-
|
||||
error:
|
||||
xmlFree(inputIds);
|
||||
}
|
||||
--
|
||||
2.18.1
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
From 664f881008f40356c0502c8cc154e17e3c80e353 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 26 Sep 2019 11:01:58 +0200
|
||||
Subject: [PATCH] Fix use-after-free in xmlTextReaderFreeNodeList
|
||||
|
||||
Recent commit 1fbcf40 caused a use-after-free read because it didn't
|
||||
account for the fact that xmlTextReaderFreeDoc frees entities before
|
||||
freeing entity references via xmlTextReaderFreeNodeList.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 9229c18..b505f16 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -367,10 +367,10 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
- while ((cur->children != NULL) &&
|
||||
- (cur->children->parent == cur) &&
|
||||
- (cur->type != XML_DTD_NODE) &&
|
||||
- (cur->type != XML_ENTITY_REF_NODE)) {
|
||||
+ while ((cur->type != XML_DTD_NODE) &&
|
||||
+ (cur->type != XML_ENTITY_REF_NODE) &&
|
||||
+ (cur->children != NULL) &&
|
||||
+ (cur->children->parent == cur)) {
|
||||
cur = cur->children;
|
||||
depth += 1;
|
||||
}
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,211 +0,0 @@
|
||||
From 3be39335ced799eb1ec312b7b542c84dac4ebd57 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Fri, 4 Oct 2019 14:42:59 +0200
|
||||
Subject: [PATCH] Make xmlDumpElementContent non-recursive
|
||||
|
||||
Avoid call stack overflow when dumping deeply nested element
|
||||
declarations.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
backport from https://gitlab.gnome.org/GNOME/libxml2/commit/24e3973bc03c15d534b2eac6e70fc2b2bef2b6c0
|
||||
---
|
||||
valid.c | 157 ++++++++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 89 insertions(+), 68 deletions(-)
|
||||
|
||||
diff --git a/valid.c b/valid.c
|
||||
index b1cfede..632c5e7 100644
|
||||
--- a/valid.c
|
||||
+++ b/valid.c
|
||||
@@ -1148,83 +1148,104 @@ xmlFreeElementContent(xmlElementContentPtr cur) {
|
||||
|
||||
#ifdef LIBXML_OUTPUT_ENABLED
|
||||
/**
|
||||
- * xmlDumpElementContent:
|
||||
+ * xmlDumpElementOccur:
|
||||
* @buf: An XML buffer
|
||||
- * @content: An element table
|
||||
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
|
||||
+ * @cur: An element table
|
||||
*
|
||||
- * This will dump the content of the element table as an XML DTD definition
|
||||
+ * Dump the occurence operator of an element.
|
||||
*/
|
||||
static void
|
||||
-xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
|
||||
- if (content == NULL) return;
|
||||
-
|
||||
- if (glob) xmlBufferWriteChar(buf, "(");
|
||||
- switch (content->type) {
|
||||
- case XML_ELEMENT_CONTENT_PCDATA:
|
||||
- xmlBufferWriteChar(buf, "#PCDATA");
|
||||
- break;
|
||||
- case XML_ELEMENT_CONTENT_ELEMENT:
|
||||
- if (content->prefix != NULL) {
|
||||
- xmlBufferWriteCHAR(buf, content->prefix);
|
||||
- xmlBufferWriteChar(buf, ":");
|
||||
- }
|
||||
- xmlBufferWriteCHAR(buf, content->name);
|
||||
- break;
|
||||
- case XML_ELEMENT_CONTENT_SEQ:
|
||||
- if ((content->c1 != NULL) &&
|
||||
- ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
|
||||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
|
||||
- xmlDumpElementContent(buf, content->c1, 1);
|
||||
- else
|
||||
- xmlDumpElementContent(buf, content->c1, 0);
|
||||
- xmlBufferWriteChar(buf, " , ");
|
||||
- if ((content->c2 != NULL) &&
|
||||
- ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
|
||||
- ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
|
||||
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
|
||||
- xmlDumpElementContent(buf, content->c2, 1);
|
||||
- else
|
||||
- xmlDumpElementContent(buf, content->c2, 0);
|
||||
- break;
|
||||
- case XML_ELEMENT_CONTENT_OR:
|
||||
- if ((content->c1 != NULL) &&
|
||||
- ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
|
||||
- (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
|
||||
- xmlDumpElementContent(buf, content->c1, 1);
|
||||
- else
|
||||
- xmlDumpElementContent(buf, content->c1, 0);
|
||||
- xmlBufferWriteChar(buf, " | ");
|
||||
- if ((content->c2 != NULL) &&
|
||||
- ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
|
||||
- ((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
|
||||
- (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
|
||||
- xmlDumpElementContent(buf, content->c2, 1);
|
||||
- else
|
||||
- xmlDumpElementContent(buf, content->c2, 0);
|
||||
- break;
|
||||
- default:
|
||||
- xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
|
||||
- "Internal: ELEMENT content corrupted invalid type\n",
|
||||
- NULL);
|
||||
- }
|
||||
- if (glob)
|
||||
- xmlBufferWriteChar(buf, ")");
|
||||
- switch (content->ocur) {
|
||||
+xmlDumpElementOccur(xmlBufferPtr buf, xmlElementContentPtr cur) {
|
||||
+ switch (cur->ocur) {
|
||||
case XML_ELEMENT_CONTENT_ONCE:
|
||||
- break;
|
||||
+ break;
|
||||
case XML_ELEMENT_CONTENT_OPT:
|
||||
- xmlBufferWriteChar(buf, "?");
|
||||
- break;
|
||||
+ xmlBufferWriteChar(buf, "?");
|
||||
+ break;
|
||||
case XML_ELEMENT_CONTENT_MULT:
|
||||
- xmlBufferWriteChar(buf, "*");
|
||||
- break;
|
||||
+ xmlBufferWriteChar(buf, "*");
|
||||
+ break;
|
||||
case XML_ELEMENT_CONTENT_PLUS:
|
||||
- xmlBufferWriteChar(buf, "+");
|
||||
- break;
|
||||
+ xmlBufferWriteChar(buf, "+");
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * xmlDumpElementContent:
|
||||
+ * @buf: An XML buffer
|
||||
+ * @content: An element table
|
||||
+ *
|
||||
+ * This will dump the content of the element table as an XML DTD definition
|
||||
+ */
|
||||
+static void
|
||||
+xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content) {
|
||||
+ xmlElementContentPtr cur;
|
||||
+
|
||||
+ if (content == NULL) return;
|
||||
+
|
||||
+ xmlBufferWriteChar(buf, "(");
|
||||
+ cur = content;
|
||||
+
|
||||
+ do {
|
||||
+ if (cur == NULL) return;
|
||||
+
|
||||
+ switch (cur->type) {
|
||||
+ case XML_ELEMENT_CONTENT_PCDATA:
|
||||
+ xmlBufferWriteChar(buf, "#PCDATA");
|
||||
+ break;
|
||||
+ case XML_ELEMENT_CONTENT_ELEMENT:
|
||||
+ if (cur->prefix != NULL) {
|
||||
+ xmlBufferWriteCHAR(buf, cur->prefix);
|
||||
+ xmlBufferWriteChar(buf, ":");
|
||||
+ }
|
||||
+ xmlBufferWriteCHAR(buf, cur->name);
|
||||
+ break;
|
||||
+ case XML_ELEMENT_CONTENT_SEQ:
|
||||
+ case XML_ELEMENT_CONTENT_OR:
|
||||
+ if ((cur != content) &&
|
||||
+ (cur->parent != NULL) &&
|
||||
+ ((cur->type != cur->parent->type) ||
|
||||
+ (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
|
||||
+ xmlBufferWriteChar(buf, "(");
|
||||
+ cur = cur->c1;
|
||||
+ continue;
|
||||
+ default:
|
||||
+ xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
|
||||
+ "Internal: ELEMENT cur corrupted invalid type\n",
|
||||
+ NULL);
|
||||
+ }
|
||||
+
|
||||
+ while (cur != content) {
|
||||
+ xmlElementContentPtr parent = cur->parent;
|
||||
+
|
||||
+ if (parent == NULL) return;
|
||||
+
|
||||
+ if (((cur->type == XML_ELEMENT_CONTENT_OR) ||
|
||||
+ (cur->type == XML_ELEMENT_CONTENT_SEQ)) &&
|
||||
+ ((cur->type != parent->type) ||
|
||||
+ (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
|
||||
+ xmlBufferWriteChar(buf, ")");
|
||||
+ xmlDumpElementOccur(buf, cur);
|
||||
+
|
||||
+ if (cur == parent->c1) {
|
||||
+ if (parent->type == XML_ELEMENT_CONTENT_SEQ)
|
||||
+ xmlBufferWriteChar(buf, " , ");
|
||||
+ else if (parent->type == XML_ELEMENT_CONTENT_OR)
|
||||
+ xmlBufferWriteChar(buf, " | ");
|
||||
+
|
||||
+ cur = parent->c2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ cur = parent;
|
||||
+ }
|
||||
+ } while (cur != content);
|
||||
+
|
||||
+ xmlBufferWriteChar(buf, ")");
|
||||
+ xmlDumpElementOccur(buf, content);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* xmlSprintfElementContent:
|
||||
* @buf: an output buffer
|
||||
@@ -1703,7 +1724,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
|
||||
}
|
||||
xmlBufferWriteCHAR(buf, elem->name);
|
||||
xmlBufferWriteChar(buf, " ");
|
||||
- xmlDumpElementContent(buf, elem->content, 1);
|
||||
+ xmlDumpElementContent(buf, elem->content);
|
||||
xmlBufferWriteChar(buf, ">\n");
|
||||
break;
|
||||
case XML_ELEMENT_TYPE_ELEMENT:
|
||||
@@ -1714,7 +1735,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
|
||||
}
|
||||
xmlBufferWriteCHAR(buf, elem->name);
|
||||
xmlBufferWriteChar(buf, " ");
|
||||
- xmlDumpElementContent(buf, elem->content, 1);
|
||||
+ xmlDumpElementContent(buf, elem->content);
|
||||
xmlBufferWriteChar(buf, ">\n");
|
||||
break;
|
||||
default:
|
||||
--
|
||||
2.18.1
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
From 0762c9b69ba01628f72eada1c64ff3d361fb5716 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 23 Sep 2019 17:07:40 +0200
|
||||
Subject: [PATCH 2/3] Make xmlFreeNodeList non-recursive
|
||||
|
||||
Avoid call stack overflow when freeing deeply nested documents.
|
||||
---
|
||||
tree.c | 26 +++++++++++++++++++++-----
|
||||
1 file changed, 21 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tree.c b/tree.c
|
||||
index bba0614..4781326 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -3664,7 +3664,9 @@ xmlNextElementSibling(xmlNodePtr node) {
|
||||
void
|
||||
xmlFreeNodeList(xmlNodePtr cur) {
|
||||
xmlNodePtr next;
|
||||
+ xmlNodePtr parent;
|
||||
xmlDictPtr dict = NULL;
|
||||
+ size_t depth = 0;
|
||||
|
||||
if (cur == NULL) return;
|
||||
if (cur->type == XML_NAMESPACE_DECL) {
|
||||
@@ -3680,16 +3682,21 @@ xmlFreeNodeList(xmlNodePtr cur) {
|
||||
return;
|
||||
}
|
||||
if (cur->doc != NULL) dict = cur->doc->dict;
|
||||
- while (cur != NULL) {
|
||||
+ while (1) {
|
||||
+ while ((cur->children != NULL) &&
|
||||
+ (cur->type != XML_DTD_NODE) &&
|
||||
+ (cur->type != XML_ENTITY_REF_NODE)) {
|
||||
+ cur = cur->children;
|
||||
+ depth += 1;
|
||||
+ }
|
||||
+
|
||||
next = cur->next;
|
||||
+ parent = cur->parent;
|
||||
if (cur->type != XML_DTD_NODE) {
|
||||
|
||||
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
|
||||
xmlDeregisterNodeDefaultValue(cur);
|
||||
|
||||
- if ((cur->children != NULL) &&
|
||||
- (cur->type != XML_ENTITY_REF_NODE))
|
||||
- xmlFreeNodeList(cur->children);
|
||||
if (((cur->type == XML_ELEMENT_NODE) ||
|
||||
(cur->type == XML_XINCLUDE_START) ||
|
||||
(cur->type == XML_XINCLUDE_END)) &&
|
||||
@@ -3720,7 +3727,16 @@ xmlFreeNodeList(xmlNodePtr cur) {
|
||||
DICT_FREE(cur->name)
|
||||
xmlFree(cur);
|
||||
}
|
||||
- cur = next;
|
||||
+
|
||||
+ if (next != NULL) {
|
||||
+ cur = next;
|
||||
+ } else {
|
||||
+ if ((depth == 0) || (parent == NULL))
|
||||
+ break;
|
||||
+ depth -= 1;
|
||||
+ cur = parent;
|
||||
+ cur->children = NULL;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,510 +0,0 @@
|
||||
From 94aa233233dac8d6f497f6584d183e3b5cc2a0f8 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 30 Sep 2019 13:50:02 +0200
|
||||
Subject: [PATCH] Make xmlParseConditionalSections non-recursive
|
||||
|
||||
Avoid call stack overflow in deeply nested conditional sections.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
backport from https://gitlab.gnome.org/GNOME/libxml2/commit/c51e38cb3a808e315248e03c9e52bce08943c22b
|
||||
---
|
||||
parser.c | 265 ++++++++++++++--------------
|
||||
result/errors/759573-2.xml.err | 10 --
|
||||
result/errors/759573.xml.err | 13 --
|
||||
result/valid/cond_sect1.xml | 8 +
|
||||
result/valid/cond_sect1.xml.err | 0
|
||||
result/valid/cond_sect1.xml.err.rdr | 0
|
||||
result/valid/cond_sect2.xml | 0
|
||||
result/valid/cond_sect2.xml.err | 9 +
|
||||
result/valid/cond_sect2.xml.err.rdr | 10 ++
|
||||
test/valid/cond_sect1.xml | 7 +
|
||||
test/valid/cond_sect2.xml | 4 +
|
||||
test/valid/dtds/cond_sect1.dtd | 20 +++
|
||||
test/valid/dtds/cond_sect2.dtd | 16 ++
|
||||
13 files changed, 203 insertions(+), 159 deletions(-)
|
||||
create mode 100644 result/valid/cond_sect1.xml
|
||||
create mode 100644 result/valid/cond_sect1.xml.err
|
||||
create mode 100644 result/valid/cond_sect1.xml.err.rdr
|
||||
create mode 100644 result/valid/cond_sect2.xml
|
||||
create mode 100644 result/valid/cond_sect2.xml.err
|
||||
create mode 100644 result/valid/cond_sect2.xml.err.rdr
|
||||
create mode 100644 test/valid/cond_sect1.xml
|
||||
create mode 100644 test/valid/cond_sect2.xml
|
||||
create mode 100644 test/valid/dtds/cond_sect1.dtd
|
||||
create mode 100644 test/valid/dtds/cond_sect2.dtd
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 9fb14fe..bfa6585 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -6632,149 +6632,143 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) {
|
||||
|
||||
static void
|
||||
xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
|
||||
- int id = ctxt->input->id;
|
||||
+ int *inputIds = NULL;
|
||||
+ size_t inputIdsSize = 0;
|
||||
+ size_t depth = 0;
|
||||
|
||||
- SKIP(3);
|
||||
- SKIP_BLANKS;
|
||||
- if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
|
||||
- SKIP(7);
|
||||
- SKIP_BLANKS;
|
||||
- if (RAW != '[') {
|
||||
- xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
|
||||
- xmlHaltParser(ctxt);
|
||||
- return;
|
||||
- } else {
|
||||
- if (ctxt->input->id != id) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
- "All markup of the conditional section is not"
|
||||
- " in the same entity\n");
|
||||
- }
|
||||
- NEXT;
|
||||
- }
|
||||
- if (xmlParserDebugEntities) {
|
||||
- if ((ctxt->input != NULL) && (ctxt->input->filename))
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "%s(%d): ", ctxt->input->filename,
|
||||
- ctxt->input->line);
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "Entering INCLUDE Conditional Section\n");
|
||||
- }
|
||||
+ while (ctxt->instate != XML_PARSER_EOF) {
|
||||
+ if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
+ int id = ctxt->input->id;
|
||||
|
||||
- SKIP_BLANKS;
|
||||
- GROW;
|
||||
- while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
|
||||
- (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
|
||||
- const xmlChar *check = CUR_PTR;
|
||||
- unsigned int cons = ctxt->input->consumed;
|
||||
+ SKIP(3);
|
||||
+ SKIP_BLANKS;
|
||||
|
||||
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
- xmlParseConditionalSections(ctxt);
|
||||
- } else
|
||||
- xmlParseMarkupDecl(ctxt);
|
||||
+ if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
|
||||
+ SKIP(7);
|
||||
+ SKIP_BLANKS;
|
||||
+ if (RAW != '[') {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
|
||||
+ xmlHaltParser(ctxt);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ if (ctxt->input->id != id) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
+ "All markup of the conditional section is"
|
||||
+ " not in the same entity\n");
|
||||
+ }
|
||||
+ NEXT;
|
||||
|
||||
- SKIP_BLANKS;
|
||||
- GROW;
|
||||
+ if (inputIdsSize <= depth) {
|
||||
+ int *tmp;
|
||||
|
||||
- if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
|
||||
- xmlHaltParser(ctxt);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- if (xmlParserDebugEntities) {
|
||||
- if ((ctxt->input != NULL) && (ctxt->input->filename))
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "%s(%d): ", ctxt->input->filename,
|
||||
- ctxt->input->line);
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "Leaving INCLUDE Conditional Section\n");
|
||||
- }
|
||||
+ inputIdsSize = (inputIdsSize == 0 ? 4 : inputIdsSize * 2);
|
||||
+ tmp = (int *) xmlRealloc(inputIds,
|
||||
+ inputIdsSize * sizeof(int));
|
||||
+ if (tmp == NULL) {
|
||||
+ xmlErrMemory(ctxt, NULL);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ inputIds = tmp;
|
||||
+ }
|
||||
+ inputIds[depth] = id;
|
||||
+ depth++;
|
||||
+ } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
|
||||
+ int state;
|
||||
+ xmlParserInputState instate;
|
||||
+ size_t ignoreDepth = 0;
|
||||
+
|
||||
+ SKIP(6);
|
||||
+ SKIP_BLANKS;
|
||||
+ if (RAW != '[') {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
|
||||
+ xmlHaltParser(ctxt);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ if (ctxt->input->id != id) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
+ "All markup of the conditional section is"
|
||||
+ " not in the same entity\n");
|
||||
+ }
|
||||
+ NEXT;
|
||||
|
||||
- } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
|
||||
- int state;
|
||||
- xmlParserInputState instate;
|
||||
- int depth = 0;
|
||||
+ /*
|
||||
+ * Parse up to the end of the conditional section but disable
|
||||
+ * SAX event generating DTD building in the meantime
|
||||
+ */
|
||||
+ state = ctxt->disableSAX;
|
||||
+ instate = ctxt->instate;
|
||||
+ if (ctxt->recovery == 0) ctxt->disableSAX = 1;
|
||||
+ ctxt->instate = XML_PARSER_IGNORE;
|
||||
+
|
||||
+ while (RAW != 0) {
|
||||
+ if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
+ SKIP(3);
|
||||
+ ignoreDepth++;
|
||||
+ /* Check for integer overflow */
|
||||
+ if (ignoreDepth == 0) {
|
||||
+ xmlErrMemory(ctxt, NULL);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ } else if ((RAW == ']') && (NXT(1) == ']') &&
|
||||
+ (NXT(2) == '>')) {
|
||||
+ if (ignoreDepth == 0)
|
||||
+ break;
|
||||
+ SKIP(3);
|
||||
+ ignoreDepth--;
|
||||
+ } else {
|
||||
+ NEXT;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- SKIP(6);
|
||||
- SKIP_BLANKS;
|
||||
- if (RAW != '[') {
|
||||
- xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
|
||||
- xmlHaltParser(ctxt);
|
||||
- return;
|
||||
- } else {
|
||||
- if (ctxt->input->id != id) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
- "All markup of the conditional section is not"
|
||||
- " in the same entity\n");
|
||||
- }
|
||||
- NEXT;
|
||||
- }
|
||||
- if (xmlParserDebugEntities) {
|
||||
- if ((ctxt->input != NULL) && (ctxt->input->filename))
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "%s(%d): ", ctxt->input->filename,
|
||||
- ctxt->input->line);
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "Entering IGNORE Conditional Section\n");
|
||||
- }
|
||||
+ ctxt->disableSAX = state;
|
||||
+ ctxt->instate = instate;
|
||||
|
||||
- /*
|
||||
- * Parse up to the end of the conditional section
|
||||
- * But disable SAX event generating DTD building in the meantime
|
||||
- */
|
||||
- state = ctxt->disableSAX;
|
||||
- instate = ctxt->instate;
|
||||
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
|
||||
- ctxt->instate = XML_PARSER_IGNORE;
|
||||
+ if (ctxt->input->id != id) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
+ "All markup of the conditional section is"
|
||||
+ " not in the same entity\n");
|
||||
+ }
|
||||
+ SKIP(3);
|
||||
+ } else {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
|
||||
+ xmlHaltParser(ctxt);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ } else if ((depth > 0) &&
|
||||
+ (RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
|
||||
+ depth--;
|
||||
+ if (ctxt->input->id != inputIds[depth]) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
+ "All markup of the conditional section is not"
|
||||
+ " in the same entity\n");
|
||||
+ }
|
||||
+ SKIP(3);
|
||||
+ } else {
|
||||
+ const xmlChar *check = CUR_PTR;
|
||||
+ unsigned int cons = ctxt->input->consumed;
|
||||
|
||||
- while (((depth >= 0) && (RAW != 0)) &&
|
||||
- (ctxt->instate != XML_PARSER_EOF)) {
|
||||
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
- depth++;
|
||||
- SKIP(3);
|
||||
- continue;
|
||||
- }
|
||||
- if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
|
||||
- if (--depth >= 0) SKIP(3);
|
||||
- continue;
|
||||
- }
|
||||
- NEXT;
|
||||
- continue;
|
||||
- }
|
||||
+ xmlParseMarkupDecl(ctxt);
|
||||
|
||||
- ctxt->disableSAX = state;
|
||||
- ctxt->instate = instate;
|
||||
+ if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
|
||||
+ xmlHaltParser(ctxt);
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (xmlParserDebugEntities) {
|
||||
- if ((ctxt->input != NULL) && (ctxt->input->filename))
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "%s(%d): ", ctxt->input->filename,
|
||||
- ctxt->input->line);
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "Leaving IGNORE Conditional Section\n");
|
||||
- }
|
||||
+ if (depth == 0)
|
||||
+ break;
|
||||
|
||||
- } else {
|
||||
- xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
|
||||
- xmlHaltParser(ctxt);
|
||||
- return;
|
||||
+ SKIP_BLANKS;
|
||||
+ GROW;
|
||||
}
|
||||
|
||||
- if (RAW == 0)
|
||||
- SHRINK;
|
||||
-
|
||||
if (RAW == 0) {
|
||||
xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
|
||||
- } else {
|
||||
- if (ctxt->input->id != id) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
|
||||
- "All markup of the conditional section is not in"
|
||||
- " the same entity\n");
|
||||
- }
|
||||
- if ((ctxt-> instate != XML_PARSER_EOF) &&
|
||||
- ((ctxt->input->cur + 3) <= ctxt->input->end))
|
||||
- SKIP(3);
|
||||
}
|
||||
+
|
||||
+error:
|
||||
+ xmlFree(inputIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6836,16 +6830,6 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return;
|
||||
|
||||
- /*
|
||||
- * Conditional sections are allowed from entities included
|
||||
- * by PE References in the internal subset.
|
||||
- */
|
||||
- if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
|
||||
- if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
- xmlParseConditionalSections(ctxt);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
ctxt->instate = XML_PARSER_DTD;
|
||||
}
|
||||
|
||||
@@ -8306,6 +8290,15 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
|
||||
xmlParseMarkupDecl(ctxt);
|
||||
xmlParsePEReference(ctxt);
|
||||
|
||||
+ /*
|
||||
+ * Conditional sections are allowed from entities included
|
||||
+ * by PE References in the internal subset.
|
||||
+ */
|
||||
+ if ((ctxt->inputNr > 1) &&
|
||||
+ (RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
|
||||
+ xmlParseConditionalSections(ctxt);
|
||||
+ }
|
||||
+
|
||||
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
|
||||
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
|
||||
"xmlParseInternalSubset: error detected in Markup declaration\n");
|
||||
diff --git a/result/errors/759573-2.xml.err b/result/errors/759573-2.xml.err
|
||||
index 86d6420..ecaf18f 100644
|
||||
--- a/result/errors/759573-2.xml.err
|
||||
+++ b/result/errors/759573-2.xml.err
|
||||
@@ -46,13 +46,3 @@ Entity: line 3:
|
||||
Entity: line 3:
|
||||
%zz;<!ELEMENTD(%MENT%MENTDŹMENTD%zNMT9KENSMYSYSTEM;MENT9%zz;
|
||||
^
|
||||
-./test/errors/759573-2.xml:6: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
|
||||
-
|
||||
-
|
||||
-^
|
||||
-./test/errors/759573-2.xml:6: parser error : DOCTYPE improperly terminated
|
||||
-
|
||||
-^
|
||||
-./test/errors/759573-2.xml:6: parser error : Start tag expected, '<' not found
|
||||
-
|
||||
-^
|
||||
diff --git a/result/errors/759573.xml.err b/result/errors/759573.xml.err
|
||||
index 554039f..2617cad 100644
|
||||
--- a/result/errors/759573.xml.err
|
||||
+++ b/result/errors/759573.xml.err
|
||||
@@ -19,16 +19,3 @@ T t (A)><!ENTITY % xx '%<![INCLUDE[000%ஸ000%z;'><!ENTITYz>%xx;
|
||||
Entity: line 1:
|
||||
%<![INCLUDE[000%ஸ000%z;
|
||||
^
|
||||
-./test/errors/759573.xml:1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
|
||||
-
|
||||
-<?h?><!DOCTYPEt[<!ELEMENT t (A)><!ENTITY % xx '%<![INCLUDE[000%ஸ00
|
||||
- ^
|
||||
-./test/errors/759573.xml:1: parser error : DOCTYPE improperly terminated
|
||||
-<?h?><!DOCTYPEt[<!ELEMENT t (A)><!ENTITY % xx '%<![INCLUDE[000%ஸ00
|
||||
- ^
|
||||
-./test/errors/759573.xml:1: parser error : StartTag: invalid element name
|
||||
-<?h?><!DOCTYPEt[<!ELEMENT t (A)><!ENTITY % xx '%<![INCLUDE[000%ஸ00
|
||||
- ^
|
||||
-./test/errors/759573.xml:1: parser error : Extra content at the end of the document
|
||||
-<?h?><!DOCTYPEt[<!ELEMENT t (A)><!ENTITY % xx '%<![INCLUDE[000%ஸ00
|
||||
- ^
|
||||
diff --git a/result/valid/cond_sect1.xml b/result/valid/cond_sect1.xml
|
||||
new file mode 100644
|
||||
index 0000000..dd2e5b4
|
||||
--- /dev/null
|
||||
+++ b/result/valid/cond_sect1.xml
|
||||
@@ -0,0 +1,8 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!DOCTYPE doc SYSTEM "dtds/cond_sect1.dtd" [
|
||||
+<!ENTITY % include "INCLUDE">
|
||||
+<!ENTITY % ignore "IGNORE">
|
||||
+]>
|
||||
+<doc>
|
||||
+ <child>text</child>
|
||||
+</doc>
|
||||
diff --git a/result/valid/cond_sect1.xml.err b/result/valid/cond_sect1.xml.err
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/result/valid/cond_sect1.xml.err.rdr b/result/valid/cond_sect1.xml.err.rdr
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/result/valid/cond_sect2.xml b/result/valid/cond_sect2.xml
|
||||
new file mode 100644
|
||||
index 0000000..e69de29
|
||||
diff --git a/result/valid/cond_sect2.xml.err b/result/valid/cond_sect2.xml.err
|
||||
new file mode 100644
|
||||
index 0000000..9a7624b
|
||||
--- /dev/null
|
||||
+++ b/result/valid/cond_sect2.xml.err
|
||||
@@ -0,0 +1,9 @@
|
||||
+test/valid/dtds/cond_sect2.dtd:15: parser error : All markup of the conditional section is not in the same entity
|
||||
+ %ent;
|
||||
+ ^
|
||||
+Entity: line 1:
|
||||
+]]>
|
||||
+^
|
||||
+test/valid/dtds/cond_sect2.dtd:17: parser error : Content error in the external subset
|
||||
+
|
||||
+^
|
||||
diff --git a/result/valid/cond_sect2.xml.err.rdr b/result/valid/cond_sect2.xml.err.rdr
|
||||
new file mode 100644
|
||||
index 0000000..fd3cb75
|
||||
--- /dev/null
|
||||
+++ b/result/valid/cond_sect2.xml.err.rdr
|
||||
@@ -0,0 +1,10 @@
|
||||
+test/valid/dtds/cond_sect2.dtd:15: parser error : All markup of the conditional section is not in the same entity
|
||||
+ %ent;
|
||||
+ ^
|
||||
+Entity: line 1:
|
||||
+]]>
|
||||
+^
|
||||
+test/valid/dtds/cond_sect2.dtd:17: parser error : Content error in the external subset
|
||||
+
|
||||
+^
|
||||
+./test/valid/cond_sect2.xml : failed to parse
|
||||
diff --git a/test/valid/cond_sect1.xml b/test/valid/cond_sect1.xml
|
||||
new file mode 100644
|
||||
index 0000000..796faa4
|
||||
--- /dev/null
|
||||
+++ b/test/valid/cond_sect1.xml
|
||||
@@ -0,0 +1,7 @@
|
||||
+<!DOCTYPE doc SYSTEM "dtds/cond_sect1.dtd" [
|
||||
+ <!ENTITY % include "INCLUDE">
|
||||
+ <!ENTITY % ignore "IGNORE">
|
||||
+]>
|
||||
+<doc>
|
||||
+ <child>text</child>
|
||||
+</doc>
|
||||
diff --git a/test/valid/cond_sect2.xml b/test/valid/cond_sect2.xml
|
||||
new file mode 100644
|
||||
index 0000000..5153d05
|
||||
--- /dev/null
|
||||
+++ b/test/valid/cond_sect2.xml
|
||||
@@ -0,0 +1,4 @@
|
||||
+<!DOCTYPE doc SYSTEM "dtds/cond_sect2.dtd">
|
||||
+<doc>
|
||||
+ <child>text</child>
|
||||
+</doc>
|
||||
diff --git a/test/valid/dtds/cond_sect1.dtd b/test/valid/dtds/cond_sect1.dtd
|
||||
new file mode 100644
|
||||
index 0000000..e327022
|
||||
--- /dev/null
|
||||
+++ b/test/valid/dtds/cond_sect1.dtd
|
||||
@@ -0,0 +1,20 @@
|
||||
+<![ %include; [
|
||||
+ <![%include; [
|
||||
+ <![ %include;[
|
||||
+ <![%include;[
|
||||
+ <!ELEMENT doc (child)>
|
||||
+ <!ELEMENT child (#PCDATA)>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+]]>
|
||||
+<![ %ignore; [
|
||||
+ <![%include; [
|
||||
+ <![ %include;[
|
||||
+ <![%ignore;[
|
||||
+ <!ELEMENT doc (x)>
|
||||
+ <!ELEMENT child (y)>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+]]>
|
||||
diff --git a/test/valid/dtds/cond_sect2.dtd b/test/valid/dtds/cond_sect2.dtd
|
||||
new file mode 100644
|
||||
index 0000000..29eb4bf
|
||||
--- /dev/null
|
||||
+++ b/test/valid/dtds/cond_sect2.dtd
|
||||
@@ -0,0 +1,16 @@
|
||||
+<!ENTITY % ent "]]>">
|
||||
+<![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ <![INCLUDE[
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ ]]>
|
||||
+ %ent;
|
||||
+]]>
|
||||
--
|
||||
2.18.1
|
||||
|
||||
@ -1,286 +0,0 @@
|
||||
From 62150ed2ab19a4dd76c15acc62c7d923d9f3b2cc Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 23 Sep 2019 14:46:41 +0200
|
||||
Subject: [PATCH 1/3] Make xmlParseContent and xmlParseElement non-recursive
|
||||
|
||||
Split xmlParseElement into subfunctions. Use nameNsPush to store prefix,
|
||||
URI and nsNr on the heap, similar to the push parser.
|
||||
|
||||
Closes #84.
|
||||
---
|
||||
parser.c | 121 +++++++++++++++++++++++++------------------
|
||||
result/errors/754947.xml.err | 2 +-
|
||||
result/errors/759398.xml.err | 4 +-
|
||||
3 files changed, 74 insertions(+), 53 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 5b8df8c..cad0a9d 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -96,6 +96,12 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
|
||||
|
||||
static void xmlHaltParser(xmlParserCtxtPtr ctxt);
|
||||
|
||||
+static int
|
||||
+xmlParseElementStart(xmlParserCtxtPtr ctxt);
|
||||
+
|
||||
+static void
|
||||
+xmlParseElementEnd(xmlParserCtxtPtr ctxt);
|
||||
+
|
||||
/************************************************************************
|
||||
* *
|
||||
* Arbitrary limits set in the parser. See XML_PARSE_HUGE *
|
||||
@@ -1822,7 +1828,6 @@ nodePop(xmlParserCtxtPtr ctxt)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
-#ifdef LIBXML_PUSH_ENABLED
|
||||
/**
|
||||
* nameNsPush:
|
||||
* @ctxt: an XML parser context
|
||||
@@ -1858,6 +1863,11 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
|
||||
goto mem_error;
|
||||
}
|
||||
ctxt->pushTab = tmp2;
|
||||
+ } else if (ctxt->pushTab == NULL) {
|
||||
+ ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
|
||||
+ sizeof(ctxt->pushTab[0]));
|
||||
+ if (ctxt->pushTab == NULL)
|
||||
+ goto mem_error;
|
||||
}
|
||||
ctxt->nameTab[ctxt->nameNr] = value;
|
||||
ctxt->name = value;
|
||||
@@ -1869,6 +1879,7 @@ mem_error:
|
||||
xmlErrMemory(ctxt, NULL);
|
||||
return (-1);
|
||||
}
|
||||
+#ifdef LIBXML_PUSH_ENABLED
|
||||
/**
|
||||
* nameNsPop:
|
||||
* @ctxt: an XML parser context
|
||||
@@ -9812,9 +9823,10 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
|
||||
void
|
||||
xmlParseContent(xmlParserCtxtPtr ctxt) {
|
||||
+ int nameNr = ctxt->nameNr;
|
||||
+
|
||||
GROW;
|
||||
while ((RAW != 0) &&
|
||||
- ((RAW != '<') || (NXT(1) != '/')) &&
|
||||
(ctxt->instate != XML_PARSER_EOF)) {
|
||||
const xmlChar *test = CUR_PTR;
|
||||
unsigned int cons = ctxt->input->consumed;
|
||||
@@ -9848,7 +9860,13 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
|
||||
* Fourth case : a sub-element.
|
||||
*/
|
||||
else if (*cur == '<') {
|
||||
- xmlParseElement(ctxt);
|
||||
+ if (NXT(1) == '/') {
|
||||
+ if (ctxt->nameNr <= nameNr)
|
||||
+ break;
|
||||
+ xmlParseElementEnd(ctxt);
|
||||
+ } else {
|
||||
+ xmlParseElementStart(ctxt);
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9883,7 +9901,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
|
||||
* xmlParseElement:
|
||||
* @ctxt: an XML parser context
|
||||
*
|
||||
- * parse an XML element, this is highly recursive
|
||||
+ * parse an XML element
|
||||
*
|
||||
* [39] element ::= EmptyElemTag | STag content ETag
|
||||
*
|
||||
@@ -9895,6 +9913,23 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
|
||||
|
||||
void
|
||||
xmlParseElement(xmlParserCtxtPtr ctxt) {
|
||||
+ if (xmlParseElementStart(ctxt) != 0)
|
||||
+ return;
|
||||
+ xmlParseContent(ctxt);
|
||||
+ if (ctxt->instate == XML_PARSER_EOF)
|
||||
+ return;
|
||||
+ xmlParseElementEnd(ctxt);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * xmlParseElementStart:
|
||||
+ * @ctxt: an XML parser context
|
||||
+ *
|
||||
+ * Parse the start of an XML element. Returns -1 in case of error, 0 if an
|
||||
+ * opening tag was parsed, 1 if an empty element was parsed.
|
||||
+ */
|
||||
+static int
|
||||
+xmlParseElementStart(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *name;
|
||||
const xmlChar *prefix = NULL;
|
||||
const xmlChar *URI = NULL;
|
||||
@@ -9909,7 +9944,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
|
||||
"Excessive depth in document: %d use XML_PARSE_HUGE option\n",
|
||||
xmlParserMaxDepth);
|
||||
xmlHaltParser(ctxt);
|
||||
- return;
|
||||
+ return(-1);
|
||||
}
|
||||
|
||||
/* Capture start position */
|
||||
@@ -9936,12 +9971,17 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
|
||||
name = xmlParseStartTag(ctxt);
|
||||
#endif /* LIBXML_SAX1_ENABLED */
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
- return;
|
||||
+ return(-1);
|
||||
if (name == NULL) {
|
||||
spacePop(ctxt);
|
||||
- return;
|
||||
+ return(-1);
|
||||
}
|
||||
- namePush(ctxt, name);
|
||||
+ if (ctxt->sax2)
|
||||
+ nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
|
||||
+#ifdef LIBXML_SAX1_ENABLED
|
||||
+ else
|
||||
+ namePush(ctxt, name);
|
||||
+#endif /* LIBXML_SAX1_ENABLED */
|
||||
ret = ctxt->node;
|
||||
|
||||
#ifdef LIBXML_VALID_ENABLED
|
||||
@@ -9982,7 +10022,7 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
|
||||
node_info.node = ret;
|
||||
xmlParserAddNodeInfo(ctxt, &node_info);
|
||||
}
|
||||
- return;
|
||||
+ return(1);
|
||||
}
|
||||
if (RAW == '>') {
|
||||
NEXT1;
|
||||
@@ -10010,41 +10050,39 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
|
||||
node_info.node = ret;
|
||||
xmlParserAddNodeInfo(ctxt, &node_info);
|
||||
}
|
||||
- return;
|
||||
+ return(-1);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Parse the content of the element:
|
||||
- */
|
||||
- xmlParseContent(ctxt);
|
||||
- if (ctxt->instate == XML_PARSER_EOF)
|
||||
- return;
|
||||
- if (!IS_BYTE_CHAR(RAW)) {
|
||||
- xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
|
||||
- "Premature end of data in tag %s line %d\n",
|
||||
- name, line, NULL);
|
||||
+ return(0);
|
||||
+}
|
||||
|
||||
- /*
|
||||
- * end of parsing of this node.
|
||||
- */
|
||||
- nodePop(ctxt);
|
||||
- namePop(ctxt);
|
||||
- spacePop(ctxt);
|
||||
- if (nsNr != ctxt->nsNr)
|
||||
- nsPop(ctxt, ctxt->nsNr - nsNr);
|
||||
- return;
|
||||
- }
|
||||
+/**
|
||||
+ * xmlParseElementEnd:
|
||||
+ * @ctxt: an XML parser context
|
||||
+ *
|
||||
+ * Parse the end of an XML element.
|
||||
+ */
|
||||
+static void
|
||||
+xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
|
||||
+ xmlParserNodeInfo node_info;
|
||||
+ xmlNodePtr ret = ctxt->node;
|
||||
+
|
||||
+ if (ctxt->nameNr <= 0)
|
||||
+ return;
|
||||
|
||||
/*
|
||||
* parse the end of tag: '</' should be here.
|
||||
*/
|
||||
if (ctxt->sax2) {
|
||||
- xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
|
||||
+ const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 3 - 3];
|
||||
+ const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 3 - 2];
|
||||
+ int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 3 - 1];
|
||||
+ xmlParseEndTag2(ctxt, prefix, URI, 0, nsNr, 0);
|
||||
namePop(ctxt);
|
||||
}
|
||||
#ifdef LIBXML_SAX1_ENABLED
|
||||
- else
|
||||
- xmlParseEndTag1(ctxt, line);
|
||||
+ else
|
||||
+ xmlParseEndTag1(ctxt, 0);
|
||||
#endif /* LIBXML_SAX1_ENABLED */
|
||||
|
||||
/*
|
||||
@@ -12361,13 +12399,6 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
|
||||
return(NULL);
|
||||
}
|
||||
ctxt->dictNames = 1;
|
||||
- ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
|
||||
- if (ctxt->pushTab == NULL) {
|
||||
- xmlErrMemory(ctxt, NULL);
|
||||
- xmlFreeParserInputBuffer(buf);
|
||||
- xmlFreeParserCtxt(ctxt);
|
||||
- return(NULL);
|
||||
- }
|
||||
if (sax != NULL) {
|
||||
#ifdef LIBXML_SAX1_ENABLED
|
||||
if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
|
||||
@@ -14949,16 +14980,6 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
|
||||
|
||||
xmlCtxtReset(ctxt);
|
||||
|
||||
- if (ctxt->pushTab == NULL) {
|
||||
- ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
|
||||
- sizeof(xmlChar *));
|
||||
- if (ctxt->pushTab == NULL) {
|
||||
- xmlErrMemory(ctxt, NULL);
|
||||
- xmlFreeParserInputBuffer(buf);
|
||||
- return(1);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (filename == NULL) {
|
||||
ctxt->directory = NULL;
|
||||
} else {
|
||||
diff --git a/result/errors/754947.xml.err b/result/errors/754947.xml.err
|
||||
index f45cb5a..51e9b4e 100644
|
||||
--- a/result/errors/754947.xml.err
|
||||
+++ b/result/errors/754947.xml.err
|
||||
@@ -2,6 +2,6 @@
|
||||
Bytes: 0xEE 0x5D 0x5D 0x3E
|
||||
<d><![CDATA[0000000000000î]]>
|
||||
^
|
||||
-./test/errors/754947.xml:1: parser error : Premature end of data in tag d line 1
|
||||
+./test/errors/754947.xml:1: parser error : EndTag: '</' not found
|
||||
<d><![CDATA[0000000000000î]]>
|
||||
^
|
||||
diff --git a/result/errors/759398.xml.err b/result/errors/759398.xml.err
|
||||
index f6036a3..bc9e5e0 100644
|
||||
--- a/result/errors/759398.xml.err
|
||||
+++ b/result/errors/759398.xml.err
|
||||
@@ -1,10 +1,10 @@
|
||||
./test/errors/759398.xml:210: parser error : StartTag: invalid element name
|
||||
need to worry about parsers whi<! don't expand PErefs finding
|
||||
^
|
||||
-./test/errors/759398.xml:309: parser error : Opening and ending tag mismatch: â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–m line 308 and termdef
|
||||
+./test/errors/759398.xml:309: parser error : Opening and ending tag mismatch: â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–â„–m line 205 and termdef
|
||||
and provide access to their content and structure.</termdef> <termdef
|
||||
^
|
||||
-./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 50 and p
|
||||
+./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 205 and p
|
||||
data and the information it must provide to the application.</p>
|
||||
^
|
||||
./test/errors/759398.xml:316: parser error : Extra content at the end of the document
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
@ -1,77 +0,0 @@
|
||||
From 1fbcf4098ba2aefe241de8d7ceb229b995d8daec Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 23 Sep 2019 17:13:05 +0200
|
||||
Subject: [PATCH 3/3] Make xmlTextReaderFreeNodeList non-recursive
|
||||
|
||||
Avoid call stack overflow when freeing deeply nested documents.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
---
|
||||
xmlreader.c | 32 +++++++++++++++++++++++---------
|
||||
1 file changed, 23 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index d715071..9229c18 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -348,7 +348,9 @@ xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
||||
static void
|
||||
xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
||||
xmlNodePtr next;
|
||||
+ xmlNodePtr parent;
|
||||
xmlDictPtr dict;
|
||||
+ size_t depth = 0;
|
||||
|
||||
if ((reader != NULL) && (reader->ctxt != NULL))
|
||||
dict = reader->ctxt->dict;
|
||||
@@ -364,18 +366,21 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
||||
xmlFreeDoc((xmlDocPtr) cur);
|
||||
return;
|
||||
}
|
||||
- while (cur != NULL) {
|
||||
+ while (1) {
|
||||
+ while ((cur->children != NULL) &&
|
||||
+ (cur->children->parent == cur) &&
|
||||
+ (cur->type != XML_DTD_NODE) &&
|
||||
+ (cur->type != XML_ENTITY_REF_NODE)) {
|
||||
+ cur = cur->children;
|
||||
+ depth += 1;
|
||||
+ }
|
||||
+
|
||||
next = cur->next;
|
||||
+ parent = cur->parent;
|
||||
+
|
||||
/* unroll to speed up freeing the document */
|
||||
if (cur->type != XML_DTD_NODE) {
|
||||
|
||||
- if ((cur->children != NULL) &&
|
||||
- (cur->type != XML_ENTITY_REF_NODE)) {
|
||||
- if (cur->children->parent == cur)
|
||||
- xmlTextReaderFreeNodeList(reader, cur->children);
|
||||
- cur->children = NULL;
|
||||
- }
|
||||
-
|
||||
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
|
||||
xmlDeregisterNodeDefaultValue(cur);
|
||||
|
||||
@@ -414,7 +419,16 @@ xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
||||
xmlFree(cur);
|
||||
}
|
||||
}
|
||||
- cur = next;
|
||||
+
|
||||
+ if (next != NULL) {
|
||||
+ cur = next;
|
||||
+ } else {
|
||||
+ if ((depth == 0) || (parent == NULL))
|
||||
+ break;
|
||||
+ depth -= 1;
|
||||
+ cur = parent;
|
||||
+ cur->children = NULL;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.12.4
|
||||
|
||||
10
libxml2.spec
10
libxml2.spec
@ -1,7 +1,7 @@
|
||||
Summary: Library providing XML and HTML support
|
||||
Name: libxml2
|
||||
Version: 2.9.10
|
||||
Release: 3
|
||||
Release: 4
|
||||
License: MIT
|
||||
Group: Development/Libraries
|
||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
||||
@ -16,7 +16,7 @@ Patch6: Fix-memory-leak-in-error-path-of-XPath-expr-parser.patch
|
||||
Patch7: Fix-memory-leaks-of-encoding-handlers-in-xmlsave-c.patch
|
||||
Patch8: Use-random-seed-in-xmlDictComputeFastKey.patch
|
||||
Patch9: Fix-more-memory-leaks-in-error-paths-of-XPath-parser.patch
|
||||
Patch10: Fix-freeing-of-nested-documents.patch
|
||||
Patch10: Fix-freeing-of-nested-documents.patch
|
||||
Patch11: Fix-overflow-check-in-xmlNodeDump.patch
|
||||
Patch12: Check-for-overflow-when-allocating-two-dimensional-arrays.patch
|
||||
Patch13: Fix-integer-overflow-in-xmlBufferResize.patch
|
||||
@ -26,6 +26,9 @@ Patch16: Merge-code-paths-loading-external-entities.patch
|
||||
Patch17: Don-t-load-external-entity-from-xmlSAX2GetEntity.patch
|
||||
Patch18: Fix-use-after-free-with-validating-reader.patch
|
||||
Patch19: Never-expand-parameter-entities-in-text-declaration.patch
|
||||
Patch20: Fix-integer-overflow-in-xmlFAParseQuantExact.patch
|
||||
Patch21: Report-error-for-invalid-regexp-quantifiers.patch
|
||||
Patch22: Add-regexp-regression-tests.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: python2-devel
|
||||
@ -217,6 +220,9 @@ rm -fr %{buildroot}
|
||||
|
||||
|
||||
%changelog
|
||||
* Mon Aug 3 2020 Liquor <lirui130@huawei.com> - 2.9.10-4
|
||||
- Fix integer overflow in xmlFAParseQuantExact
|
||||
|
||||
* Tue Jul 28 2020 shenyangyang <shenyangyang4@huawei.com> - 2.9.10-3
|
||||
- Fix-use-after-free-with-validating-reader and
|
||||
Never-expand-parameter-entities-in-text-declaration
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user