[libxslt] Fix for pattern predicates calling functions
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxslt] Fix for pattern predicates calling functions
- Date: Tue, 3 Jan 2017 16:10:06 +0000 (UTC)
commit bf6c947bf6b77d28344829cd489b1f19eeb26536
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Tue Jan 3 15:42:26 2017 +0100
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
libxslt/functions.c | 2 +-
libxslt/pattern.c | 30 ++++++++++++++++++------------
libxslt/templates.c | 12 ++++++++++++
tests/docs/bug-200.xml | 1 +
tests/general/bug-200.out | 2 ++
tests/general/bug-200.xsl | 5 +++++
6 files changed, 39 insertions(+), 13 deletions(-)
---
diff --git a/libxslt/functions.c b/libxslt/functions.c
index a5e7021..5e99e92 100644
--- a/libxslt/functions.c
+++ b/libxslt/functions.c
@@ -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);
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index e211a01..8359e4b 100644
--- a/libxslt/pattern.c
+++ b/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) {
diff --git a/libxslt/templates.c b/libxslt/templates.c
index 02193f7..ad83dce 100644
--- a/libxslt/templates.c
+++ b/libxslt/templates.c
@@ -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;
diff --git a/tests/docs/bug-200.xml b/tests/docs/bug-200.xml
new file mode 100644
index 0000000..69d62f2
--- /dev/null
+++ b/tests/docs/bug-200.xml
@@ -0,0 +1 @@
+<doc/>
diff --git a/tests/general/bug-200.out b/tests/general/bug-200.out
new file mode 100644
index 0000000..71afb61
--- /dev/null
+++ b/tests/general/bug-200.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+found
diff --git a/tests/general/bug-200.xsl b/tests/general/bug-200.xsl
new file mode 100644
index 0000000..8aad8b5
--- /dev/null
+++ b/tests/general/bug-200.xsl
@@ -0,0 +1,5 @@
+<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>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]