Package init

This commit is contained in:
dogsheng 2019-12-25 17:13:34 +08:00
parent b4285adc2f
commit 7225a592c9
39 changed files with 2818 additions and 75 deletions

View File

@ -0,0 +1,61 @@
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

View File

@ -0,0 +1,67 @@
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

View File

@ -0,0 +1,29 @@
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

View File

@ -0,0 +1,104 @@
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

View File

@ -0,0 +1,27 @@
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

View File

@ -0,0 +1,189 @@
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

View File

@ -0,0 +1,378 @@
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

View File

@ -0,0 +1,443 @@
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

View File

@ -0,0 +1,26 @@
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

View File

@ -0,0 +1,28 @@
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

View File

@ -0,0 +1,33 @@
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

View File

@ -0,0 +1,28 @@
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

View File

@ -0,0 +1,31 @@
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

View File

@ -0,0 +1,54 @@
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

View File

@ -0,0 +1,43 @@
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

View File

@ -0,0 +1,50 @@
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

View File

@ -0,0 +1,41 @@
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

View File

@ -0,0 +1,49 @@
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

View File

@ -0,0 +1,36 @@
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

View File

@ -0,0 +1,85 @@
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

View File

@ -0,0 +1,171 @@
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>&#010100000000000000000000000000000000000000000000000060;</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>&#010100000000000000000000000000000000000000000000000060;</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

View File

@ -0,0 +1,26 @@
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

View File

@ -0,0 +1,150 @@
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

View File

@ -0,0 +1,39 @@
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

View File

@ -0,0 +1,26 @@
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

View File

@ -0,0 +1,33 @@
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

View File

@ -0,0 +1,31 @@
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

View File

@ -0,0 +1,36 @@
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

View File

@ -0,0 +1,37 @@
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

View File

@ -0,0 +1,44 @@
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

View File

@ -0,0 +1,29 @@
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

View File

@ -0,0 +1,47 @@
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

View File

@ -1,36 +0,0 @@
# libxml2
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +0,0 @@
# libxml2
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -0,0 +1,33 @@
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

View File

@ -0,0 +1,39 @@
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

BIN
libxml2-2.9.8.tar.gz Normal file

Binary file not shown.

24
libxml2-multilib.patch Normal file
View File

@ -0,0 +1,24 @@
*** XML/xml2-config.in.orig 2006-06-06 16:35:56.000000000 +0200
--- XML/xml2-config.in 2006-06-06 16:36:24.000000000 +0200
***************
*** 3,9 ****
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
! libdir=@libdir@
usage()
{
--- 3,14 ----
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
! if [ "`ldd /bin/sh | grep lib64`" = "" ]
! then
! libdir=${exec_prefix}/lib
! else
! libdir=${exec_prefix}/lib64
! fi
usage()
{

251
libxml2.spec Normal file
View File

@ -0,0 +1,251 @@
Summary: Library providing XML and HTML support
Name: libxml2
Version: 2.9.8
Release: 8
License: MIT
Group: Development/Libraries
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
Patch0: libxml2-multilib.patch
# upstream patches
Patch0001: 0001-NaN-and-Inf-fixes-for-pre-C99-compilers.patch
Patch0002: 0002-Revert-Change-calls-to-xmlCharEncInput-to-set-flush-.patch
Patch0003: 0003-Fix-inconsistency-in-xmlXPathIsInf.patch
Patch0004: 0004-Stop-using-XPATH_OP_RESET.patch
Patch0005: 0005-Don-t-change-context-node-in-xmlXPathRoot.patch
Patch0006: 0006-Avoid-unnecessary-backups-of-the-context-node.patch
Patch0007: 0007-Simplify-and-harden-nodeset-filtering.patch
Patch0008: 0008-Improve-restoring-of-context-size-and-position.patch
Patch0009: 0009-HTML-noscript-should-not-close-p.patch
Patch0010: 0010-Remove-a-misleading-line-from-xmlCharEncOutput.patch
Patch0011: 0011-Remove-stray-character-from-comment.patch
Patch0012: 0012-Fix-nullptr-deref-with-XPath-logic-ops.patch
Patch0013: 0013-Fix-infinite-loop-in-LZMA-decompression.patch
Patch6000: Remove-a-misleading-line-from-xmlCharEncOutput.patch
Patch6001: Fix-xmlSchemaValidCtxtPtr-reuse-memory-leak.patch
Patch6002: Reset-HTML-parser-input-pointers-on-encoding-failure.patch
Patch6003: Fix-HTML-serialization-with-UTF-8-encoding.patch
Patch6004: Fix-memory-leak-in-xmlSwitchInputEncodingInt-error-p.patch
Patch6005: Memory-leak-in-xmlFreeID-xmlreader.c.patch
Patch6006: Memory-leak-in-xmlFreeTextReader.patch
Patch6007: Fix-NULL-pointer-deref-in-xmlTextReaderValidateEntit.patch
Patch6008: Fix-commit-Memory-leak-in-xmlFreeID-xmlreader.c.patch
Patch6009: Fix-memory-leaks-in-xmlParseStartTag2-error-paths.patch
Patch6010: 0009-Fix-null-deref-in-xmlregexp-error-path.patch
Patch6011: 0012-Check-XPath-stack-after-calling-functions.patch
Patch6012: 0013-Check-for-integer-overflow-in-xmlXPtrEvalChildSeq.patch
Patch6013: 0021-Fix-memory-leaks-in-xmlXPathParseNameComplex-error-p.patch
Patch6014: 0026-Fix-call-stack-overflow-in-xmlFreePattern.patch
Patch6015: 0031-Fix-parser-termination-from-Double-hyphen-within-com.patch
Patch6016: 0032-Fix-return-value-of-xmlOutputBufferWrite.patch
Patch6017: 0034-Fix-unsigned-integer-overflow.patch
Patch6018: 0037-Fix-memory-leak-in-xmlAllocOutputBufferInternal-erro.patch
Patch9000: Fix-memory-leak-in-xmlParseBalancedChunkMemoryRecove.patch
Patch9001: Fix-memory-leak-in-xmlSchemaValidateStream.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-root
BuildRequires: python2-devel
BuildRequires: python3-devel
BuildRequires: zlib-devel
BuildRequires: pkgconfig
BuildRequires: xz-devel
URL: http://xmlsoft.org/
%description
This library allows to manipulate XML files. It includes support
to read, modify and write XML and HTML files. There is DTDs support
this includes parsing and validation even with complex DtDs, either
at parse time or later once the document has been modified. The output
can be a simple SAX stream or and in-memory DOM like representations.
In this case one can use the built-in XPath and XPointer implementation
to select sub nodes or ranges. A flexible Input/Output mechanism is
available, with existing HTTP and FTP modules and combined to an
URI library.
%package devel
Summary: Libraries, includes, etc. to develop XML and HTML applications
Group: Development/Libraries
Requires: libxml2 = %{version}-%{release}
Requires: zlib-devel
Requires: xz-devel
Requires: pkgconfig
Obsoletes: %{name}-static
Provides: %{name}-static
%description devel
Libraries, include files, etc you can use to develop XML applications.
This library allows to manipulate XML files. It includes support
to read, modify and write XML and HTML files. There is DTDs support
this includes parsing and validation even with complex DtDs, either
at parse time or later once the document has been modified. The output
can be a simple SAX stream or and in-memory DOM like representations.
In this case one can use the built-in XPath and XPointer implementation
to select sub nodes or ranges. A flexible Input/Output mechanism is
available, with existing HTTP and FTP modules and combined to an
URI library.
%package -n python2-%{name}
%{?python_provide:%python_provide python-%{name}}
Summary: Python bindings for the libxml2 library
Group: Development/Libraries
Requires: libxml2 = %{version}-%{release}
Obsoletes: %{name}-python < %{version}-%{release}
Provides: %{name}-python = %{version}-%{release}
%description -n python2-%{name}
The libxml2-python package contains a Python 2 module that permits applications
written in the Python programming language, version 2, to use the interface
supplied by the libxml2 library to manipulate XML files.
This library allows to manipulate XML files. It includes support
to read, modify and write XML and HTML files. There is DTDs support
this includes parsing and validation even with complex DTDs, either
at parse time or later once the document has been modified.
%package -n python3-%{name}
Summary: Python 3 bindings for the libxml2 library
Group: Development/Libraries
Requires: libxml2 = %{version}-%{release}
Obsoletes: %{name}-python3 < %{version}-%{release}
Provides: %{name}-python3 = %{version}-%{release}
%description -n python3-%{name}
The libxml2-python3 package contains a Python 3 module that permits
applications written in the Python programming language, version 3, to use the
interface supplied by the libxml2 library to manipulate XML files.
This library allows to manipulate XML files. It includes support
to read, modify and write XML and HTML files. There is DTDs support
this includes parsing and validation even with complex DTDs, either
at parse time or later once the document has been modified.
%package help
Summary: Man page for libxml2
BuildArch: noarch
%description help
%{summary}.
%prep
%autosetup -n %{name}-%{version} -p1
mkdir py3doc
cp doc/*.py py3doc
sed -i 's|#!/usr/bin/python |#!%{__python3} |' py3doc/*.py
%build
%configure
%make_build
find doc -type f -exec chmod 0644 \{\} \;
%install
%make_install
make clean
# for python3
%configure --with-python=%{__python3}
%make_install
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.a
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.la
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libxml2-%{version}/*
rm -rf $RPM_BUILD_ROOT%{_datadir}/doc/libxml2-python-%{version}/*
(cd doc/examples ; make clean ; rm -rf .deps Makefile)
gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz
%check
make runtests
%clean
rm -fr %{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-, root, root)
%doc AUTHORS NEWS README Copyright TODO
%{_libdir}/lib*.so.*
%{_bindir}/xmllint
%{_bindir}/xmlcatalog
%files devel
%defattr(-, root, root)
%doc AUTHORS NEWS README Copyright
%doc doc/*.html doc/html doc/*.gif doc/*.png
%doc doc/tutorial doc/libxml2-api.xml.gz
%doc doc/examples
%doc %dir %{_datadir}/gtk-doc/html/libxml2
%doc %{_datadir}/gtk-doc/html/libxml2/*.devhelp
%doc %{_datadir}/gtk-doc/html/libxml2/*.html
%doc %{_datadir}/gtk-doc/html/libxml2/*.png
%doc %{_datadir}/gtk-doc/html/libxml2/*.css
%{_libdir}/lib*.so
%{_libdir}/*.sh
%{_includedir}/*
%{_bindir}/xml2-config
%{_datadir}/aclocal/libxml.m4
%{_libdir}/pkgconfig/libxml-2.0.pc
%{_libdir}/cmake/libxml2/libxml2-config.cmake
%{_libdir}/*a
%files -n python2-%{name}
%defattr(-, root, root)
%{_libdir}/python2*/site-packages/libxml2.py*
%{_libdir}/python2*/site-packages/drv_libxml2.py*
%{_libdir}/python2*/site-packages/libxml2mod*
%doc python/TODO
%doc python/libxml2class.txt
%doc python/tests/*.py
%doc doc/*.py
%doc doc/python.html
%files -n python3-%{name}
%defattr(-, root, root)
%{_libdir}/python3*/site-packages/libxml2.py*
%{_libdir}/python3*/site-packages/drv_libxml2.py*
%{_libdir}/python3*/site-packages/__pycache__/*py*
%{_libdir}/python3*/site-packages/libxml2mod*
%doc python/TODO
%doc python/libxml2class.txt
%doc py3doc/*.py
%doc doc/python.html
%files help
%doc %{_mandir}/man1/xml2-config.1*
%doc %{_mandir}/man1/xmllint.1*
%doc %{_mandir}/man1/xmlcatalog.1*
%doc %{_mandir}/man3/libxml.3*
%changelog
* Thu Dec 19 2019 openEuler Buildteam <buildteam@openEuler.org> - 2.9.8-8
- Delete unused infomation
* Tue Sep 24 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.8-7
- Fix memory leak in xmlSchemaValidateStream
* Fri Sep 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.8-6
- Delete redundant information
* Thu Sep 10 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.8-5
- Delete epoch
* Thu Sep 5 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.8-2
- Backport upstream patches and merge static library to devel package