Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Unified Diff: third_party/libxslt/libxslt/variables.c

Issue 2411263002: Roll libxslt to 8345634c5482ca04293ae1862d52fa9dd764aeca (Closed)
Patch Set: config.log Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/libxslt/libxslt/variables.h ('k') | third_party/libxslt/libxslt/xslt.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/libxslt/libxslt/variables.c
diff --git a/third_party/libxslt/libxslt/variables.c b/third_party/libxslt/libxslt/variables.c
index 345123d6ac144b1e15e0cfb60a21373e0a29aa95..e1a80eeee56b037961237fee0e1fc8caf011cd8e 100644
--- a/third_party/libxslt/libxslt/variables.c
+++ b/third_party/libxslt/libxslt/variables.c
@@ -43,8 +43,8 @@ const xmlChar *xsltDocFragFake = (const xmlChar *) " fake node libxslt";
const xmlChar *xsltComputingGlobalVarMarker =
(const xmlChar *) " var/param being computed";
-#define XSLT_VAR_GLOBAL 1<<0
-#define XSLT_VAR_IN_SELECT 1<<1
+#define XSLT_VAR_GLOBAL (1<<0)
+#define XSLT_VAR_IN_SELECT (1<<1)
#define XSLT_TCTXT_VARIABLE(c) ((xsltStackElemPtr) (c)->contextVariable)
/************************************************************************
@@ -122,6 +122,9 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
if ((ctxt == NULL) || (RVT == NULL))
return(-1);
+ RVT->prev = NULL;
+ RVT->psvi = XSLT_RVT_VARIABLE;
+
/*
* We'll restrict the lifetime of user-created fragments
* insinde an xsl:variable and xsl:param to the lifetime of the
@@ -159,15 +162,18 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
if ((ctxt == NULL) || (RVT == NULL))
return(-1);
+ RVT->prev = NULL;
+
/*
* When evaluating "select" expressions of xsl:variable
* and xsl:param, we need to bind newly created tree fragments
- * to the variable itself; otherwise the tragment will be
+ * to the variable itself; otherwise the fragment will be
* freed before we leave the scope of a var.
*/
if ((ctxt->contextVariable != NULL) &&
(XSLT_TCTXT_VARIABLE(ctxt)->flags & XSLT_VAR_IN_SELECT))
{
+ RVT->psvi = XSLT_RVT_VARIABLE;
RVT->next = (xmlNodePtr) XSLT_TCTXT_VARIABLE(ctxt)->fragment;
XSLT_TCTXT_VARIABLE(ctxt)->fragment = RVT;
return(0);
@@ -177,19 +183,11 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
* If not reference by a returning instruction (like EXSLT's function),
* then this fragment will be freed, when the instruction exits.
*/
+ RVT->psvi = XSLT_RVT_LOCAL;
RVT->next = (xmlNodePtr) ctxt->localRVT;
if (ctxt->localRVT != NULL)
ctxt->localRVT->prev = (xmlNodePtr) RVT;
ctxt->localRVT = RVT;
- /*
- * We need to keep track of the first registered fragment
- * for extension instructions which return fragments
- * (e.g. EXSLT'S function), in order to let
- * xsltExtensionInstructionResultFinalize() clear the
- * preserving flag on the fragments.
- */
- if (ctxt->localRVTBase == NULL)
- ctxt->localRVTBase = RVT;
return(0);
}
@@ -204,26 +202,16 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
* collector will free them after the function-calling process exits.
*
* Returns 0 in case of success and -1 in case of API or internal errors.
+ *
+ * This function is unsupported in newer releases of libxslt.
*/
int
xsltExtensionInstructionResultFinalize(xsltTransformContextPtr ctxt)
{
- xmlDocPtr cur;
-
- if (ctxt == NULL)
- return(-1);
- if (ctxt->localRVTBase == NULL)
- return(0);
- /*
- * Enable remaining local tree fragments to be freed
- * by the fragment garbage collector.
- */
- cur = ctxt->localRVTBase;
- do {
- cur->psvi = NULL;
- cur = (xmlDocPtr) cur->next;
- } while (cur != NULL);
- return(0);
+ xmlGenericError(xmlGenericErrorContext,
+ "xsltExtensionInstructionResultFinalize is unsupported "
+ "in this release of libxslt.\n");
+ return(-1);
}
/**
@@ -238,11 +226,35 @@ xsltExtensionInstructionResultFinalize(xsltTransformContextPtr ctxt)
* tree fragments (via xsltCreateRVT()) with xsltRegisterLocalRVT().
*
* Returns 0 in case of success and -1 in case of error.
+ *
+ * It isn't necessary to call this function in newer releases of
+ * libxslt.
*/
int
xsltExtensionInstructionResultRegister(xsltTransformContextPtr ctxt,
xmlXPathObjectPtr obj)
{
+ return(0);
+}
+
+/**
+ * xsltFlagRVTs:
+ * @ctxt: an XSLT transformation context
+ * @obj: an XPath object to be inspected for result tree fragments
+ * @val: the flag value
+ *
+ * Updates ownership information of RVTs in @obj according to @val.
+ *
+ * @val = XSLT_RVT_FUNC_RESULT for the result of an extension function, so its
+ * RVTs won't be destroyed after leaving the returning scope.
+ * @val = XSLT_RVT_LOCAL for the result of an extension function to reset
+ * the state of its RVTs after it was returned to a new scope.
+ * @val = XSLT_RVT_GLOBAL for parts of global variables.
+ *
+ * Returns 0 in case of success and -1 in case of error.
+ */
+int
+xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) {
int i;
xmlNodePtr cur;
xmlDocPtr doc;
@@ -275,36 +287,59 @@ xsltExtensionInstructionResultRegister(xsltTransformContextPtr ctxt,
doc = cur->doc;
} else {
xsltTransformError(ctxt, NULL, ctxt->inst,
- "Internal error in "
- "xsltExtensionInstructionResultRegister(): "
+ "Internal error in xsltFlagRVTs(): "
"Cannot retrieve the doc of a namespace node.\n");
- goto error;
+ return(-1);
}
} else {
doc = cur->doc;
}
if (doc == NULL) {
xsltTransformError(ctxt, NULL, ctxt->inst,
- "Internal error in "
- "xsltExtensionInstructionResultRegister(): "
+ "Internal error in xsltFlagRVTs(): "
"Cannot retrieve the doc of a node.\n");
- goto error;
+ return(-1);
}
- if (doc->name && (doc->name[0] == ' ')) {
+ if (doc->name && (doc->name[0] == ' ') &&
+ doc->psvi != XSLT_RVT_GLOBAL) {
/*
* This is a result tree fragment.
- * We'll use the @psvi field for reference counting.
- * TODO: How do we know if this is a value of a
- * global variable or a doc acquired via the
+ * We store ownership information in the @psvi field.
+ * TODO: How do we know if this is a doc acquired via the
* document() function?
*/
- doc->psvi = (void *) ((long) 1);
+#ifdef WITH_XSLT_DEBUG_VARIABLE
+ XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
+ "Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val));
+#endif
+
+ if (val == XSLT_RVT_LOCAL) {
+ if (doc->psvi != XSLT_RVT_FUNC_RESULT) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xsltFlagRVTs: Invalid transition %p => LOCAL\n",
+ doc->psvi);
+ return(-1);
+ }
+
+ xsltRegisterLocalRVT(ctxt, doc);
+ } else if (val == XSLT_RVT_GLOBAL) {
+ if (doc->psvi != XSLT_RVT_LOCAL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xsltFlagRVTs: Invalid transition %p => GLOBAL\n",
+ doc->psvi);
+ doc->psvi = XSLT_RVT_GLOBAL;
+ return(-1);
+ }
+
+ /* Will be registered as persistant in xsltReleaseLocalRVTs. */
+ doc->psvi = XSLT_RVT_GLOBAL;
+ } else if (val == XSLT_RVT_FUNC_RESULT) {
+ doc->psvi = val;
+ }
}
}
return(0);
-error:
- return(-1);
}
/**
@@ -350,9 +385,9 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
}
/*
- * Reset the reference counter.
+ * Reset the ownership information.
*/
- RVT->psvi = 0;
+ RVT->psvi = NULL;
RVT->next = (xmlNodePtr) ctxt->cache->RVT;
ctxt->cache->RVT = RVT;
@@ -391,6 +426,8 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
{
if ((ctxt == NULL) || (RVT == NULL)) return(-1);
+ RVT->psvi = XSLT_RVT_GLOBAL;
+ RVT->prev = NULL;
RVT->next = (xmlNodePtr) ctxt->persistRVT;
if (ctxt->persistRVT != NULL)
ctxt->persistRVT->prev = (xmlNodePtr) RVT;
@@ -541,35 +578,21 @@ xsltFreeStackElem(xsltStackElemPtr elem) {
/*
* Release the list of temporary Result Tree Fragments.
*/
- if (elem->fragment) {
+ if (elem->context) {
xmlDocPtr cur;
while (elem->fragment != NULL) {
cur = elem->fragment;
elem->fragment = (xmlDocPtr) cur->next;
- if (elem->context &&
- (cur->psvi == (void *) ((long) 1)))
- {
- /*
- * This fragment is a result of an extension instruction
- * (e.g. XSLT's function) and needs to be preserved until
- * the instruction exits.
- * Example: The fragment of the variable must not be freed
- * since it is returned by the EXSLT function:
- * <f:function name="foo">
- * <xsl:variable name="bar">
- * <bar/>
- * </xsl:variable>
- * <f:result select="$bar"/>
- * </f:function>
- *
- */
- xsltRegisterLocalRVT(elem->context, cur);
- } else {
+ if (cur->psvi == XSLT_RVT_VARIABLE) {
xsltReleaseRVT((xsltTransformContextPtr) elem->context,
cur);
- }
+ } else if (cur->psvi != XSLT_RVT_FUNC_RESULT) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xsltFreeStackElem: Unexpected RVT flag %p\n",
+ cur->psvi);
+ }
}
}
/*
@@ -963,6 +986,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
* the Result Tree Fragment.
*/
variable->fragment = container;
+ container->psvi = XSLT_RVT_VARIABLE;
oldOutput = ctxt->output;
oldInsert = ctxt->insert;
@@ -1149,16 +1173,23 @@ xsltEvalGlobalVariable(xsltStackElemPtr elem, xsltTransformContextPtr ctxt)
xsltTransformError(ctxt, NULL, comp->inst,
"Evaluating global variable %s failed\n", elem->name);
ctxt->state = XSLT_STATE_STOPPED;
+ goto error;
+ }
+
+ /*
+ * Mark all RVTs that are referenced from result as part
+ * of this variable so they won't be freed too early.
+ */
+ xsltFlagRVTs(ctxt, result, XSLT_RVT_GLOBAL);
+
#ifdef WITH_XSLT_DEBUG_VARIABLE
#ifdef LIBXML_DEBUG_ENABLED
- } else {
- if ((xsltGenericDebugContext == stdout) ||
- (xsltGenericDebugContext == stderr))
- xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
- result, 0);
+ if ((xsltGenericDebugContext == stdout) ||
+ (xsltGenericDebugContext == stderr))
+ xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext,
+ result, 0);
#endif
#endif
- }
} else {
if (elem->tree == NULL) {
result = xmlXPathNewCString("");
@@ -1772,8 +1803,7 @@ xsltBuildVariable(xsltTransformContextPtr ctxt,
elem->tree = tree;
elem->value = xsltEvalVariable(ctxt, elem,
(xsltStylePreCompPtr) comp);
- if (elem->value != NULL)
- elem->computed = 1;
+ elem->computed = 1;
return(elem);
}
« no previous file with comments | « third_party/libxslt/libxslt/variables.h ('k') | third_party/libxslt/libxslt/xslt.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698