Index: third_party/libxslt/libxslt/pattern.c |
diff --git a/third_party/libxslt/libxslt/pattern.c b/third_party/libxslt/libxslt/pattern.c |
index 9e9fbd699604bc0a8d0f056d84bc450679a3ff6c..63ec25a31b7e25d02ec6e218c6d044a52ac0dbf6 100644 |
--- a/third_party/libxslt/libxslt/pattern.c |
+++ b/third_party/libxslt/libxslt/pattern.c |
@@ -25,6 +25,7 @@ |
#include <libxml/hash.h> |
#include <libxml/xmlerror.h> |
#include <libxml/parserInternals.h> |
+#include <libxml/xpath.h> |
#include "xslt.h" |
#include "xsltInternals.h" |
#include "xsltutils.h" |
@@ -127,9 +128,9 @@ struct _xsltParserContext { |
}; |
/************************************************************************ |
- * * |
- * Type functions * |
- * * |
+ * * |
+ * Type functions * |
+ * * |
************************************************************************/ |
/** |
@@ -303,6 +304,10 @@ xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, |
"xsltCompMatchAdd: memory re-allocation failure.\n"); |
if (ctxt->style != NULL) |
ctxt->style->errors++; |
+ if (value) |
+ xmlFree(value); |
+ if (value2) |
+ xmlFree(value2); |
return (-1); |
} |
comp->maxStep *= 2; |
@@ -368,7 +373,7 @@ xsltSwapTopCompMatch(xsltCompMatchPtr comp) { |
if (j > 0) { |
register xmlChar *tmp; |
register xsltOp op; |
- register xmlXPathCompExprPtr expr; |
+ register xmlXPathCompExprPtr expr; |
register int t; |
i = j - 1; |
tmp = comp->steps[i].value; |
@@ -469,9 +474,9 @@ xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) { |
} |
/************************************************************************ |
- * * |
- * The interpreter for the precompiled patterns * |
- * * |
+ * * |
+ * The interpreter for the precompiled patterns * |
+ * * |
************************************************************************/ |
static int |
@@ -540,19 +545,21 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, |
ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); |
list = (xmlXPathObjectPtr) |
XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra); |
- |
+ |
if ((list == NULL) || (prevdoc != doc)) { |
xmlXPathObjectPtr newlist; |
xmlNodePtr parent = node->parent; |
xmlDocPtr olddoc; |
xmlNodePtr oldnode; |
- int oldNsNr; |
+ int oldNsNr, oldContextSize, oldProximityPosition; |
xmlNsPtr *oldNamespaces; |
oldnode = ctxt->xpathCtxt->node; |
olddoc = ctxt->xpathCtxt->doc; |
oldNsNr = ctxt->xpathCtxt->nsNr; |
oldNamespaces = ctxt->xpathCtxt->namespaces; |
+ oldContextSize = ctxt->xpathCtxt->contextSize; |
+ oldProximityPosition = ctxt->xpathCtxt->proximityPosition; |
ctxt->xpathCtxt->node = node; |
ctxt->xpathCtxt->doc = doc; |
ctxt->xpathCtxt->namespaces = nsList; |
@@ -562,6 +569,8 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, |
ctxt->xpathCtxt->doc = olddoc; |
ctxt->xpathCtxt->namespaces = oldNamespaces; |
ctxt->xpathCtxt->nsNr = oldNsNr; |
+ ctxt->xpathCtxt->contextSize = oldContextSize; |
+ ctxt->xpathCtxt->proximityPosition = oldProximityPosition; |
if (newlist == NULL) |
return(-1); |
if (newlist->type != XPATH_NODESET) { |
@@ -572,7 +581,7 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, |
if ((parent == NULL) || (node->doc == NULL) || isRVT) |
nocache = 1; |
- |
+ |
if (nocache == 0) { |
if (list != NULL) |
xmlXPathFreeObject(list); |
@@ -754,8 +763,8 @@ restart: |
if (step->op == XSLT_OP_ROOT) |
goto found; |
/* added NS, ID and KEY as a result of bug 168208 */ |
- if ((step->op != XSLT_OP_ELEM) && |
- (step->op != XSLT_OP_ALL) && |
+ if ((step->op != XSLT_OP_ELEM) && |
+ (step->op != XSLT_OP_ALL) && |
(step->op != XSLT_OP_NS) && |
(step->op != XSLT_OP_ID) && |
(step->op != XSLT_OP_KEY)) |
@@ -863,7 +872,7 @@ restart: |
xmlFree(states.states); |
} |
return(xsltTestCompMatchDirect(ctxt, comp, node, |
- comp->nsList, comp->nsNr)); |
+ comp->nsList, comp->nsNr)); |
} |
doc = node->doc; |
@@ -884,11 +893,10 @@ restart: |
(node->type == XML_ELEMENT_NODE) && |
(node->parent != NULL)) { |
xmlNodePtr previous; |
- int ix, nocache = 0; |
+ int nocache = 0; |
previous = (xmlNodePtr) |
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr); |
- ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); |
if ((previous != NULL) && |
(previous->parent == node->parent)) { |
/* |
@@ -900,7 +908,7 @@ restart: |
while (sibling != NULL) { |
if (sibling == previous) |
break; |
- if ((previous->type == XML_ELEMENT_NODE) && |
+ if ((sibling->type == XML_ELEMENT_NODE) && |
(previous->name != NULL) && |
(sibling->name != NULL) && |
(previous->name[0] == sibling->name[0]) && |
@@ -921,7 +929,7 @@ restart: |
while (sibling != NULL) { |
if (sibling == previous) |
break; |
- if ((previous->type == XML_ELEMENT_NODE) && |
+ if ((sibling->type == XML_ELEMENT_NODE) && |
(previous->name != NULL) && |
(sibling->name != NULL) && |
(previous->name[0] == sibling->name[0]) && |
@@ -939,7 +947,8 @@ restart: |
} |
} |
if (sibling != NULL) { |
- pos = ix + indx; |
+ pos = XSLT_RUNTIME_EXTRA(ctxt, |
+ sel->indexExtra, ival) + indx; |
/* |
* If the node is in a Value Tree we need to |
* save len, but cannot cache the node! |
@@ -955,7 +964,6 @@ restart: |
sel->indexExtra, ival) = pos; |
} |
} |
- ix = pos; |
} else |
pos = 0; |
} else { |
@@ -1016,11 +1024,10 @@ restart: |
} else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) && |
(node->type == XML_ELEMENT_NODE)) { |
xmlNodePtr previous; |
- int ix, nocache = 0; |
+ int nocache = 0; |
previous = (xmlNodePtr) |
XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr); |
- ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); |
if ((previous != NULL) && |
(previous->parent == node->parent)) { |
/* |
@@ -1049,7 +1056,8 @@ restart: |
} |
} |
if (sibling != NULL) { |
- pos = ix + indx; |
+ pos = XSLT_RUNTIME_EXTRA(ctxt, |
+ sel->indexExtra, ival) + indx; |
/* |
* If the node is in a Value Tree we cannot |
* cache it ! |
@@ -1227,17 +1235,17 @@ xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, |
#define NXT(val) ctxt->cur[(val)] |
#define CUR_PTR ctxt->cur |
-#define SKIP_BLANKS \ |
+#define SKIP_BLANKS \ |
while (IS_BLANK_CH(CUR)) NEXT |
#define CURRENT (*ctxt->cur) |
#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) |
-#define PUSH(op, val, val2, novar) \ |
+#define PUSH(op, val, val2, novar) \ |
if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2), (novar))) goto error; |
-#define SWAP() \ |
+#define SWAP() \ |
xsltSwapTopCompMatch(ctxt->comp); |
#define XSLT_ERROR(X) \ |
@@ -1381,17 +1389,22 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, |
NEXT; |
SKIP_BLANKS; |
lit = xsltScanLiteral(ctxt); |
- if (ctxt->error) |
+ if (ctxt->error) { |
+ xsltTransformError(NULL, NULL, NULL, |
+ "xsltCompileIdKeyPattern : Literal expected\n"); |
return; |
+ } |
SKIP_BLANKS; |
if (CUR != ')') { |
xsltTransformError(NULL, NULL, NULL, |
"xsltCompileIdKeyPattern : ) expected\n"); |
+ xmlFree(lit); |
ctxt->error = 1; |
return; |
} |
NEXT; |
PUSH(XSLT_OP_ID, lit, NULL, novar); |
+ lit = NULL; |
} else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) { |
if (axis != 0) { |
xsltTransformError(NULL, NULL, NULL, |
@@ -1402,8 +1415,11 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, |
NEXT; |
SKIP_BLANKS; |
lit = xsltScanLiteral(ctxt); |
- if (ctxt->error) |
+ if (ctxt->error) { |
+ xsltTransformError(NULL, NULL, NULL, |
+ "xsltCompileIdKeyPattern : Literal expected\n"); |
return; |
+ } |
SKIP_BLANKS; |
if (CUR != ',') { |
xsltTransformError(NULL, NULL, NULL, |
@@ -1414,25 +1430,36 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, |
NEXT; |
SKIP_BLANKS; |
lit2 = xsltScanLiteral(ctxt); |
- if (ctxt->error) |
+ if (ctxt->error) { |
+ xsltTransformError(NULL, NULL, NULL, |
+ "xsltCompileIdKeyPattern : Literal expected\n"); |
+ xmlFree(lit); |
return; |
+ } |
SKIP_BLANKS; |
if (CUR != ')') { |
xsltTransformError(NULL, NULL, NULL, |
"xsltCompileIdKeyPattern : ) expected\n"); |
+ xmlFree(lit); |
+ xmlFree(lit2); |
ctxt->error = 1; |
return; |
} |
NEXT; |
/* URGENT TODO: support namespace in keys */ |
PUSH(XSLT_OP_KEY, lit, lit2, novar); |
+ lit = NULL; |
+ lit2 = NULL; |
} else if (xmlStrEqual(name, (const xmlChar *)"processing-instruction")) { |
NEXT; |
SKIP_BLANKS; |
if (CUR != ')') { |
lit = xsltScanLiteral(ctxt); |
- if (ctxt->error) |
+ if (ctxt->error) { |
+ xsltTransformError(NULL, NULL, NULL, |
+ "xsltCompileIdKeyPattern : Literal expected\n"); |
return; |
+ } |
SKIP_BLANKS; |
if (CUR != ')') { |
xsltTransformError(NULL, NULL, NULL, |
@@ -1443,6 +1470,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, |
} |
NEXT; |
PUSH(XSLT_OP_PI, lit, NULL, novar); |
+ lit = NULL; |
} else if (xmlStrEqual(name, (const xmlChar *)"text")) { |
NEXT; |
SKIP_BLANKS; |
@@ -1493,8 +1521,7 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, |
return; |
} |
error: |
- if (name != NULL) |
- xmlFree(name); |
+ return; |
} |
/** |
@@ -1506,7 +1533,7 @@ error: |
* Compile the XSLT StepPattern and generates a precompiled |
* form suitable for fast matching. |
* |
- * [5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* |
+ * [5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* |
* [6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifier |
* | ('child' | 'attribute') '::' |
* from XPath |
@@ -1557,6 +1584,8 @@ parse_node_test: |
SKIP_BLANKS; |
if (CUR == '(') { |
xsltCompileIdKeyPattern(ctxt, token, 0, novar, axis); |
+ xmlFree(token); |
+ token = NULL; |
if (ctxt->error) |
goto error; |
} else if (CUR == ':') { |
@@ -1575,20 +1604,24 @@ parse_node_test: |
"xsltCompileStepPattern : no namespace bound to prefix %s\n", |
prefix); |
xmlFree(prefix); |
+ prefix=NULL; |
ctxt->error = 1; |
goto error; |
} else { |
URL = xmlStrdup(ns->href); |
} |
xmlFree(prefix); |
+ prefix=NULL; |
if (token == NULL) { |
if (CUR == '*') { |
NEXT; |
if (axis == AXIS_ATTRIBUTE) { |
PUSH(XSLT_OP_ATTR, NULL, URL, novar); |
+ URL = NULL; |
} |
else { |
PUSH(XSLT_OP_NS, URL, NULL, novar); |
+ URL = NULL; |
} |
} else { |
xsltTransformError(NULL, NULL, NULL, |
@@ -1599,9 +1632,13 @@ parse_node_test: |
} else { |
if (axis == AXIS_ATTRIBUTE) { |
PUSH(XSLT_OP_ATTR, token, URL, novar); |
+ token = NULL; |
+ URL = NULL; |
} |
else { |
PUSH(XSLT_OP_ELEM, token, URL, novar); |
+ token = NULL; |
+ URL = NULL; |
} |
} |
} else { |
@@ -1623,6 +1660,7 @@ parse_node_test: |
goto error; |
} |
xmlFree(token); |
+ token = NULL; |
SKIP_BLANKS; |
token = xsltScanNCName(ctxt); |
goto parse_node_test; |
@@ -1637,9 +1675,13 @@ parse_node_test: |
URL = xmlStrdup(URI); |
if (axis == AXIS_ATTRIBUTE) { |
PUSH(XSLT_OP_ATTR, token, URL, novar); |
+ token = NULL; |
+ URL = NULL; |
} |
else { |
PUSH(XSLT_OP_ELEM, token, URL, novar); |
+ token = NULL; |
+ URL = NULL; |
} |
} |
parse_predicate: |
@@ -1679,6 +1721,7 @@ parse_predicate: |
} |
ret = xmlStrndup(q, CUR_PTR - q); |
PUSH(XSLT_OP_PREDICATE, ret, NULL, novar); |
+ ret = NULL; |
/* push the predicate lower than local test */ |
SWAP(); |
NEXT; |
@@ -1787,8 +1830,8 @@ xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) { |
SKIP_BLANKS; |
if ((CUR == '(') && !xmlXPathIsNodeType(name)) { |
xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0); |
- if (ctxt->error) |
- return; |
+ xmlFree(name); |
+ name = NULL; |
if ((CUR == '/') && (NXT(1) == '/')) { |
PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar); |
NEXT; |
@@ -1866,8 +1909,8 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc, |
while ((pattern[end] != 0) && (pattern[end] != '"')) |
end++; |
} |
- if (pattern[end] == 0) |
- break; |
+ if (pattern[end] == 0) |
+ break; |
end++; |
} |
if (current == end) { |
@@ -2044,12 +2087,12 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, |
pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem, |
style, NULL, 1); |
if (pat == NULL) |
- return(-1); |
+ return(-1); |
while (pat) { |
next = pat->next; |
pat->next = NULL; |
name = NULL; |
- |
+ |
pat->template = cur; |
if (mode != NULL) |
pat->mode = xmlDictLookup(style->dict, mode, -1); |
@@ -2436,7 +2479,7 @@ keyed_match: |
goto error; |
switch (node->type) { |
- case XML_ELEMENT_NODE: |
+ case XML_ELEMENT_NODE: |
if (node->psvi != NULL) keyed = 1; |
break; |
case XML_ATTRIBUTE_NODE: |
@@ -2445,13 +2488,13 @@ keyed_match: |
case XML_TEXT_NODE: |
case XML_CDATA_SECTION_NODE: |
case XML_COMMENT_NODE: |
- case XML_PI_NODE: |
+ case XML_PI_NODE: |
if (node->psvi != NULL) keyed = 1; |
break; |
case XML_DOCUMENT_NODE: |
case XML_HTML_DOCUMENT_NODE: |
if (((xmlDocPtr) node)->psvi != NULL) keyed = 1; |
- break; |
+ break; |
default: |
break; |
} |