author | Tomas Kuthan <tomas.kuthan@oracle.com> |
Mon, 11 Jun 2012 22:35:26 -0700 | |
changeset 866 | c6e2467e422e |
parent 651 | 501e808038f6 |
permissions | -rw-r--r-- |
The contents of this patch taken directly from upstream: http://git.gnome.org/browse/libxml2/commit/?id=f5048b3e71fc30ad096970b8df6e7af073bae4cb via copy/paste of the code changes into the source files from which I generated new patch diffs. This explains the error of the missing 3 lines that are concatenated to the bottom of this patch. --- libxml2-2.7.6/xpath.c Wed Nov 30 08:31:34 2011 +++ libxml2-2.7.6/new.xpath.c Wed Nov 30 08:30:31 2011 @@ -252,6 +252,7 @@ "Encoding error\n", "Char out of XML range\n", "Invalid or incomplete context\n", + "Stack usage error\n", "?? Unknown error ??\n" /* Must be last in the list! */ }; #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \ @@ -2398,6 +2399,42 @@ ************************************************************************/ /** + * xmlXPathSetFrame: + * @ctxt: an XPath parser context + * + * Set the callee evaluation frame + * + * Returns the previous frame value to be restored once done + */ +static int +xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) { + int ret; + + if (ctxt == NULL) + return(0); + ret = ctxt->valueFrame; + ctxt->valueFrame = ctxt->valueNr; + return(ret); +} + +/** + * xmlXPathPopFrame: + * @ctxt: an XPath parser context + * @frame: the previous frame value + * + * Remove the callee evaluation frame + */ +static void +xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) { + if (ctxt == NULL) + return; + if (ctxt->valueNr < ctxt->valueFrame) { + xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); + } + ctxt->valueFrame = frame; +} + +/** * valuePop: * @ctxt: an XPath evaluation context * @@ -2412,6 +2449,12 @@ if ((ctxt == NULL) || (ctxt->valueNr <= 0)) return (NULL); + + if (ctxt->valueNr <= ctxt->valueFrame) { + xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); + return (NULL); + } + ctxt->valueNr--; if (ctxt->valueNr > 0) ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; @@ -6154,6 +6197,7 @@ ret->valueNr = 0; ret->valueMax = 10; ret->value = NULL; + ret->valueFrame = 0; ret->context = ctxt; ret->comp = comp; @@ -11688,6 +11732,7 @@ xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; xmlNodePtr oldContextNode, contextNode = NULL; xmlXPathContextPtr xpctxt = ctxt->context; + int frame; #ifdef LIBXML_XPTR_ENABLED /* @@ -11707,6 +11752,8 @@ */ exprOp = &ctxt->comp->steps[op->ch2]; for (i = 0; i < set->nodeNr; i++) { + xmlXPathObjectPtr tmp; + if (set->nodeTab[i] == NULL) continue; @@ -11738,19 +11785,18 @@ res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { - xmlXPathObjectPtr tmp; - /* pop the result if any */ - tmp = valuePop(ctxt); - if (tmp != contextObj) { + while (tmp != contextObj) { /* * Free up the result * then pop off contextObj, which will be freed later */ xmlXPathReleaseObject(xpctxt, tmp); - valuePop(ctxt); + tmp = valuePop(ctxt); } goto evaluation_error; } + /* push the result back onto the stack */ + valuePush(ctxt, tmp); if (res) pos++; @@ -13354,7 +13400,9 @@ xmlXPathFunction func; const xmlChar *oldFunc, *oldFuncURI; int i; + int frame; + frame = xmlXPathSetFrame(ctxt); if (op->ch1 != -1) total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); @@ -13362,15 +13410,18 @@ xmlGenericError(xmlGenericErrorContext, "xmlXPathCompOpEval: parameter error\n"); ctxt->error = XPATH_INVALID_OPERAND; + xmlXPathPopFrame(ctxt, frame); return (total); } - for (i = 0; i < op->value; i++) + for (i = 0; i < op->value; i++) { if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlXPathCompOpEval: parameter error\n"); ctxt->error = XPATH_INVALID_OPERAND; + xmlXPathPopFrame(ctxt, frame); return (total); } + } if (op->cache != NULL) XML_CAST_FPTR(func) = op->cache; else { @@ -13386,6 +13437,7 @@ xmlGenericError(xmlGenericErrorContext, "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", (char *)op->value4, (char *)op->value5); + xmlXPathPopFrame(ctxt, frame); return (total); } func = xmlXPathFunctionLookupNS(ctxt->context, @@ -13407,6 +13459,7 @@ func(ctxt, op->value); ctxt->context->function = oldFunc; ctxt->context->functionURI = oldFuncURI; + xmlXPathPopFrame(ctxt, frame); return (total); } case XPATH_OP_ARG: @@ -14310,6 +14363,7 @@ ctxt->valueNr = 0; ctxt->valueMax = 10; ctxt->value = NULL; + ctxt->valueFrame = 0; } #ifdef XPATH_STREAMING if (ctxt->comp->stream) { --- libxml2-2.7.6/include/libxml/xpath.h Thu Sep 24 08:31:59 2009 +++ libxml2-2.7.6/include/libxml/new.xpath.h Mon Oct 24 11:21:50 2011 @@ -68,7 +68,8 @@ XPATH_UNDEF_PREFIX_ERROR, XPATH_ENCODING_ERROR, XPATH_INVALID_CHAR_ERROR, - XPATH_INVALID_CTXT + XPATH_INVALID_CTXT, + XPATH_STACK_ERROR } xmlXPathError; /* @@ -380,6 +381,8 @@ xmlXPathCompExprPtr comp; /* the precompiled expression */ int xptr; /* it this an XPointer expression */ xmlNodePtr ancestor; /* used for walking preceding axis */ + + int valueFrame; /* used to limit Pop on the stack */ }; /************************************************************************ --- libxml2-2.7.6/xpointer.c Mon Oct 24 11:18:07 2011 +++ libxml2-2.7.6/new.xpointer.c Mon Oct 24 11:42:52 2011 @@ -1269,6 +1269,7 @@ ctxt->valueNr = 0; ctxt->valueMax = 10; ctxt->value = NULL; + ctxt->valueFrame = 0; } SKIP_BLANKS; if (CUR == '/') { --- libxml2-2.7.6/xpath.c Thu Jan 5 10:51:16 2012 +++ libxml2-2.7.6/xpath.c.new Thu Jan 5 11:00:39 2012 @@ -11781,8 +11781,11 @@ xmlXPathNodeSetAddUnique(contextObj->nodesetval, contextNode); + frame = xmlXPathSetFrame(ctxt); valuePush(ctxt, contextObj); res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); + tmp = valuePop(ctxt); + xmlXPathPopFrame(ctxt, frame); if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { while (tmp != contextObj) {