| 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;
|
| }
|
|
|