xzyang / rpms / libxml2

Forked from rpms/libxml2 3 years ago
Clone

Blame SOURCES/libxml2-2.9.1-CVE-2016-5131.patch

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
 /**