aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian C. Young <bcyoung@google.com>2017-04-03 12:46:02 -0700
committerMSe <mse1969@posteo.de>2017-06-09 14:35:22 +0200
commit0f96d37d46fab8af7fd58ae40e8a69effb52b0a9 (patch)
treef7c961da8933af3ef5abdc7e4a342de46ffedd16
parent16304977ca877f04b55b1f4a0848107f36af26ad (diff)
downloadandroid_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/vidbase1
-rw-r--r--xpath.c7
-rw-r--r--xpointer.c76
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')))
diff --git a/xpath.c b/xpath.c
index 935fcff0..1b8206ba 100644
--- a/xpath.c
+++ b/xpath.c
@@ -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,
diff --git a/xpointer.c b/xpointer.c
index 4b4ac2ee..0494f0d0 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -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);
}
/**