diff options
author | Brian C. Young <bcyoung@google.com> | 2017-04-03 12:46:02 -0700 |
---|---|---|
committer | MSe <mse1969@posteo.de> | 2017-06-09 14:35:22 +0200 |
commit | 0f96d37d46fab8af7fd58ae40e8a69effb52b0a9 (patch) | |
tree | f7c961da8933af3ef5abdc7e4a342de46ffedd16 | |
parent | 16304977ca877f04b55b1f4a0848107f36af26ad (diff) | |
download | android_external_libxml2-0f96d37d46fab8af7fd58ae40e8a69effb52b0a9.tar.gz android_external_libxml2-0f96d37d46fab8af7fd58ae40e8a69effb52b0a9.tar.bz2 android_external_libxml2-0f96d37d46fab8af7fd58ae40e8a69effb52b0a9.zip |
DO NOT MERGE: Fix XPointer paths beginning with range-to
The old code would invoke the broken xmlXPtrRangeToFunction. range-to
isn't really a function but a special kind of location step. Remove
this function and always handle range-to in the XPath code.
The old xmlXPtrRangeToFunction could also be abused to trigger a
use-after-free error with the potential for remote code execution.
Found with afl-fuzz.
Fixes CVE-2016-5131.
Bug: 36554209
AOSP-Change-Id: I2bd369290a884c432d16796884d48db6285f8502
(cherry picked from commit e875e1cd1fc92fd2daa57826024125cbd0b195c7)
Change-Id: I66c6cfb4f4f81827891b10125c991d15315ce3a7
-rw-r--r-- | test/XPath/xptr/vidbase | 1 | ||||
-rw-r--r-- | xpath.c | 7 | ||||
-rw-r--r-- | xpointer.c | 76 |
3 files changed, 13 insertions, 71 deletions
diff --git a/test/XPath/xptr/vidbase b/test/XPath/xptr/vidbase index b1463830..884b1065 100644 --- a/test/XPath/xptr/vidbase +++ b/test/XPath/xptr/vidbase @@ -1,2 +1,3 @@ xpointer(id('chapter1')/p) xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2])) +xpointer(range-to(id('chapter2'))) @@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { lc = 1; break; } else if ((NXT(len) == '(')) { - /* Note Type or Function */ + /* Node Type or Function */ if (xmlXPathIsNodeType(name)) { #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, "PathExpr: Type search\n"); #endif lc = 1; +#ifdef LIBXML_XPTR_ENABLED + } else if (ctxt->xptr && + xmlStrEqual(name, BAD_CAST "range-to")) { + lc = 1; +#endif } else { #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, @@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) { ret->here = here; ret->origin = origin; - xmlXPathRegisterFunc(ret, (xmlChar *)"range-to", - xmlXPtrRangeToFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range", xmlXPtrRangeFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside", @@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) { * @nargs: the number of args * * Implement the range-to() XPointer function + * + * Obsolete. range-to is not a real function but a special type of location + * step which is handled in xpath.c. */ void -xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr range; - const xmlChar *cur; - xmlXPathObjectPtr res, obj; - xmlXPathObjectPtr tmp; - xmlLocationSetPtr newset = NULL; - xmlNodeSetPtr oldset; - int i; - - if (ctxt == NULL) return; - CHECK_ARITY(1); - /* - * Save the expression pointer since we will have to evaluate - * it multiple times. Initialize the new set. - */ - CHECK_TYPE(XPATH_NODESET); - obj = valuePop(ctxt); - oldset = obj->nodesetval; - ctxt->context->node = NULL; - - cur = ctxt->cur; - newset = xmlXPtrLocationSetCreate(NULL); - - for (i = 0; i < oldset->nodeNr; i++) { - ctxt->cur = cur; - - /* - * Run the evaluation with a node list made of a single item - * in the nodeset. - */ - ctxt->context->node = oldset->nodeTab[i]; - tmp = xmlXPathNewNodeSet(ctxt->context->node); - valuePush(ctxt, tmp); - - xmlXPathEvalExpr(ctxt); - CHECK_ERROR; - - /* - * The result of the evaluation need to be tested to - * decided whether the filter succeeded or not - */ - res = valuePop(ctxt); - range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res); - if (range != NULL) { - xmlXPtrLocationSetAdd(newset, range); - } - - /* - * Cleanup - */ - if (res != NULL) - xmlXPathFreeObject(res); - if (ctxt->value == tmp) { - res = valuePop(ctxt); - xmlXPathFreeObject(res); - } - - ctxt->context->node = NULL; - } - - /* - * The result is used as the new evaluation set. - */ - xmlXPathFreeObject(obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; - valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); +xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, + int nargs ATTRIBUTE_UNUSED) { + XP_ERROR(XPATH_EXPR_ERROR); } /** |