From 58e98329ecf9ec88bdc04349a2c7bc64a220df63 Mon Sep 17 00:00:00 2001 From: "William M. Brack" Date: Mon, 2 Aug 2004 15:51:00 +0000 Subject: [PATCH] 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. --- ChangeLog | 7 +++++++ libxslt/documents.c | 6 ++++-- libxslt/functions.c | 30 ++++++++++++++++++++++++------ libxslt/transform.c | 10 +++++----- libxslt/variables.c | 9 +++++++++ tests/exslt/common/Makefile.am | 1 + tests/exslt/common/node-set.7.out | 2 ++ tests/exslt/common/node-set.7.xml | 1 + tests/exslt/common/node-set.7.xsl | 28 ++++++++++++++++++++++++++++ 9 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 tests/exslt/common/node-set.7.out create mode 100644 tests/exslt/common/node-set.7.xml create mode 100644 tests/exslt/common/node-set.7.xsl diff --git a/ChangeLog b/ChangeLog index 2b43575..ac61ff1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Mon Aug 2 08:48:03 PDT 2004 William Brack + + * 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 * libexslt/strings.c: fixed str:tokenize for case when 2nd diff --git a/libxslt/documents.c b/libxslt/documents.c index c4e4b36..a30374a 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 ad839cc..aa1a236 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 4be9ee7..35b6e2b 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 6cb2986..00b07b9 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 7a1f612..39decd9 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 0000000..dfb17cf --- /dev/null +++ b/tests/exslt/common/node-set.7.out @@ -0,0 +1,2 @@ + +A diff --git a/tests/exslt/common/node-set.7.xml b/tests/exslt/common/node-set.7.xml new file mode 100644 index 0000000..8eb294b --- /dev/null +++ b/tests/exslt/common/node-set.7.xml @@ -0,0 +1 @@ +junk diff --git a/tests/exslt/common/node-set.7.xsl b/tests/exslt/common/node-set.7.xsl new file mode 100644 index 0000000..7f1068e --- /dev/null +++ b/tests/exslt/common/node-set.7.xsl @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + -- 2.7.4