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:
@ -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,
|
||||||
|
@ -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__ */
|
||||||
|
113
xpointer.c
113
xpointer.c
@ -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) {
|
||||||
|
Reference in New Issue
Block a user