Index: third_party/libxslt/libxslt/pattern.c |
diff --git a/third_party/libxslt/libxslt/pattern.c b/third_party/libxslt/libxslt/pattern.c |
index e211a01d80618e822a68f9e6d557eaad0d055827..8359e4b6762c7062f3617dd592ebdf12fef44e8f 100644 |
--- a/third_party/libxslt/libxslt/pattern.c |
+++ b/third_party/libxslt/libxslt/pattern.c |
@@ -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) { |