1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-09-02 17:49:22 +03:00

xpath: Improve error handling

Introduce xmlXPathSetErrorHandler allowing to set a structured error
handler for an XPath context.

Remove arguments from memory error handlers.

Use xmlRaiseMemoryError.

Remove TODO, STRANGE and CHECK_CTXT macros.

Remove remaining uses of xmlGenericError.
This commit is contained in:
Nick Wellnhofer
2023-12-18 19:39:38 +01:00
parent 54c70ed57f
commit 954b898494
4 changed files with 248 additions and 358 deletions

View File

@ -515,6 +515,10 @@ XMLPUBFUN xmlXPathContextPtr
xmlXPathNewContext (xmlDocPtr doc); xmlXPathNewContext (xmlDocPtr doc);
XMLPUBFUN void XMLPUBFUN void
xmlXPathFreeContext (xmlXPathContextPtr ctxt); xmlXPathFreeContext (xmlXPathContextPtr ctxt);
XMLPUBFUN void
xmlXPathSetErrorHandler(xmlXPathContextPtr ctxt,
xmlStructuredErrorFunc handler,
void *context);
XMLPUBFUN int XMLPUBFUN int
xmlXPathContextSetCache(xmlXPathContextPtr ctxt, xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
int active, int active,

View File

@ -8,9 +8,9 @@ xmlInitXPathInternal(void);
#ifdef LIBXML_XPATH_ENABLED #ifdef LIBXML_XPATH_ENABLED
XML_HIDDEN void XML_HIDDEN void
xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra); xmlXPathErrMemory(xmlXPathContextPtr ctxt);
XML_HIDDEN void XML_HIDDEN void
xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra); xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt);
#endif #endif
#endif /* XML_XPATH_H_PRIVATE__ */ #endif /* XML_XPATH_H_PRIVATE__ */

445
xpath.c

File diff suppressed because it is too large Load Diff

View File

@ -47,16 +47,6 @@
#include "private/error.h" #include "private/error.h"
#include "private/xpath.h" #include "private/xpath.h"
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
#define STRANGE \
xmlGenericError(xmlGenericErrorContext, \
"Internal error at %s:%d\n", \
__FILE__, __LINE__);
/************************************************************************ /************************************************************************
* * * *
* Some factorized error routines * * Some factorized error routines *
@ -71,50 +61,51 @@
* Handle an XPointer 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 code,
const char * msg, const xmlChar *extra) const char * msg, const xmlChar *extra)
{ {
if (ctxt->context->lastError.code == XML_ERR_NO_MEMORY) xmlStructuredErrorFunc serror = NULL;
return; void *data = NULL;
if (ctxt != NULL) xmlNodePtr node = NULL;
ctxt->error = error;
if ((ctxt == NULL) || (ctxt->context == NULL)) {
__xmlRaiseError(NULL, NULL, NULL,
NULL, NULL, XML_FROM_XPOINTER, error,
XML_ERR_ERROR, NULL, 0,
(const char *) extra, NULL, NULL, 0, 0,
msg, extra);
return;
}
/* cleanup current last error */
xmlResetError(&ctxt->context->lastError);
ctxt->context->lastError.domain = XML_FROM_XPOINTER;
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 {
int res; int res;
res = __xmlRaiseError(NULL, NULL, NULL, if (ctxt == NULL)
NULL, ctxt->context->debugNode, XML_FROM_XPOINTER, return;
error, XML_ERR_ERROR, NULL, 0, /* Only report the first error */
(const char *) extra, (const char *) ctxt->base, NULL, if (ctxt->error != 0)
ctxt->cur - ctxt->base, 0, return;
ctxt->error = code;
if (ctxt->context != NULL) {
xmlErrorPtr err = &ctxt->context->lastError;
/* cleanup current last error */
xmlResetError(err);
err->domain = XML_FROM_XPOINTER;
err->code = code;
err->level = XML_ERR_ERROR;
err->str1 = (char *) xmlStrdup(ctxt->base);
if (err->str1 == NULL) {
xmlXPathPErrMemory(ctxt);
return;
}
err->int1 = ctxt->cur - ctxt->base;
err->node = ctxt->context->debugNode;
serror = ctxt->context->error;
data = ctxt->context->userData;
node = ctxt->context->debugNode;
}
res = __xmlRaiseError(serror, NULL, data, NULL, node,
XML_FROM_XPOINTER, code, XML_ERR_ERROR, NULL, 0,
(const char *) extra, (const char *) ctxt->base,
NULL, ctxt->cur - ctxt->base, 0,
msg, extra); msg, extra);
if (res < 0) if (res < 0)
xmlXPathPErrMemory(ctxt, NULL); xmlXPathPErrMemory(ctxt);
}
} }
/************************************************************************ /************************************************************************
@ -211,12 +202,9 @@ xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
* Handle a redefinition of attribute error * Handle a redefinition of attribute error
*/ */
static void static void
xmlXPtrErrMemory(const char *extra) xmlXPtrErrMemory(const char *extra ATTRIBUTE_UNUSED)
{ {
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER, xmlRaiseMemoryError(NULL, NULL, NULL, XML_FROM_XPOINTER, NULL);
XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
NULL, NULL, 0, 0,
"Memory allocation failed : %s\n", extra);
} }
/** /**
@ -970,7 +958,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
len++; len++;
buffer = (xmlChar *) xmlMallocAtomic(len); buffer = (xmlChar *) xmlMallocAtomic(len);
if (buffer == NULL) { if (buffer == NULL) {
xmlXPathPErrMemory(ctxt, "allocating buffer"); xmlXPathPErrMemory(ctxt);
xmlFree(name); xmlFree(name);
return; return;
} }
@ -1241,7 +1229,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) {
xmlXPathPErrMemory(ctxt, "allocating evaluation context"); xmlXPathPErrMemory(ctxt);
return; return;
} }
ctxt->valueNr = 0; ctxt->valueNr = 0;
@ -1366,7 +1354,7 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
ctxt = xmlXPathNewParserContext(str, ctx); ctxt = xmlXPathNewParserContext(str, ctx);
if (ctxt == NULL) { if (ctxt == NULL) {
xmlXPathErrMemory(ctx, NULL); xmlXPathErrMemory(ctx);
return(NULL); return(NULL);
} }
xmlXPtrEvalXPointer(ctxt); xmlXPtrEvalXPointer(ctxt);
@ -1553,7 +1541,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
/* Do not copy DTD information */ /* Do not copy DTD information */
break; break;
case XML_ENTITY_DECL: case XML_ENTITY_DECL:
TODO /* handle crossing entities -> stack needed */ /* TODO: handle crossing entities -> stack needed */
break; break;
case XML_XINCLUDE_START: case XML_XINCLUDE_START:
case XML_XINCLUDE_END: case XML_XINCLUDE_END:
@ -1561,7 +1549,6 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
break; break;
case XML_ATTRIBUTE_NODE: case XML_ATTRIBUTE_NODE:
/* Humm, should not happen ! */ /* Humm, should not happen ! */
STRANGE
break; break;
default: default:
tmp = xmlCopyNode(cur, 1); tmp = xmlCopyNode(cur, 1);
@ -1569,7 +1556,6 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
} }
if (tmp != NULL) { if (tmp != NULL) {
if ((list == NULL) || ((last == NULL) && (parent == NULL))) { if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
STRANGE
return(NULL); return(NULL);
} }
if (last != NULL) if (last != NULL)
@ -1583,7 +1569,6 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
* Skip to next node in document order * Skip to next node in document order
*/ */
if ((list == NULL) || ((last == NULL) && (parent == NULL))) { if ((list == NULL) || ((last == NULL) && (parent == NULL))) {
STRANGE
return(NULL); return(NULL);
} }
cur = xmlXPtrAdvanceNode(cur, NULL); cur = xmlXPtrAdvanceNode(cur, NULL);
@ -2012,7 +1997,8 @@ xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
} }
} }
default: default:
TODO /* missed one case ??? */ /* TODO: missed one case ??? */
break;
} }
return(NULL); return(NULL);
} }
@ -2159,7 +2145,8 @@ xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
} }
} }
default: default:
TODO /* missed one case ??? */ /* TODO: missed one case ??? */
break;
} }
return(NULL); return(NULL);
} }
@ -2294,7 +2281,6 @@ found:
(cur->type != XML_HTML_DOCUMENT_NODE) && (cur->type != XML_HTML_DOCUMENT_NODE) &&
(cur->type != XML_CDATA_SECTION_NODE)) { (cur->type != XML_CDATA_SECTION_NODE)) {
if (cur->type == XML_ENTITY_REF_NODE) { /* Shouldn't happen */ if (cur->type == XML_ENTITY_REF_NODE) { /* Shouldn't happen */
TODO
goto skip; goto skip;
} }
goto next; goto next;
@ -2368,7 +2354,6 @@ xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
} }
if (pos > len) { if (pos > len) {
/* Strange, the indx in the text node is greater than it's len */ /* Strange, the indx in the text node is greater than it's len */
STRANGE
pos = len; pos = len;
} }
if (pos + bytes >= len) { if (pos + bytes >= len) {