mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-08-08 21:42:07 +03:00
malloc-fail: Fix null deref in exsltFuncFunctionFunction
Found with libFuzzer, see #84.
This commit is contained in:
@@ -286,16 +286,12 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
exsltFuncData *data;
|
exsltFuncData *data;
|
||||||
exsltFuncFunctionData *func;
|
exsltFuncFunctionData *func;
|
||||||
xmlNodePtr paramNode, oldInsert, oldXPNode, fake;
|
xmlNodePtr paramNode, oldInsert, oldXPNode, fake;
|
||||||
int oldBase;
|
int oldBase, newBase;
|
||||||
void *oldCtxtVar;
|
void *oldCtxtVar;
|
||||||
xsltStackElemPtr params = NULL, param;
|
xsltStackElemPtr params = NULL, param;
|
||||||
xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
|
xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
|
||||||
int i, notSet;
|
int i;
|
||||||
struct objChain {
|
xmlXPathObjectPtr *args = NULL;
|
||||||
struct objChain *next;
|
|
||||||
xmlXPathObjectPtr obj;
|
|
||||||
};
|
|
||||||
struct objChain *savedObjChain = NULL, *savedObj;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* retrieve func:function template
|
* retrieve func:function template
|
||||||
@@ -357,6 +353,10 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
/* Evaluating templates can change the XPath context node. */
|
/* Evaluating templates can change the XPath context node. */
|
||||||
oldXPNode = tctxt->xpathCtxt->node;
|
oldXPNode = tctxt->xpathCtxt->node;
|
||||||
|
|
||||||
|
fake = xmlNewDocNode(tctxt->output, NULL,
|
||||||
|
(const xmlChar *)"fake", NULL);
|
||||||
|
if (fake == NULL)
|
||||||
|
goto error;
|
||||||
/*
|
/*
|
||||||
* We have a problem with the evaluation of function parameters.
|
* We have a problem with the evaluation of function parameters.
|
||||||
* The original library code did not evaluate XPath expressions until
|
* The original library code did not evaluate XPath expressions until
|
||||||
@@ -379,16 +379,15 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
* In order to give the function params and variables a new 'scope'
|
* In order to give the function params and variables a new 'scope'
|
||||||
* we change varsBase in the context.
|
* we change varsBase in the context.
|
||||||
*/
|
*/
|
||||||
oldBase = tctxt->varsBase;
|
newBase = tctxt->varsNr;
|
||||||
tctxt->varsBase = tctxt->varsNr;
|
|
||||||
/* If there are any parameters */
|
/* If there are any parameters */
|
||||||
if (paramNode != NULL) {
|
if (paramNode != NULL) {
|
||||||
|
args = (xmlXPathObjectPtr *) xmlMalloc(sizeof(*args) * nargs);
|
||||||
|
if (args == NULL)
|
||||||
|
goto error;
|
||||||
/* Fetch the stored argument values from the caller */
|
/* Fetch the stored argument values from the caller */
|
||||||
for (i = 0; i < nargs; i++) {
|
for (i = nargs - 1; i >= 0; i--) {
|
||||||
savedObj = xmlMalloc(sizeof(struct objChain));
|
args[i] = valuePop(ctxt);
|
||||||
savedObj->next = savedObjChain;
|
|
||||||
savedObj->obj = valuePop(ctxt);
|
|
||||||
savedObjChain = savedObj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -405,17 +404,20 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
* as arguments from the caller
|
* as arguments from the caller
|
||||||
* Calculate the number of un-set parameters
|
* Calculate the number of un-set parameters
|
||||||
*/
|
*/
|
||||||
notSet = func->nargs - nargs;
|
for (i = 0; i < func->nargs; i++) {
|
||||||
for (; i > 0; i--) {
|
|
||||||
param = xsltParseStylesheetCallerParam (tctxt, paramNode);
|
param = xsltParseStylesheetCallerParam (tctxt, paramNode);
|
||||||
if (i > notSet) { /* if parameter value set */
|
if (param == NULL) {
|
||||||
|
xsltLocalVariablePop(tctxt, newBase, -2);
|
||||||
|
xsltFreeStackElemList(params);
|
||||||
|
for (; i < nargs; i++)
|
||||||
|
xmlXPathFreeObject(args[i]);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (i < nargs) { /* if parameter value set */
|
||||||
param->computed = 1;
|
param->computed = 1;
|
||||||
if (param->value != NULL)
|
if (param->value != NULL)
|
||||||
xmlXPathFreeObject(param->value);
|
xmlXPathFreeObject(param->value);
|
||||||
savedObj = savedObjChain; /* get next val from chain */
|
param->value = args[i];
|
||||||
param->value = savedObj->obj;
|
|
||||||
savedObjChain = savedObjChain->next;
|
|
||||||
xmlFree(savedObj);
|
|
||||||
}
|
}
|
||||||
xsltLocalVariablePush(tctxt, param, -1);
|
xsltLocalVariablePush(tctxt, param, -1);
|
||||||
param->next = params;
|
param->next = params;
|
||||||
@@ -427,11 +429,11 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
* Actual processing. The context variable is cleared and restored
|
* Actual processing. The context variable is cleared and restored
|
||||||
* when func:result is evaluated.
|
* when func:result is evaluated.
|
||||||
*/
|
*/
|
||||||
fake = xmlNewDocNode(tctxt->output, NULL,
|
oldBase = tctxt->varsBase;
|
||||||
(const xmlChar *)"fake", NULL);
|
|
||||||
oldInsert = tctxt->insert;
|
oldInsert = tctxt->insert;
|
||||||
oldCtxtVar = data->ctxtVar;
|
oldCtxtVar = data->ctxtVar;
|
||||||
data->ctxtVar = tctxt->contextVariable;
|
data->ctxtVar = tctxt->contextVariable;
|
||||||
|
tctxt->varsBase = newBase;
|
||||||
tctxt->insert = fake;
|
tctxt->insert = fake;
|
||||||
tctxt->contextVariable = NULL;
|
tctxt->contextVariable = NULL;
|
||||||
xsltApplyOneTemplate (tctxt, tctxt->node,
|
xsltApplyOneTemplate (tctxt, tctxt->node,
|
||||||
@@ -470,14 +472,14 @@ exsltFuncFunctionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
"{%s}%s: cannot write to result tree while "
|
"{%s}%s: cannot write to result tree while "
|
||||||
"executing a function\n",
|
"executing a function\n",
|
||||||
ctxt->context->functionURI, ctxt->context->function);
|
ctxt->context->functionURI, ctxt->context->function);
|
||||||
xmlFreeNode(fake);
|
|
||||||
xmlXPathFreeObject(ret);
|
xmlXPathFreeObject(ret);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
xmlFreeNode(fake);
|
|
||||||
valuePush(ctxt, ret);
|
valuePush(ctxt, ret);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
xmlFree(args);
|
||||||
|
xmlFreeNode(fake);
|
||||||
tctxt->depth--;
|
tctxt->depth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user