| Index: third_party/libxslt/libxslt/transform.c
|
| diff --git a/third_party/libxslt/libxslt/transform.c b/third_party/libxslt/libxslt/transform.c
|
| index 8b86e2ebc0d96c81bea6a35ee113c023c0717759..b3fce80aade12a9a1e7eba718d0cc66b60e6412c 100644
|
| --- a/third_party/libxslt/libxslt/transform.c
|
| +++ b/third_party/libxslt/libxslt/transform.c
|
| @@ -56,6 +56,7 @@
|
| #ifdef WITH_XSLT_DEBUG
|
| #define WITH_XSLT_DEBUG_EXTRA
|
| #define WITH_XSLT_DEBUG_PROCESS
|
| +#define WITH_XSLT_DEBUG_VARIABLE
|
| #endif
|
|
|
| #define XSLT_GENERATE_HTML_DOCTYPE
|
| @@ -784,7 +785,7 @@ static xmlNodePtr
|
| xsltAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
| xmlNodePtr ret;
|
|
|
| - if ((cur == NULL) || (parent == NULL))
|
| + if (cur == NULL)
|
| return(NULL);
|
| if (parent == NULL) {
|
| xmlFreeNode(cur);
|
| @@ -2020,6 +2021,9 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
|
|
| /*
|
| * Handling of Elements: second pass, actual processing
|
| + *
|
| + * Note that params are passed to the next template. This matches
|
| + * XSLT 2.0 behavior but doesn't conform to XSLT 1.0.
|
| */
|
| oldSize = ctxt->xpathCtxt->contextSize;
|
| oldPos = ctxt->xpathCtxt->proximityPosition;
|
| @@ -2299,30 +2303,28 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
|
| {
|
| xmlDocPtr cur = ctxt->localRVT, tmp;
|
|
|
| - while ((cur != NULL) && (cur != base)) {
|
| - if (cur->psvi == (void *) ((long) 1)) {
|
| - cur = (xmlDocPtr) cur->next;
|
| - } else {
|
| - tmp = cur;
|
| - cur = (xmlDocPtr) cur->next;
|
| -
|
| - if (tmp == ctxt->localRVT)
|
| - ctxt->localRVT = cur;
|
| + if (cur == base)
|
| + return;
|
| + if (cur->prev != NULL)
|
| + xsltTransformError(ctxt, NULL, NULL, "localRVT not head of list\n");
|
|
|
| - /*
|
| - * We need ctxt->localRVTBase for extension instructions
|
| - * which return values (like EXSLT's function).
|
| - */
|
| - if (tmp == ctxt->localRVTBase)
|
| - ctxt->localRVTBase = cur;
|
| + do {
|
| + tmp = cur;
|
| + cur = (xmlDocPtr) cur->next;
|
| + if (tmp->psvi == XSLT_RVT_LOCAL) {
|
| + xsltReleaseRVT(ctxt, tmp);
|
| + } else if (tmp->psvi == XSLT_RVT_GLOBAL) {
|
| + xsltRegisterPersistRVT(ctxt, tmp);
|
| + } else if (tmp->psvi != XSLT_RVT_FUNC_RESULT) {
|
| + xmlGenericError(xmlGenericErrorContext,
|
| + "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
|
| + tmp->psvi);
|
| + }
|
| + } while (cur != base);
|
|
|
| - if (tmp->prev)
|
| - tmp->prev->next = (xmlNodePtr) cur;
|
| - if (cur)
|
| - cur->prev = tmp->prev;
|
| - xsltReleaseRVT(ctxt, tmp);
|
| - }
|
| - }
|
| + if (base != NULL)
|
| + base->prev = NULL;
|
| + ctxt->localRVT = base;
|
| }
|
|
|
| /**
|
| @@ -2348,7 +2350,7 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| xmlNodePtr oldInsert, oldInst, oldCurInst, oldContextNode;
|
| xmlNodePtr cur, insert, copy = NULL;
|
| int level = 0, oldVarsNr;
|
| - xmlDocPtr oldLocalFragmentTop, oldLocalFragmentBase;
|
| + xmlDocPtr oldLocalFragmentTop;
|
|
|
| #ifdef XSLT_REFACTORED
|
| xsltStylePreCompPtr info;
|
| @@ -2376,6 +2378,24 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| return;
|
| CHECK_STOPPED;
|
|
|
| + /*
|
| + * Check for infinite recursion: stop if the maximum of nested templates
|
| + * is excceeded. Adjust xsltMaxDepth if you need more.
|
| + */
|
| + if (ctxt->depth >= ctxt->maxTemplateDepth) {
|
| + xsltTransformError(ctxt, NULL, list,
|
| + "xsltApplySequenceConstructor: A potential infinite template "
|
| + "recursion was detected.\n"
|
| + "You can adjust xsltMaxDepth (--maxdepth) in order to "
|
| + "raise the maximum number of nested template calls and "
|
| + "variables/params (currently set to %d).\n",
|
| + ctxt->maxTemplateDepth);
|
| + xsltDebug(ctxt, contextNode, list, NULL);
|
| + ctxt->state = XSLT_STATE_STOPPED;
|
| + return;
|
| + }
|
| + ctxt->depth++;
|
| +
|
| oldLocalFragmentTop = ctxt->localRVT;
|
| oldInsert = insert = ctxt->insert;
|
| oldInst = oldCurInst = ctxt->inst;
|
| @@ -2676,16 +2696,9 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| cur->name));
|
| #endif
|
| ctxt->insert = insert;
|
| - /*
|
| - * We need the fragment base for extension instructions
|
| - * which return values (like EXSLT's function).
|
| - */
|
| - oldLocalFragmentBase = ctxt->localRVTBase;
|
| - ctxt->localRVTBase = NULL;
|
|
|
| func(ctxt, contextNode, cur, cur->psvi);
|
|
|
| - ctxt->localRVTBase = oldLocalFragmentBase;
|
| /*
|
| * Cleanup temporary tree fragments.
|
| */
|
| @@ -2749,12 +2762,9 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| oldCurInst = ctxt->inst;
|
| ctxt->inst = cur;
|
| ctxt->insert = insert;
|
| - oldLocalFragmentBase = ctxt->localRVTBase;
|
| - ctxt->localRVTBase = NULL;
|
|
|
| info->func(ctxt, contextNode, cur, (xsltElemPreCompPtr) info);
|
|
|
| - ctxt->localRVTBase = oldLocalFragmentBase;
|
| /*
|
| * Cleanup temporary tree fragments.
|
| */
|
| @@ -2869,12 +2879,6 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| #endif
|
|
|
| ctxt->insert = insert;
|
| - /*
|
| - * We need the fragment base for extension instructions
|
| - * which return values (like EXSLT's function).
|
| - */
|
| - oldLocalFragmentBase = ctxt->localRVTBase;
|
| - ctxt->localRVTBase = NULL;
|
|
|
| function(ctxt, contextNode, cur, cur->psvi);
|
| /*
|
| @@ -2883,7 +2887,6 @@ xsltApplySequenceConstructor(xsltTransformContextPtr ctxt,
|
| if (oldLocalFragmentTop != ctxt->localRVT)
|
| xsltReleaseLocalRVTs(ctxt, oldLocalFragmentTop);
|
|
|
| - ctxt->localRVTBase = oldLocalFragmentBase;
|
| ctxt->insert = oldInsert;
|
|
|
| }
|
| @@ -3025,6 +3028,8 @@ error:
|
| ctxt->inst = oldInst;
|
| ctxt->insert = oldInsert;
|
|
|
| + ctxt->depth--;
|
| +
|
| #ifdef WITH_DEBUGGER
|
| if ((ctxt->debugStatus != XSLT_DEBUG_NONE) && (addCallResult)) {
|
| xslDropCall();
|
| @@ -3059,7 +3064,7 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| long start = 0;
|
| xmlNodePtr cur;
|
| xsltStackElemPtr tmpParam = NULL;
|
| - xmlDocPtr oldUserFragmentTop, oldLocalFragmentTop;
|
| + xmlDocPtr oldUserFragmentTop;
|
|
|
| #ifdef XSLT_REFACTORED
|
| xsltStyleItemParamPtr iparam;
|
| @@ -3091,23 +3096,6 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| return;
|
| CHECK_STOPPED;
|
|
|
| - /*
|
| - * Check for infinite recursion: stop if the maximum of nested templates
|
| - * is excceeded. Adjust xsltMaxDepth if you need more.
|
| - */
|
| - if (ctxt->templNr >= ctxt->maxTemplateDepth)
|
| - {
|
| - xsltTransformError(ctxt, NULL, list,
|
| - "xsltApplyXSLTTemplate: A potential infinite template recursion "
|
| - "was detected.\n"
|
| - "You can adjust xsltMaxDepth (--maxdepth) in order to "
|
| - "raise the maximum number of nested template calls and "
|
| - "variables/params (currently set to %d).\n",
|
| - ctxt->maxTemplateDepth);
|
| - xsltDebug(ctxt, contextNode, list, NULL);
|
| - return;
|
| - }
|
| -
|
| if (ctxt->varsNr >= ctxt->maxTemplateVars)
|
| {
|
| xsltTransformError(ctxt, NULL, list,
|
| @@ -3117,12 +3105,12 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| "raise the maximum number of variables/params (currently set to %d).\n",
|
| ctxt->maxTemplateVars);
|
| xsltDebug(ctxt, contextNode, list, NULL);
|
| + ctxt->state = XSLT_STATE_STOPPED;
|
| return;
|
| }
|
|
|
| oldUserFragmentTop = ctxt->tmpRVT;
|
| ctxt->tmpRVT = NULL;
|
| - oldLocalFragmentTop = ctxt->localRVT;
|
|
|
| /*
|
| * Initiate a distinct scope of local params/variables.
|
| @@ -3224,31 +3212,6 @@ xsltApplyXSLTTemplate(xsltTransformContextPtr ctxt,
|
| ctxt->varsBase = oldVarsBase;
|
|
|
| /*
|
| - * Clean up remaining local tree fragments.
|
| - * This also frees fragments which are the result of
|
| - * extension instructions. Should normally not be hit; but
|
| - * just for the case xsltExtensionInstructionResultFinalize()
|
| - * was not called by the extension author.
|
| - */
|
| - if (oldLocalFragmentTop != ctxt->localRVT) {
|
| - xmlDocPtr curdoc = ctxt->localRVT, tmp;
|
| -
|
| - do {
|
| - tmp = curdoc;
|
| - curdoc = (xmlDocPtr) curdoc->next;
|
| - /* Need to housekeep localRVTBase */
|
| - if (tmp == ctxt->localRVTBase)
|
| - ctxt->localRVTBase = curdoc;
|
| - if (tmp->prev)
|
| - tmp->prev->next = (xmlNodePtr) curdoc;
|
| - if (curdoc)
|
| - curdoc->prev = tmp->prev;
|
| - xsltReleaseRVT(ctxt, tmp);
|
| - } while (curdoc != oldLocalFragmentTop);
|
| - }
|
| - ctxt->localRVT = oldLocalFragmentTop;
|
| -
|
| - /*
|
| * Release user-created fragments stored in the scope
|
| * of xsl:template. Note that this mechanism is deprecated:
|
| * user code should now use xsltRegisterLocalRVT() instead
|
| @@ -3853,7 +3816,6 @@ xsltDocumentElem(xsltTransformContextPtr ctxt, xmlNodePtr node,
|
| xsltTransformError(ctxt, NULL, inst,
|
| "xsltDocumentElem: unable to save to %s\n",
|
| filename);
|
| - ctxt->state = XSLT_STATE_ERROR;
|
| #ifdef WITH_XSLT_DEBUG_EXTRA
|
| } else {
|
| xsltGenericDebug(xsltGenericDebugContext,
|
| @@ -4718,6 +4680,10 @@ xsltApplyImports(xsltTransformContextPtr ctxt, xmlNodePtr contextNode,
|
|
|
| ctxt->currentTemplateRule = oldCurTemplRule;
|
| }
|
| + else {
|
| + /* Use built-in templates. */
|
| + xsltDefaultProcessOneNode(ctxt, contextNode, NULL);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -6040,6 +6006,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
|
|
| xsltEvalGlobalVariables(ctxt);
|
|
|
| + /* Clean up any unused RVTs. */
|
| + xsltReleaseLocalRVTs(ctxt, NULL);
|
| +
|
| ctxt->node = (xmlNodePtr) doc;
|
| ctxt->output = res;
|
| ctxt->insert = (xmlNodePtr) res;
|
| @@ -6184,7 +6153,7 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
|
| /*
|
| * Be pedantic.
|
| */
|
| - if ((ctxt != NULL) && (ctxt->state == XSLT_STATE_ERROR)) {
|
| + if ((ctxt != NULL) && (ctxt->state != XSLT_STATE_OK)) {
|
| xmlFreeDoc(res);
|
| res = NULL;
|
| }
|
|
|