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

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

Issue 1193533007: Upgrade to libxml 2.9.2 and libxslt 1.1.28 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: no iconv Created 5 years, 6 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/templates.c ('k') | third_party/libxslt/libxslt/variables.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..35701deabb6eb3546461223687521b5f1b928be7 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,54 @@ 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++;
+ }
+}
+
/************************************************************************
* *
* XInclude default settings *
@@ -456,6 +506,7 @@ xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
cur->templNr = 0;
cur->templMax = 5;
cur->templ = NULL;
+ cur->maxTemplateDepth = xsltMaxDepth;
/*
* initialize the variables stack
@@ -471,6 +522,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 +778,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 +2987,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 +2995,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 +3027,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 +3294,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 +3710,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 +4008,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 +4062,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 +4090,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 +4104,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))
@@ -4364,7 +4471,6 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltStylePreCompPtr comp = castedComp;
#endif
xmlXPathObjectPtr res = NULL;
- xmlNodePtr copy = NULL;
xmlChar *value = NULL;
xmlDocPtr oldXPContextDoc;
xmlNsPtr *oldXPNamespaces;
@@ -4437,8 +4543,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,
@@ -4832,7 +4937,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 +4989,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,
« no previous file with comments | « third_party/libxslt/libxslt/templates.c ('k') | third_party/libxslt/libxslt/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698