1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +03:00

xpath: Report malloc failures

Fix many places where malloc failures aren't reported.

Rework XPath object cache to store free objects in a linked list to
avoid allocating an additional array. Remove some unneeded object pools.
This commit is contained in:
Nick Wellnhofer 2023-12-10 16:56:16 +01:00
parent f3455ecd52
commit e632d9f02e
4 changed files with 808 additions and 953 deletions

View File

@ -29,7 +29,7 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xmlFuzzDataInit(data, size);
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
expr = xmlFuzzReadString(&exprSize);
xml = xmlFuzzReadString(&xmlSize);
@ -42,10 +42,19 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
xpctxt = xmlXPathNewContext(doc);
if (xpctxt != NULL) {
int res;
/* Operation limit to avoid timeout */
xpctxt->opLimit = 500000;
res = xmlXPathContextSetCache(xpctxt, 1, 4, 0);
xmlFuzzCheckMallocFailure("xmlXPathContextSetCache", res == -1);
xmlFuzzResetMallocFailed();
xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt));
xmlFuzzCheckMallocFailure("xmlXPtrEval",
xpctxt->lastError.code ==
XML_ERR_NO_MEMORY);
xmlXPathFreeContext(xpctxt);
}

View File

@ -1,7 +1,16 @@
#ifndef XML_XPATH_H_PRIVATE__
#define XML_XPATH_H_PRIVATE__
#include <libxml/xpath.h>
XML_HIDDEN void
xmlInitXPathInternal(void);
#ifdef LIBXML_XPATH_ENABLED
XML_HIDDEN void
xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra);
XML_HIDDEN void
xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra);
#endif
#endif /* XML_XPATH_H_PRIVATE__ */

1681
xpath.c

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,7 @@
#define XPTR_XMLNS_SCHEME
#include "private/error.h"
#include "private/xpath.h"
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
@ -62,32 +63,19 @@
* *
************************************************************************/
/**
* xmlXPtrErrMemory:
* @extra: extra information
*
* Handle a redefinition of attribute error
*/
static void
xmlXPtrErrMemory(const char *extra)
{
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
NULL, NULL, 0, 0,
"Memory allocation failed : %s\n", extra);
}
/**
* xmlXPtrErr:
* @ctxt: an XPTR evaluation context
* @extra: extra information
*
* Handle a redefinition of attribute error
* Handle an XPointer error
*/
static void LIBXML_ATTR_FORMAT(3,0)
xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
const char * msg, const xmlChar *extra)
{
if (ctxt->context->lastError.code == XML_ERR_NO_MEMORY)
return;
if (ctxt != NULL)
ctxt->error = error;
if ((ctxt == NULL) || (ctxt->context == NULL)) {
@ -106,18 +94,26 @@ xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
ctxt->context->lastError.code = error;
ctxt->context->lastError.level = XML_ERR_ERROR;
ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
if (ctxt->context->lastError.str1 == NULL) {
xmlXPathPErrMemory(ctxt, NULL);
return;
}
ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
ctxt->context->lastError.node = ctxt->context->debugNode;
if (ctxt->context->error != NULL) {
ctxt->context->error(ctxt->context->userData,
&ctxt->context->lastError);
} else {
__xmlRaiseError(NULL, NULL, NULL,
int res;
res = __xmlRaiseError(NULL, NULL, NULL,
NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
error, XML_ERR_ERROR, NULL, 0,
(const char *) extra, (const char *) ctxt->base, NULL,
ctxt->cur - ctxt->base, 0,
msg, extra);
if (res < 0)
xmlXPathPErrMemory(ctxt, NULL);
}
}
@ -208,6 +204,21 @@ xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
* *
************************************************************************/
/**
* xmlXPtrErrMemory:
* @extra: extra information
*
* Handle a redefinition of attribute error
*/
static void
xmlXPtrErrMemory(const char *extra)
{
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
NULL, NULL, 0, 0,
"Memory allocation failed : %s\n", extra);
}
/**
* xmlXPtrCmpPoints:
* @node1: the first node
@ -959,7 +970,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
len++;
buffer = (xmlChar *) xmlMallocAtomic(len);
if (buffer == NULL) {
xmlXPtrErrMemory("allocating buffer");
xmlXPathPErrMemory(ctxt, "allocating buffer");
xmlFree(name);
return;
}
@ -1230,7 +1241,7 @@ xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
ctxt->valueTab = (xmlXPathObjectPtr *)
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
if (ctxt->valueTab == NULL) {
xmlXPtrErrMemory("allocating evaluation context");
xmlXPathPErrMemory(ctxt, "allocating evaluation context");
return;
}
ctxt->valueNr = 0;
@ -1351,10 +1362,16 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
if ((ctx == NULL) || (str == NULL))
return(NULL);
xmlResetError(&ctx->lastError);
ctxt = xmlXPathNewParserContext(str, ctx);
if (ctxt == NULL)
if (ctxt == NULL) {
xmlXPathErrMemory(ctx, NULL);
return(NULL);
}
xmlXPtrEvalXPointer(ctxt);
if (ctx->lastError.code != XML_ERR_OK)
goto error;
if ((ctxt->value != NULL) &&
#ifdef LIBXML_XPTR_LOCS_ENABLED
@ -1392,11 +1409,12 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
"xmlXPtrEval: object(s) left on the eval stack\n",
NULL);
}
if (ctxt->error != XPATH_EXPRESSION_OK) {
if (ctx->lastError.code != XML_ERR_OK) {
xmlXPathFreeObject(res);
res = NULL;
}
error:
xmlXPathFreeParserContext(ctxt);
return(res);
}