mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-02-05 05:47:00 +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:
parent
f3455ecd52
commit
e632d9f02e
11
fuzz/xpath.c
11
fuzz/xpath.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
60
xpointer.c
60
xpointer.c
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user