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:
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);
|
xmlFuzzDataInit(data, size);
|
||||||
|
|
||||||
maxAlloc = xmlFuzzReadInt(4) % (size + 1);
|
maxAlloc = xmlFuzzReadInt(4) % (size + 100);
|
||||||
expr = xmlFuzzReadString(&exprSize);
|
expr = xmlFuzzReadString(&exprSize);
|
||||||
xml = xmlFuzzReadString(&xmlSize);
|
xml = xmlFuzzReadString(&xmlSize);
|
||||||
|
|
||||||
@ -42,10 +42,19 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
|
|||||||
|
|
||||||
xpctxt = xmlXPathNewContext(doc);
|
xpctxt = xmlXPathNewContext(doc);
|
||||||
if (xpctxt != NULL) {
|
if (xpctxt != NULL) {
|
||||||
|
int res;
|
||||||
|
|
||||||
/* Operation limit to avoid timeout */
|
/* Operation limit to avoid timeout */
|
||||||
xpctxt->opLimit = 500000;
|
xpctxt->opLimit = 500000;
|
||||||
|
|
||||||
|
res = xmlXPathContextSetCache(xpctxt, 1, 4, 0);
|
||||||
|
xmlFuzzCheckMallocFailure("xmlXPathContextSetCache", res == -1);
|
||||||
|
|
||||||
|
xmlFuzzResetMallocFailed();
|
||||||
xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt));
|
xmlXPathFreeObject(xmlXPtrEval(BAD_CAST expr, xpctxt));
|
||||||
|
xmlFuzzCheckMallocFailure("xmlXPtrEval",
|
||||||
|
xpctxt->lastError.code ==
|
||||||
|
XML_ERR_NO_MEMORY);
|
||||||
xmlXPathFreeContext(xpctxt);
|
xmlXPathFreeContext(xpctxt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
#ifndef XML_XPATH_H_PRIVATE__
|
#ifndef XML_XPATH_H_PRIVATE__
|
||||||
#define XML_XPATH_H_PRIVATE__
|
#define XML_XPATH_H_PRIVATE__
|
||||||
|
|
||||||
|
#include <libxml/xpath.h>
|
||||||
|
|
||||||
XML_HIDDEN void
|
XML_HIDDEN void
|
||||||
xmlInitXPathInternal(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__ */
|
#endif /* XML_XPATH_H_PRIVATE__ */
|
||||||
|
60
xpointer.c
60
xpointer.c
@ -45,6 +45,7 @@
|
|||||||
#define XPTR_XMLNS_SCHEME
|
#define XPTR_XMLNS_SCHEME
|
||||||
|
|
||||||
#include "private/error.h"
|
#include "private/error.h"
|
||||||
|
#include "private/xpath.h"
|
||||||
|
|
||||||
#define TODO \
|
#define TODO \
|
||||||
xmlGenericError(xmlGenericErrorContext, \
|
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:
|
* xmlXPtrErr:
|
||||||
* @ctxt: an XPTR evaluation context
|
* @ctxt: an XPTR evaluation context
|
||||||
* @extra: extra information
|
* @extra: extra information
|
||||||
*
|
*
|
||||||
* Handle a redefinition of attribute error
|
* Handle an XPointer error
|
||||||
*/
|
*/
|
||||||
static void LIBXML_ATTR_FORMAT(3,0)
|
static void LIBXML_ATTR_FORMAT(3,0)
|
||||||
xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
|
xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
|
||||||
const char * msg, const xmlChar *extra)
|
const char * msg, const xmlChar *extra)
|
||||||
{
|
{
|
||||||
|
if (ctxt->context->lastError.code == XML_ERR_NO_MEMORY)
|
||||||
|
return;
|
||||||
if (ctxt != NULL)
|
if (ctxt != NULL)
|
||||||
ctxt->error = error;
|
ctxt->error = error;
|
||||||
if ((ctxt == NULL) || (ctxt->context == NULL)) {
|
if ((ctxt == NULL) || (ctxt->context == NULL)) {
|
||||||
@ -106,18 +94,26 @@ xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
|
|||||||
ctxt->context->lastError.code = error;
|
ctxt->context->lastError.code = error;
|
||||||
ctxt->context->lastError.level = XML_ERR_ERROR;
|
ctxt->context->lastError.level = XML_ERR_ERROR;
|
||||||
ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
|
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.int1 = ctxt->cur - ctxt->base;
|
||||||
ctxt->context->lastError.node = ctxt->context->debugNode;
|
ctxt->context->lastError.node = ctxt->context->debugNode;
|
||||||
if (ctxt->context->error != NULL) {
|
if (ctxt->context->error != NULL) {
|
||||||
ctxt->context->error(ctxt->context->userData,
|
ctxt->context->error(ctxt->context->userData,
|
||||||
&ctxt->context->lastError);
|
&ctxt->context->lastError);
|
||||||
} else {
|
} else {
|
||||||
__xmlRaiseError(NULL, NULL, NULL,
|
int res;
|
||||||
|
|
||||||
|
res = __xmlRaiseError(NULL, NULL, NULL,
|
||||||
NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
|
NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
|
||||||
error, XML_ERR_ERROR, NULL, 0,
|
error, XML_ERR_ERROR, NULL, 0,
|
||||||
(const char *) extra, (const char *) ctxt->base, NULL,
|
(const char *) extra, (const char *) ctxt->base, NULL,
|
||||||
ctxt->cur - ctxt->base, 0,
|
ctxt->cur - ctxt->base, 0,
|
||||||
msg, extra);
|
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:
|
* xmlXPtrCmpPoints:
|
||||||
* @node1: the first node
|
* @node1: the first node
|
||||||
@ -959,7 +970,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
|
|||||||
len++;
|
len++;
|
||||||
buffer = (xmlChar *) xmlMallocAtomic(len);
|
buffer = (xmlChar *) xmlMallocAtomic(len);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
xmlXPtrErrMemory("allocating buffer");
|
xmlXPathPErrMemory(ctxt, "allocating buffer");
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1230,7 +1241,7 @@ xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
|
|||||||
ctxt->valueTab = (xmlXPathObjectPtr *)
|
ctxt->valueTab = (xmlXPathObjectPtr *)
|
||||||
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
|
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
|
||||||
if (ctxt->valueTab == NULL) {
|
if (ctxt->valueTab == NULL) {
|
||||||
xmlXPtrErrMemory("allocating evaluation context");
|
xmlXPathPErrMemory(ctxt, "allocating evaluation context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctxt->valueNr = 0;
|
ctxt->valueNr = 0;
|
||||||
@ -1351,10 +1362,16 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
|
|||||||
if ((ctx == NULL) || (str == NULL))
|
if ((ctx == NULL) || (str == NULL))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
|
xmlResetError(&ctx->lastError);
|
||||||
|
|
||||||
ctxt = xmlXPathNewParserContext(str, ctx);
|
ctxt = xmlXPathNewParserContext(str, ctx);
|
||||||
if (ctxt == NULL)
|
if (ctxt == NULL) {
|
||||||
|
xmlXPathErrMemory(ctx, NULL);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
}
|
||||||
xmlXPtrEvalXPointer(ctxt);
|
xmlXPtrEvalXPointer(ctxt);
|
||||||
|
if (ctx->lastError.code != XML_ERR_OK)
|
||||||
|
goto error;
|
||||||
|
|
||||||
if ((ctxt->value != NULL) &&
|
if ((ctxt->value != NULL) &&
|
||||||
#ifdef LIBXML_XPTR_LOCS_ENABLED
|
#ifdef LIBXML_XPTR_LOCS_ENABLED
|
||||||
@ -1392,11 +1409,12 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
|
|||||||
"xmlXPtrEval: object(s) left on the eval stack\n",
|
"xmlXPtrEval: object(s) left on the eval stack\n",
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
if (ctxt->error != XPATH_EXPRESSION_OK) {
|
if (ctx->lastError.code != XML_ERR_OK) {
|
||||||
xmlXPathFreeObject(res);
|
xmlXPathFreeObject(res);
|
||||||
res = NULL;
|
res = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error:
|
||||||
xmlXPathFreeParserContext(ctxt);
|
xmlXPathFreeParserContext(ctxt);
|
||||||
return(res);
|
return(res);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user