mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-16 02:50:07 +03:00
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.
This commit is contained in:
parent
a005199330
commit
9ab01a277d
@ -17,3 +17,16 @@ Object is a Location Set:
|
||||
To node
|
||||
ELEMENT p
|
||||
|
||||
|
||||
========================
|
||||
Expression: xpointer(range-to(id('chapter2')))
|
||||
Object is a Location Set:
|
||||
1 : Object is a range :
|
||||
From node
|
||||
/
|
||||
To node
|
||||
ELEMENT chapter
|
||||
ATTRIBUTE id
|
||||
TEXT
|
||||
content=chapter2
|
||||
|
||||
|
@ -1,2 +1,3 @@
|
||||
xpointer(id('chapter1')/p)
|
||||
xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2]))
|
||||
xpointer(range-to(id('chapter2')))
|
||||
|
7
xpath.c
7
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,
|
||||
|
76
xpointer.c
76
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user