Commit bf6c947b authored by Nick Wellnhofer's avatar Nick Wellnhofer
Browse files

Fix for pattern predicates calling functions

Set correct XSLT instruction when evaluating predicates in patterns.
This is needed by functions like element-available. Could also lead
to a NULL pointer dereference.

Thanks to Wang Junjie for the report. Fixes bug #776792:

https://bugzilla.gnome.org/show_bug.cgi?id=776792
parent e49797c8
......@@ -835,7 +835,7 @@ xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){
}
obj = valuePop(ctxt);
tctxt = xsltXPathGetTransformContext(ctxt);
if (tctxt == NULL) {
if ((tctxt == NULL) || (tctxt->inst == NULL)) {
xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
"element-available() : internal error tctxt == NULL\n");
xmlXPathFreeObject(obj);
......
......@@ -104,6 +104,7 @@ struct _xsltCompMatch {
const xmlChar *mode; /* the mode */
const xmlChar *modeURI; /* the mode URI */
xsltTemplatePtr template; /* the associated template */
xmlNodePtr node; /* the containing element */
int direct;
/* TODO fix the statically allocated size steps[] */
......@@ -914,7 +915,9 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
xmlNodePtr matchNode, const xmlChar *mode,
const xmlChar *modeURI) {
int i;
int found = 0;
xmlNodePtr node = matchNode;
xmlNodePtr oldInst;
xsltStepOpPtr step, sel = NULL;
xsltStepStates states = {0, 0, NULL}; /* // may require backtrack */
......@@ -948,6 +951,10 @@ xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
return(0);
}
/* Some XPath functions rely on inst being set correctly. */
oldInst = ctxt->inst;
ctxt->inst = comp->node;
i = 0;
restart:
for (;i < comp->nbStep;i++) {
......@@ -1140,12 +1147,9 @@ restart:
* as possible this costly computation.
*/
if (comp->direct) {
if (states.states != NULL) {
/* Free the rollback states */
xmlFree(states.states);
}
return(xsltTestCompMatchDirect(ctxt, comp, matchNode,
comp->nsList, comp->nsNr));
found = xsltTestCompMatchDirect(ctxt, comp, matchNode,
comp->nsList, comp->nsNr);
goto exit;
}
if (!xsltTestPredicateMatch(ctxt, comp, node, step, sel))
......@@ -1185,18 +1189,19 @@ restart:
}
}
found:
found = 1;
exit:
ctxt->inst = oldInst;
if (states.states != NULL) {
/* Free the rollback states */
xmlFree(states.states);
}
return(1);
return found;
rollback:
/* got an error try to rollback */
if (states.states == NULL)
return(0);
if (states.nbstates <= 0) {
xmlFree(states.states);
return(0);
if (states.states == NULL || states.nbstates <= 0) {
found = 0;
goto exit;
}
states.nbstates--;
i = states.states[states.nbstates].step;
......@@ -1944,6 +1949,7 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
goto error;
ctxt->cur = &(ctxt->base)[current - start];
element->pattern = ctxt->base;
element->node = node;
element->nsList = xmlGetNsList(doc, node);
j = 0;
if (element->nsList != NULL) {
......
......@@ -63,6 +63,12 @@ xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
xmlNodePtr oldInst;
int oldProximityPosition, oldContextSize;
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
xsltTransformError(ctxt, NULL, NULL,
"xsltEvalXPathPredicate: No context or instruction\n");
return(0);
}
oldContextSize = ctxt->xpathCtxt->contextSize;
oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
oldNsNr = ctxt->xpathCtxt->nsNr;
......@@ -124,6 +130,12 @@ xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
int oldNsNr;
xmlNsPtr *oldNamespaces;
if ((ctxt == NULL) || (ctxt->inst == NULL)) {
xsltTransformError(ctxt, NULL, NULL,
"xsltEvalXPathStringNs: No context or instruction\n");
return(0);
}
oldInst = ctxt->inst;
oldNode = ctxt->node;
oldPos = ctxt->xpathCtxt->proximityPosition;
......
<?xml version="1.0"?>
found
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<template xmlns="http://www.w3.org/1999/XSL/Transform" match="*[element-available('apply-templates')]">
<text>found</text>
</template>
</xsl:stylesheet>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment