summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam M. Brack <wbrack@src.gnome.org>2004-08-02 15:51:00 +0000
committerWilliam M. Brack <wbrack@src.gnome.org>2004-08-02 15:51:00 +0000
commit58e98329ecf9ec88bdc04349a2c7bc64a220df63 (patch)
treedf32208dcb3b6471f2d5c89d6add8ee6402709e0
parent391aed81b51dbad8608773e4c1f65fd917beb917 (diff)
downloadlibxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.tar.gz
libxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.tar.bz2
libxslt-58e98329ecf9ec88bdc04349a2c7bc64a220df63.zip
added code to assure keys are generated when needed for node-sets (bug
* libxslt/documents.c, libxslt/functions.c, libxslt/transform.c, libxslt/variables.c: added code to assure keys are generated when needed for node-sets (bug 148773) * tests/exslt/common/node-set.7.* - added test case for above.
-rw-r--r--ChangeLog7
-rw-r--r--libxslt/documents.c6
-rw-r--r--libxslt/functions.c30
-rw-r--r--libxslt/transform.c10
-rw-r--r--libxslt/variables.c9
-rw-r--r--tests/exslt/common/Makefile.am1
-rw-r--r--tests/exslt/common/node-set.7.out2
-rw-r--r--tests/exslt/common/node-set.7.xml1
-rw-r--r--tests/exslt/common/node-set.7.xsl28
9 files changed, 81 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 2b435757..ac61ff12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Mon Aug 2 08:48:03 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+ * libxslt/documents.c, libxslt/functions.c, libxslt/transform.c,
+ libxslt/variables.c: added code to assure keys are generated
+ when needed for node-sets (bug 148773)
+ * tests/exslt/common/node-set.7.* - added test case for above.
+
Mon Jul 26 17:03:22 PDT 2004 William Brack <wbrack@mmm.com.hk>
* libexslt/strings.c: fixed str:tokenize for case when 2nd
diff --git a/libxslt/documents.c b/libxslt/documents.c
index c4e4b363..a30374ab 100644
--- a/libxslt/documents.c
+++ b/libxslt/documents.c
@@ -63,8 +63,10 @@ xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
memset(cur, 0, sizeof(xsltDocument));
cur->doc = doc;
if (ctxt != NULL) {
- cur->next = ctxt->docList;
- ctxt->docList = cur;
+ if (!xmlStrEqual((xmlChar *)doc->name, BAD_CAST " fake node libxslt")) {
+ cur->next = ctxt->docList;
+ ctxt->docList = cur;
+ }
xsltInitCtxtKeys(ctxt, cur);
}
return(cur);
diff --git a/libxslt/functions.c b/libxslt/functions.c
index ad839cc4..aa1a236d 100644
--- a/libxslt/functions.c
+++ b/libxslt/functions.c
@@ -437,12 +437,30 @@ xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){
oldDocumentPtr = tctxt->document;
oldXPathDocPtr = tctxt->xpathCtxt->doc;
if ((ctxt->context->doc != NULL) &&
- (tctxt->document->doc != ctxt->context->doc)) {
- tctxt->document = xsltFindDocument(tctxt, ctxt->context->doc);
- if (tctxt->document == NULL)
- tctxt->document = oldDocumentPtr;
- else
- tctxt->xpathCtxt->doc = ctxt->context->doc;
+ (tctxt->document->doc != ctxt->context->doc)) {
+ /*
+ * The xpath context document needs to be changed. If the
+ * current context document is a node-set, we must use an
+ * xsltDocument associated with the node-set, which may or
+ * may not currently exist.
+ */
+ if (xmlStrEqual((const xmlChar *)ctxt->context->doc->name,
+ BAD_CAST " fake node libxslt")) { /* node-set */
+ /*
+ * Check whether we already have an xsltDocument set up
+ */
+ if (ctxt->context->doc->_private == NULL) /* nope */
+ ctxt->context->doc->_private =
+ xsltNewDocument(tctxt, ctxt->context->doc);
+ tctxt->document = ctxt->context->doc->_private;
+ }
+ else {
+ tctxt->document = xsltFindDocument(tctxt, ctxt->context->doc);
+ if (tctxt->document == NULL)
+ tctxt->document = oldDocumentPtr;
+ else
+ tctxt->xpathCtxt->doc = ctxt->context->doc;
+ }
}
nodelist = xsltGetKey(tctxt, key, keyURI, value);
tctxt->document = oldDocumentPtr;
diff --git a/libxslt/transform.c b/libxslt/transform.c
index 4be9ee7d..35b6e2b1 100644
--- a/libxslt/transform.c
+++ b/libxslt/transform.c
@@ -1815,6 +1815,10 @@ xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlXPathFreeObject(elem->value);
}
next = (xmlDocPtr) tmp->next;
+ if (tmp->_private != NULL) {
+ xsltFreeDocumentKeys(tmp->_private);
+ xmlFree(tmp->_private);
+ }
xmlFreeDoc(tmp);
tmp = next;
}
@@ -3108,7 +3112,7 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
int nbsorts = 0;
xmlNodePtr sorts[XSLT_MAX_SORT];
xmlDocPtr oldXDocPtr;
- xsltDocumentPtr oldCDocPtr, tmpDocPtr, newDocPtr = NULL;
+ xsltDocumentPtr oldCDocPtr, newDocPtr = NULL;
xmlNodePtr newDocPtrPtr = NULL;
int oldNsNr;
xmlNsPtr *oldNamespaces;
@@ -3376,10 +3380,6 @@ error:
If we created a "pseudo-document" we must free it now
*/
if (newDocPtr != NULL) {
- tmpDocPtr = (xsltDocumentPtr)&ctxt->docList;
- while (tmpDocPtr->next != newDocPtr)
- tmpDocPtr = tmpDocPtr->next;
- tmpDocPtr->next = newDocPtr->next;
newDocPtr->doc->parent = NULL;
xsltFreeDocumentKeys(newDocPtr);
xmlFree(newDocPtr);
diff --git a/libxslt/variables.c b/libxslt/variables.c
index 6cb29868..00b07b92 100644
--- a/libxslt/variables.c
+++ b/libxslt/variables.c
@@ -29,6 +29,7 @@
#include "transform.h"
#include "imports.h"
#include "preproc.h"
+#include "keys.h"
#ifdef WITH_XSLT_DEBUG
#define WITH_XSLT_DEBUG_VARIABLE
@@ -128,12 +129,20 @@ xsltFreeRVTs(xsltTransformContextPtr ctxt)
cur = ctxt->tmpRVT;
while (cur != NULL) {
next = (xmlDocPtr) cur->next;
+ if (cur->_private != NULL) {
+ xsltFreeDocumentKeys(cur->_private);
+ xmlFree(cur->_private);
+ }
xmlFreeDoc(cur);
cur = next;
}
cur = ctxt->persistRVT;
while (cur != NULL) {
next = (xmlDocPtr) cur->next;
+ if (cur->_private != NULL) {
+ xsltFreeDocumentKeys(cur->_private);
+ xmlFree(cur->_private);
+ }
xmlFreeDoc(cur);
cur = next;
}
diff --git a/tests/exslt/common/Makefile.am b/tests/exslt/common/Makefile.am
index 7a1f6126..39decd98 100644
--- a/tests/exslt/common/Makefile.am
+++ b/tests/exslt/common/Makefile.am
@@ -10,6 +10,7 @@ EXTRA_DIST = \
node-set.4.xml node-set.4.xsl node-set.4.out \
node-set.5.xml node-set.5.xsl node-set.5.out \
node-set.6.xml node-set.6.xsl node-set.6.out \
+ node-set.7.xml node-set.7.xsl node-set.7.out \
object-type.1.xml object-type.1.xsl object-type.1.out \
import-test1a.imp import-test1b.imp import-test1.out \
import-test1.xml import-test1.xsl
diff --git a/tests/exslt/common/node-set.7.out b/tests/exslt/common/node-set.7.out
new file mode 100644
index 00000000..dfb17cf5
--- /dev/null
+++ b/tests/exslt/common/node-set.7.out
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+A
diff --git a/tests/exslt/common/node-set.7.xml b/tests/exslt/common/node-set.7.xml
new file mode 100644
index 00000000..8eb294b5
--- /dev/null
+++ b/tests/exslt/common/node-set.7.xml
@@ -0,0 +1 @@
+<root>junk</root>
diff --git a/tests/exslt/common/node-set.7.xsl b/tests/exslt/common/node-set.7.xsl
new file mode 100644
index 00000000..7f1068ec
--- /dev/null
+++ b/tests/exslt/common/node-set.7.xsl
@@ -0,0 +1,28 @@
+<xsl:transform
+ version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ extension-element-prefixes="exsl">
+
+ <xsl:key name="k" match="a" use="@x"/>
+
+ <xsl:template match="/">
+ <xsl:variable name="v">
+ <n>
+ <a x="1" y="A"/>
+ <a x="2" y="B"/>
+ </n>
+ </xsl:variable>
+ <xsl:apply-templates select="exsl:node-set($v)/*"/>
+ </xsl:template>
+
+ <xsl:template match="n">
+<!-- <xsl:apply-templates select="a[@x='1']"/> -->
+ <xsl:apply-templates select="key('k','1')"/>
+ </xsl:template>
+
+ <xsl:template match="a">
+ <xsl:value-of select="@y"/>
+ </xsl:template>
+
+</xsl:transform>