trying to harden the XPath interpreter Daniel
* xpath.c: trying to harden the XPath interpreter
Daniel
diff --git a/xpath.c b/xpath.c
index 8bbe15c..89ee25e 100644
--- a/xpath.c
+++ b/xpath.c
@@ -2421,7 +2421,7 @@
ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
(ctxt->varLookupData, name, NULL);
- if (ret != NULL) return(ret);
+ return(ret);
}
return(xmlXPathVariableLookupNS(ctxt, name, NULL));
}
@@ -8769,6 +8769,7 @@
xmlXPathCompExprPtr comp;
xmlXPathObjectPtr arg1, arg2;
+ CHECK_ERROR0;
comp = ctxt->comp;
switch (op->op) {
case XPATH_OP_END:
@@ -8777,6 +8778,7 @@
total =
xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
first);
+ CHECK_ERROR0;
if ((ctxt->value != NULL)
&& (ctxt->value->type == XPATH_NODESET)
&& (ctxt->value->nodesetval != NULL)
@@ -8790,6 +8792,7 @@
cur =
xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2],
first);
+ CHECK_ERROR0;
CHECK_TYPE0(XPATH_NODESET);
arg2 = valuePop(ctxt);
@@ -8810,15 +8813,19 @@
case XPATH_OP_NODE:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
return (total);
case XPATH_OP_RESET:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
ctxt->context->node = NULL;
return (total);
case XPATH_OP_COLLECT:{
@@ -8826,6 +8833,7 @@
return (total);
total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
/*
* Optimization for [n] selection where n is a number
@@ -8861,6 +8869,7 @@
total +=
xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
first);
+ CHECK_ERROR0;
if ((ctxt->value != NULL)
&& (ctxt->value->type == XPATH_NODESET)
&& (ctxt->value->nodesetval != NULL))
@@ -8890,6 +8899,7 @@
xmlXPathCompExprPtr comp;
xmlXPathObjectPtr arg1, arg2;
+ CHECK_ERROR0;
comp = ctxt->comp;
switch (op->op) {
case XPATH_OP_END:
@@ -8897,6 +8907,7 @@
case XPATH_OP_UNION:
total =
xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
+ CHECK_ERROR0;
if ((ctxt->value != NULL)
&& (ctxt->value->type == XPATH_NODESET)
&& (ctxt->value->nodesetval != NULL)
@@ -8912,6 +8923,7 @@
}
cur =
xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last);
+ CHECK_ERROR0;
if ((ctxt->value != NULL)
&& (ctxt->value->type == XPATH_NODESET)
&& (ctxt->value->nodesetval != NULL)
@@ -8937,15 +8949,19 @@
case XPATH_OP_NODE:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
return (total);
case XPATH_OP_RESET:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
ctxt->context->node = NULL;
return (total);
case XPATH_OP_COLLECT:{
@@ -8953,6 +8969,7 @@
return (0);
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
/*
* Optimization for [n] selection where n is a number
@@ -8990,6 +9007,7 @@
total +=
xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1],
last);
+ CHECK_ERROR0;
if ((ctxt->value != NULL)
&& (ctxt->value->type == XPATH_NODESET)
&& (ctxt->value->nodesetval != NULL))
@@ -9016,17 +9034,23 @@
xmlXPathCompExprPtr comp;
xmlXPathObjectPtr arg1, arg2;
+ CHECK_ERROR0;
comp = ctxt->comp;
switch (op->op) {
case XPATH_OP_END:
return (0);
case XPATH_OP_AND:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
xmlXPathBooleanFunction(ctxt, 1);
if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
return (total);
arg2 = valuePop(ctxt);
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ if (ctxt->error) {
+ xmlXPathFreeObject(arg2);
+ return(0);
+ }
xmlXPathBooleanFunction(ctxt, 1);
arg1 = valuePop(ctxt);
arg1->boolval &= arg2->boolval;
@@ -9035,11 +9059,16 @@
return (total);
case XPATH_OP_OR:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
xmlXPathBooleanFunction(ctxt, 1);
if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
return (total);
arg2 = valuePop(ctxt);
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ if (ctxt->error) {
+ xmlXPathFreeObject(arg2);
+ return(0);
+ }
xmlXPathBooleanFunction(ctxt, 1);
arg1 = valuePop(ctxt);
arg1->boolval |= arg2->boolval;
@@ -9048,7 +9077,9 @@
return (total);
case XPATH_OP_EQUAL:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
equal = xmlXPathEqualValues(ctxt);
if (op->value)
valuePush(ctxt, xmlXPathNewBoolean(equal));
@@ -9057,14 +9088,18 @@
return (total);
case XPATH_OP_CMP:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
valuePush(ctxt, xmlXPathNewBoolean(ret));
return (total);
case XPATH_OP_PLUS:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
if (op->value == 0)
xmlXPathSubValues(ctxt);
else if (op->value == 1)
@@ -9078,7 +9113,9 @@
return (total);
case XPATH_OP_MULT:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
if (op->value == 0)
xmlXPathMultValues(ctxt);
else if (op->value == 1)
@@ -9088,7 +9125,9 @@
return (total);
case XPATH_OP_UNION:
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
CHECK_TYPE0(XPATH_NODESET);
arg2 = valuePop(ctxt);
@@ -9106,15 +9145,19 @@
case XPATH_OP_NODE:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
return (total);
case XPATH_OP_RESET:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
ctxt->context->node = NULL;
return (total);
case XPATH_OP_COLLECT:{
@@ -9122,6 +9165,7 @@
return (total);
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
/*
* Optimization for [n] selection where n is a number
@@ -9155,14 +9199,19 @@
xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
return (total);
case XPATH_OP_VARIABLE:{
+ xmlXPathObjectPtr val;
+
if (op->ch1 != -1)
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- if (op->value5 == NULL)
- valuePush(ctxt,
- xmlXPathVariableLookup(ctxt->context,
- op->value4));
- else {
+ if (op->value5 == NULL) {
+ val = xmlXPathVariableLookup(ctxt->context, op->value4);
+ if (val == NULL) {
+ ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
+ return(0);
+ }
+ valuePush(ctxt, val);
+ } else {
const xmlChar *URI;
URI = xmlXPathNsLookup(ctxt->context, op->value5);
@@ -9172,19 +9221,37 @@
op->value4, op->value5);
return (total);
}
- valuePush(ctxt,
- xmlXPathVariableLookupNS(ctxt->context,
- op->value4, URI));
+ val = xmlXPathVariableLookupNS(ctxt->context,
+ op->value4, URI);
+ if (val == NULL) {
+ ctxt->error = XPATH_UNDEF_VARIABLE_ERROR;
+ return(0);
+ }
+ valuePush(ctxt, val);
}
return (total);
}
case XPATH_OP_FUNCTION:{
xmlXPathFunction func;
const xmlChar *oldFunc, *oldFuncURI;
+ int i;
if (op->ch1 != -1)
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ if (ctxt->valueNr < op->value) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlXPathRunEval: parameter error\n");
+ ctxt->error = XPATH_INVALID_OPERAND;
+ return (total);
+ }
+ for (i = 0; i < op->value; i++)
+ if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlXPathRunEval: parameter error\n");
+ ctxt->error = XPATH_INVALID_OPERAND;
+ return (total);
+ }
if (op->cache != NULL)
func = (xmlXPathFunction) op->cache;
else {
@@ -9227,8 +9294,10 @@
case XPATH_OP_ARG:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
+ CHECK_ERROR0;
return (total);
case XPATH_OP_PREDICATE:
case XPATH_OP_FILTER:{
@@ -9256,6 +9325,7 @@
xmlXPathCompOpEvalFirst(ctxt,
&comp->steps[op->ch1],
&first);
+ CHECK_ERROR0;
/*
* The nodeset should be in document order,
* Keep only the first value
@@ -9289,6 +9359,7 @@
xmlXPathCompOpEvalLast(ctxt,
&comp->steps[op->ch1],
&last);
+ CHECK_ERROR0;
/*
* The nodeset should be in document order,
* Keep only the last value
@@ -9313,6 +9384,7 @@
if (op->ch1 != -1)
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if (op->ch2 == -1)
return (total);
if (ctxt->value == NULL)
@@ -9427,6 +9499,7 @@
total +=
xmlXPathCompOpEval(ctxt,
&comp->steps[op->ch2]);
+ CHECK_ERROR0;
res = valuePop(ctxt);
if (res != NULL)
xmlXPathFreeObject(res);
@@ -9493,6 +9566,7 @@
case XPATH_OP_SORT:
if (op->ch1 != -1)
total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+ CHECK_ERROR0;
if ((ctxt->value != NULL) &&
(ctxt->value->type == XPATH_NODESET) &&
(ctxt->value->nodesetval != NULL))