| Index: third_party/libxslt/libxslt/transform.c
|
| diff --git a/third_party/libxslt/libxslt/transform.c b/third_party/libxslt/libxslt/transform.c
|
| index a4ca41df380ee2686b852b14713bd82958728c64..24f9eb2c37ff0f70b214f9295bad58ed9051414a 100644
|
| --- a/third_party/libxslt/libxslt/transform.c
|
| +++ b/third_party/libxslt/libxslt/transform.c
|
| @@ -20,6 +20,7 @@
|
| #include "libxslt.h"
|
|
|
| #include <string.h>
|
| +#include <stdio.h>
|
|
|
| #include <libxml/xmlmemory.h>
|
| #include <libxml/parser.h>
|
| @@ -64,6 +65,7 @@ static int xsltGetHTMLIDs(const xmlChar *version, const xmlChar **publicID,
|
| #endif
|
|
|
| int xsltMaxDepth = 3000;
|
| +int xsltMaxVars = 15000;
|
|
|
| /*
|
| * Useful macros
|
| @@ -125,7 +127,7 @@ templPush(xsltTransformContextPtr ctxt, xsltTemplatePtr value)
|
| return (0);
|
| }
|
| }
|
| - if (ctxt->templNr >= ctxt->templMax) {
|
| + else if (ctxt->templNr >= ctxt->templMax) {
|
| ctxt->templMax *= 2;
|
| ctxt->templTab =
|
| (xsltTemplatePtr *) xmlRealloc(ctxt->templTab,
|
| @@ -249,7 +251,7 @@ profPush(xsltTransformContextPtr ctxt, long value)
|
| return (0);
|
| }
|
| }
|
| - if (ctxt->profNr >= ctxt->profMax) {
|
| + else if (ctxt->profNr >= ctxt->profMax) {
|
| ctxt->profMax *= 2;
|
| ctxt->profTab =
|
| (long *) xmlRealloc(ctxt->profTab,
|
| @@ -288,6 +290,152 @@ profPop(xsltTransformContextPtr ctxt)
|
| return (ret);
|
| }
|
|
|
| +static void
|
| +profCallgraphAdd(xsltTemplatePtr templ, xsltTemplatePtr parent)
|
| +{
|
| + int i;
|
| +
|
| + if (templ->templMax == 0) {
|
| + templ->templMax = 4;
|
| + templ->templCalledTab =
|
| + (xsltTemplatePtr *) xmlMalloc(templ->templMax *
|
| + sizeof(templ->templCalledTab[0]));
|
| + templ->templCountTab =
|
| + (int *) xmlMalloc(templ->templMax *
|
| + sizeof(templ->templCountTab[0]));
|
| + if (templ->templCalledTab == NULL || templ->templCountTab == NULL) {
|
| + xmlGenericError(xmlGenericErrorContext, "malloc failed !\n");
|
| + return;
|
| + }
|
| + }
|
| + else if (templ->templNr >= templ->templMax) {
|
| + templ->templMax *= 2;
|
| + templ->templCalledTab =
|
| + (xsltTemplatePtr *) xmlRealloc(templ->templCalledTab,
|
| + templ->templMax *
|
| + sizeof(templ->templCalledTab[0]));
|
| + templ->templCountTab =
|
| + (int *) xmlRealloc(templ->templCountTab,
|
| + templ->templMax *
|
| + sizeof(templ->templCountTab[0]));
|
| + if (templ->templCalledTab == NULL || templ->templCountTab == NULL) {
|
| + xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
|
| + return;
|
| + }
|
| + }
|
| +
|
| + for (i = 0; i < templ->templNr; i++) {
|
| + if (templ->templCalledTab[i] == parent) {
|
| + templ->templCountTab[i]++;
|
| + break;
|
| + }
|
| + }
|
| + if (i == templ->templNr) {
|
| + /* not found, add new one */
|
| + templ->templCalledTab[templ->templNr] = parent;
|
| + templ->templCountTab[templ->templNr] = 1;
|
| + templ->templNr++;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * xsltPreCompEval:
|
| + * @ctxt: transform context
|
| + * @node: context node
|
| + * @comp: precompiled expression
|
| + *
|
| + * Evaluate a precompiled XPath expression.
|
| + */
|
| +static xmlXPathObjectPtr
|
| +xsltPreCompEval(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| + xsltStylePreCompPtr comp) {
|
| + xmlXPathObjectPtr res;
|
| + xmlXPathContextPtr xpctxt;
|
| + xmlNodePtr oldXPContextNode;
|
| + xmlNsPtr *oldXPNamespaces;
|
| + int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
|
| +
|
| + xpctxt = ctxt->xpathCtxt;
|
| + oldXPContextNode = xpctxt->node;
|
| + oldXPProximityPosition = xpctxt->proximityPosition;
|
| + oldXPContextSize = xpctxt->contextSize;
|
| + oldXPNsNr = xpctxt->nsNr;
|
| + oldXPNamespaces = xpctxt->namespaces;
|
| +
|
| + xpctxt->node = node;
|
| +#ifdef XSLT_REFACTORED
|
| + if (comp->inScopeNs != NULL) {
|
| + xpctxt->namespaces = comp->inScopeNs->list;
|
| + xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| + } else {
|
| + xpctxt->namespaces = NULL;
|
| + xpctxt->nsNr = 0;
|
| + }
|
| +#else
|
| + xpctxt->namespaces = comp->nsList;
|
| + xpctxt->nsNr = comp->nsNr;
|
| +#endif
|
| +
|
| + res = xmlXPathCompiledEval(comp->comp, xpctxt);
|
| +
|
| + xpctxt->node = oldXPContextNode;
|
| + xpctxt->proximityPosition = oldXPProximityPosition;
|
| + xpctxt->contextSize = oldXPContextSize;
|
| + xpctxt->nsNr = oldXPNsNr;
|
| + xpctxt->namespaces = oldXPNamespaces;
|
| +
|
| + return(res);
|
| +}
|
| +
|
| +/**
|
| + * xsltPreCompEvalToBoolean:
|
| + * @ctxt: transform context
|
| + * @node: context node
|
| + * @comp: precompiled expression
|
| + *
|
| + * Evaluate a precompiled XPath expression as boolean.
|
| + */
|
| +static int
|
| +xsltPreCompEvalToBoolean(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| + xsltStylePreCompPtr comp) {
|
| + int res;
|
| + xmlXPathContextPtr xpctxt;
|
| + xmlNodePtr oldXPContextNode;
|
| + xmlNsPtr *oldXPNamespaces;
|
| + int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
|
| +
|
| + xpctxt = ctxt->xpathCtxt;
|
| + oldXPContextNode = xpctxt->node;
|
| + oldXPProximityPosition = xpctxt->proximityPosition;
|
| + oldXPContextSize = xpctxt->contextSize;
|
| + oldXPNsNr = xpctxt->nsNr;
|
| + oldXPNamespaces = xpctxt->namespaces;
|
| +
|
| + xpctxt->node = node;
|
| +#ifdef XSLT_REFACTORED
|
| + if (comp->inScopeNs != NULL) {
|
| + xpctxt->namespaces = comp->inScopeNs->list;
|
| + xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| + } else {
|
| + xpctxt->namespaces = NULL;
|
| + xpctxt->nsNr = 0;
|
| + }
|
| +#else
|
| + xpctxt->namespaces = comp->nsList;
|
| + xpctxt->nsNr = comp->nsNr;
|
| +#endif
|
| +
|
| + res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt);
|
| +
|
| + xpctxt->node = oldXPContextNode;
|
| + xpctxt->proximityPosition = oldXPProximityPosition;
|
| + xpctxt->contextSize = oldXPContextSize;
|
| + xpctxt->nsNr = oldXPNsNr;
|
| + xpctxt->namespaces = oldXPNamespaces;
|
| +
|
| + return(res);
|
| +}
|
| +
|
| /************************************************************************
|
| * *
|
| * XInclude default settings *
|
| @@ -456,6 +604,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
| cur->templNr = 0;
|
| cur->templMax = 5;
|
| cur->templ = NULL;
|
| + cur->maxTemplateDepth = xsltMaxDepth;
|
|
|
| /*
|
| * initialize the variables stack
|
| @@ -471,6 +620,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
|
| cur->varsMax = 10;
|
| cur->vars = NULL;
|
| cur->varsBase = 0;
|
| + cur->maxTemplateVars = xsltMaxVars;
|
|
|
| /*
|
| * the profiling stack is not initialized by default
|
| @@ -726,7 +876,7 @@ xsltCopyTextString(xsltTransformContextPtr ctxt, xmlNodePtr target,
|
| #endif
|
|
|
| /*
|
| - * Play save and reset the merging mechanism for every new
|
| + * Play safe and reset the merging mechanism for every new
|
| * target node.
|
| */
|
| if ((target == NULL) || (target->children == NULL)) {
|
| @@ -2935,8 +3085,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| * Check for infinite recursion: stop if the maximum of nested templates
|
| * is excceeded. Adjust xsltMaxDepth if you need more.
|
| */
|
| - if (((ctxt->templNr >= xsltMaxDepth) ||
|
| - (ctxt->varsNr >= 5 * xsltMaxDepth)))
|
| + if (ctxt->templNr >= ctxt->maxTemplateDepth)
|
| {
|
| xsltTransformError(ctxt, NULL, list,
|
| "xsltApplyXSLTTemplate: A potential infinite template recursion "
|
| @@ -2944,11 +3093,23 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| "You can adjust xsltMaxDepth (--maxdepth) in order to "
|
| "raise the maximum number of nested template calls and "
|
| "variables/params (currently set to %d).\n",
|
| - xsltMaxDepth);
|
| + ctxt->maxTemplateDepth);
|
| xsltDebug(ctxt, contextNode, list, NULL);
|
| return;
|
| }
|
|
|
| + if (ctxt->varsNr >= ctxt->maxTemplateVars)
|
| + {
|
| + xsltTransformError(ctxt, NULL, list,
|
| + "xsltApplyXSLTTemplate: A potential infinite template recursion "
|
| + "was detected.\n"
|
| + "You can adjust maxTemplateVars (--maxvars) in order to "
|
| + "raise the maximum number of variables/params (currently set to %d).\n",
|
| + ctxt->maxTemplateVars);
|
| + xsltDebug(ctxt, contextNode, list, NULL);
|
| + return;
|
| + }
|
| +
|
| oldUserFragmentTop = ctxt->tmpRVT;
|
| ctxt->tmpRVT = NULL;
|
| oldLocalFragmentTop = ctxt->localRVT;
|
| @@ -2964,6 +3125,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| templ->nbCalls++;
|
| start = xsltTimestamp();
|
| profPush(ctxt, 0);
|
| + profCallgraphAdd(templ, ctxt->templ);
|
| }
|
| /*
|
| * Push the xsl:template declaration onto the stack.
|
| @@ -3230,6 +3392,7 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| const xmlChar *doctypeSystem;
|
| const xmlChar *version;
|
| const xmlChar *encoding;
|
| + int redirect_write_append = 0;
|
|
|
| if ((ctxt == NULL) || (node == NULL) || (inst == NULL) || (comp == NULL))
|
| return;
|
| @@ -3645,10 +3808,38 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| }
|
|
|
| /*
|
| - * Save the result
|
| + * Calls to redirect:write also take an optional attribute append.
|
| + * Attribute append="true|yes" which will attempt to simply append
|
| + * to an existing file instead of always opening a new file. The
|
| + * default behavior of always overwriting the file still happens
|
| + * if we do not specify append.
|
| + * Note that append use will forbid use of remote URI target.
|
| */
|
| - ret = xsltSaveResultToFilename((const char *) filename,
|
| - res, style, 0);
|
| + prop = xsltEvalAttrValueTemplate(ctxt, inst, (const xmlChar *)"append",
|
| + NULL);
|
| + if (prop != NULL) {
|
| + if (xmlStrEqual(prop, (const xmlChar *) "true") ||
|
| + xmlStrEqual(prop, (const xmlChar *) "yes")) {
|
| + style->omitXmlDeclaration = 1;
|
| + redirect_write_append = 1;
|
| + } else
|
| + style->omitXmlDeclaration = 0;
|
| + xmlFree(prop);
|
| + }
|
| +
|
| + if (redirect_write_append) {
|
| + FILE *f;
|
| +
|
| + f = fopen((const char *) filename, "ab");
|
| + if (f == NULL) {
|
| + ret = -1;
|
| + } else {
|
| + ret = xsltSaveResultToFile(f, res, style);
|
| + fclose(f);
|
| + }
|
| + } else {
|
| + ret = xsltSaveResultToFilename((const char *) filename, res, style, 0);
|
| + }
|
| if (ret < 0) {
|
| xsltTransformError(ctxt, NULL, inst,
|
| "xsltDocumentElem: unable to save to %s\n",
|
| @@ -3915,14 +4106,6 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| }
|
| name = xsltSplitQName(ctxt->dict, prop, &prefix);
|
| xmlFree(prop);
|
| - if ((prefix != NULL) &&
|
| - (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
|
| - {
|
| - /*
|
| - * TODO: Should we really disallow an "xml" prefix?
|
| - */
|
| - goto error;
|
| - }
|
| } else {
|
| /*
|
| * The "name" value was static.
|
| @@ -3977,7 +4160,19 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| if ((tmpNsName != NULL) && (tmpNsName[0] != 0))
|
| nsName = xmlDictLookup(ctxt->dict, BAD_CAST tmpNsName, -1);
|
| xmlFree(tmpNsName);
|
| - };
|
| + }
|
| +
|
| + if (xmlStrEqual(nsName, BAD_CAST "http://www.w3.org/2000/xmlns/")) {
|
| + xsltTransformError(ctxt, NULL, inst,
|
| + "xsl:attribute: Namespace http://www.w3.org/2000/xmlns/ "
|
| + "forbidden.\n");
|
| + goto error;
|
| + }
|
| + if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
|
| + prefix = BAD_CAST "xml";
|
| + } else if (xmlStrEqual(prefix, BAD_CAST "xml")) {
|
| + prefix = NULL;
|
| + }
|
| } else {
|
| xmlNsPtr ns;
|
| /*
|
| @@ -3993,13 +4188,13 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| * TODO: Check this in the compilation layer in case it's a
|
| * static value.
|
| */
|
| - if (prefix != NULL) {
|
| - xsltTransformError(ctxt, NULL, inst,
|
| - "xsl:element: The QName '%s:%s' has no "
|
| - "namespace binding in scope in the stylesheet; "
|
| - "this is an error, since the namespace was not "
|
| - "specified by the instruction itself.\n", prefix, name);
|
| - }
|
| + if (prefix != NULL) {
|
| + xsltTransformError(ctxt, NULL, inst,
|
| + "xsl:element: The QName '%s:%s' has no "
|
| + "namespace binding in scope in the stylesheet; "
|
| + "this is an error, since the namespace was not "
|
| + "specified by the instruction itself.\n", prefix, name);
|
| + }
|
| } else
|
| nsName = ns->href;
|
| }
|
| @@ -4007,7 +4202,17 @@ xsltElement(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| * Find/create a matching ns-decl in the result tree.
|
| */
|
| if (nsName != NULL) {
|
| - copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix, copy);
|
| + if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
|
| + /* Don't use a prefix of "xmlns" */
|
| + xmlChar *pref = xmlStrdup(BAD_CAST "ns_1");
|
| +
|
| + copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, pref, copy);
|
| +
|
| + xmlFree(pref);
|
| + } else {
|
| + copy->ns = xsltGetSpecialNamespace(ctxt, inst, nsName, prefix,
|
| + copy);
|
| + }
|
| } else if ((copy->parent != NULL) &&
|
| (copy->parent->type == XML_ELEMENT_NODE) &&
|
| (copy->parent->ns != NULL))
|
| @@ -4180,11 +4385,6 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| xmlXPathObjectPtr res = NULL;
|
| xmlNodeSetPtr list = NULL;
|
| int i;
|
| - xmlDocPtr oldXPContextDoc;
|
| - xmlNsPtr *oldXPNamespaces;
|
| - xmlNodePtr oldXPContextNode;
|
| - int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
|
| - xmlXPathContextPtr xpctxt;
|
|
|
| if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
|
| return;
|
| @@ -4220,42 +4420,7 @@ xsltCopyOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| /*
|
| * Evaluate the "select" expression.
|
| */
|
| - xpctxt = ctxt->xpathCtxt;
|
| - oldXPContextDoc = xpctxt->doc;
|
| - oldXPContextNode = xpctxt->node;
|
| - oldXPProximityPosition = xpctxt->proximityPosition;
|
| - oldXPContextSize = xpctxt->contextSize;
|
| - oldXPNsNr = xpctxt->nsNr;
|
| - oldXPNamespaces = xpctxt->namespaces;
|
| -
|
| - xpctxt->node = node;
|
| - if (comp != NULL) {
|
| -
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -
|
| - res = xmlXPathCompiledEval(comp->comp, xpctxt);
|
| -
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->node = oldXPContextNode;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| + res = xsltPreCompEval(ctxt, node, comp);
|
|
|
| if (res != NULL) {
|
| if (res->type == XPATH_NODESET) {
|
| @@ -4364,13 +4529,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| xsltStylePreCompPtr comp = castedComp;
|
| #endif
|
| xmlXPathObjectPtr res = NULL;
|
| - xmlNodePtr copy = NULL;
|
| xmlChar *value = NULL;
|
| - xmlDocPtr oldXPContextDoc;
|
| - xmlNsPtr *oldXPNamespaces;
|
| - xmlNodePtr oldXPContextNode;
|
| - int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
|
| - xmlXPathContextPtr xpctxt;
|
|
|
| if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
|
| return;
|
| @@ -4387,42 +4546,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| "xsltValueOf: select %s\n", comp->select));
|
| #endif
|
|
|
| - xpctxt = ctxt->xpathCtxt;
|
| - oldXPContextDoc = xpctxt->doc;
|
| - oldXPContextNode = xpctxt->node;
|
| - oldXPProximityPosition = xpctxt->proximityPosition;
|
| - oldXPContextSize = xpctxt->contextSize;
|
| - oldXPNsNr = xpctxt->nsNr;
|
| - oldXPNamespaces = xpctxt->namespaces;
|
| -
|
| - xpctxt->node = node;
|
| - if (comp != NULL) {
|
| -
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -
|
| - res = xmlXPathCompiledEval(comp->comp, xpctxt);
|
| -
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->node = oldXPContextNode;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| + res = xsltPreCompEval(ctxt, node, comp);
|
|
|
| /*
|
| * Cast the XPath object to string.
|
| @@ -4437,8 +4561,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| goto error;
|
| }
|
| if (value[0] != 0) {
|
| - copy = xsltCopyTextString(ctxt,
|
| - ctxt->insert, value, comp->noescape);
|
| + xsltCopyTextString(ctxt, ctxt->insert, value, comp->noescape);
|
| }
|
| } else {
|
| xsltTransformError(ctxt, NULL, inst,
|
| @@ -4479,6 +4602,10 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| #else
|
| xsltStylePreCompPtr comp = castedComp;
|
| #endif
|
| + xmlXPathContextPtr xpctxt;
|
| + xmlNsPtr *oldXPNamespaces;
|
| + int oldXPNsNr;
|
| +
|
| if (comp == NULL) {
|
| xsltTransformError(ctxt, NULL, inst,
|
| "xsl:number : compilation failed\n");
|
| @@ -4491,7 +4618,27 @@ xsltNumber(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| comp->numdata.doc = inst->doc;
|
| comp->numdata.node = inst;
|
|
|
| + xpctxt = ctxt->xpathCtxt;
|
| + oldXPNsNr = xpctxt->nsNr;
|
| + oldXPNamespaces = xpctxt->namespaces;
|
| +
|
| +#ifdef XSLT_REFACTORED
|
| + if (comp->inScopeNs != NULL) {
|
| + xpctxt->namespaces = comp->inScopeNs->list;
|
| + xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| + } else {
|
| + xpctxt->namespaces = NULL;
|
| + xpctxt->nsNr = 0;
|
| + }
|
| +#else
|
| + xpctxt->namespaces = comp->nsList;
|
| + xpctxt->nsNr = comp->nsNr;
|
| +#endif
|
| +
|
| xsltNumberFormat(ctxt, &comp->numdata, node);
|
| +
|
| + xpctxt->nsNr = oldXPNsNr;
|
| + xpctxt->namespaces = oldXPNamespaces;
|
| }
|
|
|
| /**
|
| @@ -4685,12 +4832,11 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| xmlNodePtr cur, delNode = NULL, oldContextNode;
|
| xmlNodeSetPtr list = NULL, oldList;
|
| xsltStackElemPtr withParams = NULL;
|
| - int oldXPProximityPosition, oldXPContextSize, oldXPNsNr;
|
| + int oldXPProximityPosition, oldXPContextSize;
|
| const xmlChar *oldMode, *oldModeURI;
|
| xmlDocPtr oldXPDoc;
|
| xsltDocumentPtr oldDocInfo;
|
| xmlXPathContextPtr xpctxt;
|
| - xmlNsPtr *oldXPNamespaces;
|
|
|
| if (comp == NULL) {
|
| xsltTransformError(ctxt, NULL, inst,
|
| @@ -4724,8 +4870,6 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| oldXPContextSize = xpctxt->contextSize;
|
| oldXPProximityPosition = xpctxt->proximityPosition;
|
| oldXPDoc = xpctxt->doc;
|
| - oldXPNsNr = xpctxt->nsNr;
|
| - oldXPNamespaces = xpctxt->namespaces;
|
|
|
| /*
|
| * Set up contexts.
|
| @@ -4746,26 +4890,8 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| "xsltApplyTemplates: select %s\n", comp->select));
|
| #endif
|
|
|
| - /*
|
| - * Set up XPath.
|
| - */
|
| - xpctxt->node = node; /* Set the "context node" */
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
| - res = xmlXPathCompiledEval(comp->comp, xpctxt);
|
| + res = xsltPreCompEval(ctxt, node, comp);
|
|
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| if (res != NULL) {
|
| if (res->type == XPATH_NODESET) {
|
| list = res->nodesetval; /* consume the node set */
|
| @@ -4832,7 +4958,10 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| list = xmlXPathNodeSetCreate(NULL);
|
| if (list == NULL)
|
| goto error;
|
| - cur = node->children;
|
| + if (node->type != XML_NAMESPACE_DECL)
|
| + cur = node->children;
|
| + else
|
| + cur = NULL;
|
| while (cur != NULL) {
|
| switch (cur->type) {
|
| case XML_TEXT_NODE:
|
| @@ -4881,6 +5010,8 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| if (cur->prev != NULL)
|
| cur->prev->next = cur->next;
|
| break;
|
| + case XML_NAMESPACE_DECL:
|
| + break;
|
| default:
|
| #ifdef WITH_XSLT_DEBUG_PROCESS
|
| XSLT_TRACE(ctxt,XSLT_TRACE_APPLY_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
|
| @@ -5043,8 +5174,6 @@ error:
|
| /*
|
| * Restore context states.
|
| */
|
| - xpctxt->nsNr = oldXPNsNr;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| xpctxt->doc = oldXPDoc;
|
| xpctxt->contextSize = oldXPContextSize;
|
| xpctxt->proximityPosition = oldXPProximityPosition;
|
| @@ -5100,12 +5229,6 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
|
|
| {
|
| int testRes = 0, res = 0;
|
| - xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
|
| - xmlDocPtr oldXPContextDoc = xpctxt->doc;
|
| - int oldXPProximityPosition = xpctxt->proximityPosition;
|
| - int oldXPContextSize = xpctxt->contextSize;
|
| - xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
|
| - int oldXPNsNr = xpctxt->nsNr;
|
|
|
| #ifdef XSLT_REFACTORED
|
| xsltStyleItemWhenPtr wcomp = NULL;
|
| @@ -5142,27 +5265,8 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
| "xsltChoose: test %s\n", wcomp->test));
|
| #endif
|
|
|
| - xpctxt->node = contextNode;
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| -
|
| -#ifdef XSLT_REFACTORED
|
| - if (wcomp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = wcomp->inScopeNs->list;
|
| - xpctxt->nsNr = wcomp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = wcomp->nsList;
|
| - xpctxt->nsNr = wcomp->nsNr;
|
| -#endif
|
| -
|
| -
|
| #ifdef XSLT_FAST_IF
|
| - res = xmlXPathCompiledEvalToBoolean(wcomp->comp, xpctxt);
|
| + res = xsltPreCompEvalToBoolean(ctxt, contextNode, wcomp);
|
|
|
| if (res == -1) {
|
| ctxt->state = XSLT_STATE_STOPPED;
|
| @@ -5172,7 +5276,7 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
|
|
| #else /* XSLT_FAST_IF */
|
|
|
| - res = xmlXPathCompiledEval(wcomp->comp, xpctxt);
|
| + res = xsltPreCompEval(ctxt, cotextNode, wcomp);
|
|
|
| if (res != NULL) {
|
| if (res->type != XPATH_BOOLEAN)
|
| @@ -5221,22 +5325,10 @@ xsltChoose(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
| #endif
|
| goto test_is_true;
|
| }
|
| - xpctxt->node = contextNode;
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| goto exit;
|
|
|
| test_is_true:
|
|
|
| - xpctxt->node = contextNode;
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| goto process_sequence;
|
| }
|
|
|
| @@ -5290,38 +5382,9 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
|
|
| #ifdef XSLT_FAST_IF
|
| {
|
| - xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
|
| - xmlDocPtr oldXPContextDoc = xpctxt->doc;
|
| - xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
|
| - xmlNodePtr oldXPContextNode = xpctxt->node;
|
| - int oldXPProximityPosition = xpctxt->proximityPosition;
|
| - int oldXPContextSize = xpctxt->contextSize;
|
| - int oldXPNsNr = xpctxt->nsNr;
|
| xmlDocPtr oldLocalFragmentTop = ctxt->localRVT;
|
|
|
| - xpctxt->node = contextNode;
|
| - if (comp != NULL) {
|
| -
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| - /*
|
| - * This XPath function is optimized for boolean results.
|
| - */
|
| - res = xmlXPathCompiledEvalToBoolean(comp->comp, xpctxt);
|
| + res = xsltPreCompEvalToBoolean(ctxt, contextNode, comp);
|
|
|
| /*
|
| * Cleanup fragments created during evaluation of the
|
| @@ -5329,13 +5392,6 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
| */
|
| if (oldLocalFragmentTop != ctxt->localRVT)
|
| xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
|
| -
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->node = oldXPContextNode;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| }
|
|
|
| #ifdef WITH_XSLT_DEBUG_PROCESS
|
| @@ -5357,51 +5413,10 @@ xsltIf(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
|
|
| #else /* XSLT_FAST_IF */
|
| {
|
| - xmlXPathObjectPtr xpobj = NULL;
|
| /*
|
| * OLD CODE:
|
| */
|
| - {
|
| - xmlXPathContextPtr xpctxt = ctxt->xpathCtxt;
|
| - xmlDocPtr oldXPContextDoc = xpctxt->doc;
|
| - xmlNsPtr *oldXPNamespaces = xpctxt->namespaces;
|
| - xmlNodePtr oldXPContextNode = xpctxt->node;
|
| - int oldXPProximityPosition = xpctxt->proximityPosition;
|
| - int oldXPContextSize = xpctxt->contextSize;
|
| - int oldXPNsNr = xpctxt->nsNr;
|
| -
|
| - xpctxt->node = contextNode;
|
| - if (comp != NULL) {
|
| -
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -
|
| - /*
|
| - * This XPath function is optimized for boolean results.
|
| - */
|
| - xpobj = xmlXPathCompiledEval(comp->comp, xpctxt);
|
| -
|
| - xpctxt->doc = oldXPContextDoc;
|
| - xpctxt->node = oldXPContextNode;
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->nsNr = oldXPNsNr;
|
| - xpctxt->namespaces = oldXPNamespaces;
|
| - }
|
| + xmlXPathObjectPtr xpobj = xsltPreCompEval(ctxt, contextNode, comp);
|
| if (xpobj != NULL) {
|
| if (xpobj->type != XPATH_BOOLEAN)
|
| xpobj = xmlXPathConvertBoolean(xpobj);
|
| @@ -5508,27 +5523,11 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
| oldXPDoc = xpctxt->doc;
|
| oldXPProximityPosition = xpctxt->proximityPosition;
|
| oldXPContextSize = xpctxt->contextSize;
|
| - /*
|
| - * Set up XPath.
|
| - */
|
| - xpctxt->node = contextNode;
|
| -#ifdef XSLT_REFACTORED
|
| - if (comp->inScopeNs != NULL) {
|
| - xpctxt->namespaces = comp->inScopeNs->list;
|
| - xpctxt->nsNr = comp->inScopeNs->xpathNumber;
|
| - } else {
|
| - xpctxt->namespaces = NULL;
|
| - xpctxt->nsNr = 0;
|
| - }
|
| -#else
|
| - xpctxt->namespaces = comp->nsList;
|
| - xpctxt->nsNr = comp->nsNr;
|
| -#endif
|
|
|
| /*
|
| * Evaluate the 'select' expression.
|
| */
|
| - res = xmlXPathCompiledEval(comp->comp, ctxt->xpathCtxt);
|
| + res = xsltPreCompEval(ctxt, contextNode, comp);
|
|
|
| if (res != NULL) {
|
| if (res->type == XPATH_NODESET)
|
| @@ -5559,13 +5558,6 @@ xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
| #endif
|
|
|
| /*
|
| - * Restore XPath states for the "current node".
|
| - */
|
| - xpctxt->contextSize = oldXPContextSize;
|
| - xpctxt->proximityPosition = oldXPProximityPosition;
|
| - xpctxt->node = contextNode;
|
| -
|
| - /*
|
| * Set the list; this has to be done already here for xsltDoSortFunction().
|
| */
|
| ctxt->nodeList = list;
|
|
|