|
|
8a784f |
commit 3189fa5b5d1cce13e70cf282936736b2e7889a46
|
|
|
8a784f |
Author: Nick Wellnhofer <wellnhofer@aevum.de>
|
|
|
8a784f |
Date: Tue Jun 28 14:22:23 2016 +0200
|
|
|
8a784f |
|
|
|
8a784f |
Fix XPointer paths beginning with range-to
|
|
|
8a784f |
|
|
|
8a784f |
The old code would invoke the totally broken xmlXPtrRangeToFunction.
|
|
|
8a784f |
range-to isn't really a function but a special kind of location step.
|
|
|
8a784f |
Remove this function and always handle range-to in the XPath code.
|
|
|
8a784f |
|
|
|
8a784f |
The old xmlXPtrRangeToFunction could also be abused to trigger a
|
|
|
8a784f |
use-after-free error with the potential for remote code execution.
|
|
|
8a784f |
|
|
|
8a784f |
diff --git a/xpath.c b/xpath.c
|
|
|
8a784f |
index 751665b..7c24a82 100644
|
|
|
8a784f |
--- a/xpath.c
|
|
|
8a784f |
+++ b/xpath.c
|
|
|
8a784f |
@@ -10691,13 +10691,16 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
|
|
|
8a784f |
lc = 1;
|
|
|
8a784f |
break;
|
|
|
8a784f |
} else if ((NXT(len) == '(')) {
|
|
|
8a784f |
- /* Note Type or Function */
|
|
|
8a784f |
+ /* Node Type or Function */
|
|
|
8a784f |
if (xmlXPathIsNodeType(name)) {
|
|
|
8a784f |
#ifdef DEBUG_STEP
|
|
|
8a784f |
xmlGenericError(xmlGenericErrorContext,
|
|
|
8a784f |
"PathExpr: Type search\n");
|
|
|
8a784f |
#endif
|
|
|
8a784f |
lc = 1;
|
|
|
8a784f |
+ } else if (ctxt->xptr &&
|
|
|
8a784f |
+ xmlStrEqual(name, BAD_CAST "range-to")) {
|
|
|
8a784f |
+ lc = 1;
|
|
|
8a784f |
} else {
|
|
|
8a784f |
#ifdef DEBUG_STEP
|
|
|
8a784f |
xmlGenericError(xmlGenericErrorContext,
|
|
|
8a784f |
diff --git a/xpointer.c b/xpointer.c
|
|
|
8a784f |
index 676c510..d74174a 100644
|
|
|
8a784f |
--- a/xpointer.c
|
|
|
8a784f |
+++ b/xpointer.c
|
|
|
8a784f |
@@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
|
|
|
8a784f |
ret->here = here;
|
|
|
8a784f |
ret->origin = origin;
|
|
|
8a784f |
|
|
|
8a784f |
- xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
|
|
|
8a784f |
- xmlXPtrRangeToFunction);
|
|
|
8a784f |
xmlXPathRegisterFunc(ret, (xmlChar *)"range",
|
|
|
8a784f |
xmlXPtrRangeFunction);
|
|
|
8a784f |
xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
|
|
|
8a784f |
@@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|
|
8a784f |
* @nargs: the number of args
|
|
|
8a784f |
*
|
|
|
8a784f |
* Implement the range-to() XPointer function
|
|
|
8a784f |
+ *
|
|
|
8a784f |
+ * Obsolete. range-to is not a real function but a special type of location
|
|
|
8a784f |
+ * step which is handled in xpath.c.
|
|
|
8a784f |
*/
|
|
|
8a784f |
void
|
|
|
8a784f |
-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|
|
8a784f |
- xmlXPathObjectPtr range;
|
|
|
8a784f |
- const xmlChar *cur;
|
|
|
8a784f |
- xmlXPathObjectPtr res, obj;
|
|
|
8a784f |
- xmlXPathObjectPtr tmp;
|
|
|
8a784f |
- xmlLocationSetPtr newset = NULL;
|
|
|
8a784f |
- xmlNodeSetPtr oldset;
|
|
|
8a784f |
- int i;
|
|
|
8a784f |
-
|
|
|
8a784f |
- if (ctxt == NULL) return;
|
|
|
8a784f |
- CHECK_ARITY(1);
|
|
|
8a784f |
- /*
|
|
|
8a784f |
- * Save the expression pointer since we will have to evaluate
|
|
|
8a784f |
- * it multiple times. Initialize the new set.
|
|
|
8a784f |
- */
|
|
|
8a784f |
- CHECK_TYPE(XPATH_NODESET);
|
|
|
8a784f |
- obj = valuePop(ctxt);
|
|
|
8a784f |
- oldset = obj->nodesetval;
|
|
|
8a784f |
- ctxt->context->node = NULL;
|
|
|
8a784f |
-
|
|
|
8a784f |
- cur = ctxt->cur;
|
|
|
8a784f |
- newset = xmlXPtrLocationSetCreate(NULL);
|
|
|
8a784f |
-
|
|
|
8a784f |
- for (i = 0; i < oldset->nodeNr; i++) {
|
|
|
8a784f |
- ctxt->cur = cur;
|
|
|
8a784f |
-
|
|
|
8a784f |
- /*
|
|
|
8a784f |
- * Run the evaluation with a node list made of a single item
|
|
|
8a784f |
- * in the nodeset.
|
|
|
8a784f |
- */
|
|
|
8a784f |
- ctxt->context->node = oldset->nodeTab[i];
|
|
|
8a784f |
- tmp = xmlXPathNewNodeSet(ctxt->context->node);
|
|
|
8a784f |
- valuePush(ctxt, tmp);
|
|
|
8a784f |
-
|
|
|
8a784f |
- xmlXPathEvalExpr(ctxt);
|
|
|
8a784f |
- CHECK_ERROR;
|
|
|
8a784f |
-
|
|
|
8a784f |
- /*
|
|
|
8a784f |
- * The result of the evaluation need to be tested to
|
|
|
8a784f |
- * decided whether the filter succeeded or not
|
|
|
8a784f |
- */
|
|
|
8a784f |
- res = valuePop(ctxt);
|
|
|
8a784f |
- range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
|
|
|
8a784f |
- if (range != NULL) {
|
|
|
8a784f |
- xmlXPtrLocationSetAdd(newset, range);
|
|
|
8a784f |
- }
|
|
|
8a784f |
-
|
|
|
8a784f |
- /*
|
|
|
8a784f |
- * Cleanup
|
|
|
8a784f |
- */
|
|
|
8a784f |
- if (res != NULL)
|
|
|
8a784f |
- xmlXPathFreeObject(res);
|
|
|
8a784f |
- if (ctxt->value == tmp) {
|
|
|
8a784f |
- res = valuePop(ctxt);
|
|
|
8a784f |
- xmlXPathFreeObject(res);
|
|
|
8a784f |
- }
|
|
|
8a784f |
-
|
|
|
8a784f |
- ctxt->context->node = NULL;
|
|
|
8a784f |
- }
|
|
|
8a784f |
-
|
|
|
8a784f |
- /*
|
|
|
8a784f |
- * The result is used as the new evaluation set.
|
|
|
8a784f |
- */
|
|
|
8a784f |
- xmlXPathFreeObject(obj);
|
|
|
8a784f |
- ctxt->context->node = NULL;
|
|
|
8a784f |
- ctxt->context->contextSize = -1;
|
|
|
8a784f |
- ctxt->context->proximityPosition = -1;
|
|
|
8a784f |
- valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
|
|
|
8a784f |
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
|
|
|
8a784f |
+ int nargs ATTRIBUTE_UNUSED) {
|
|
|
8a784f |
+ XP_ERROR(XPATH_EXPR_ERROR);
|
|
|
8a784f |
}
|
|
|
8a784f |
|
|
|
8a784f |
/**
|