1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

cleaning up XPath error reporting that time. applied the two patches for

* error.c include/libxml/xmlerror.h include/libxml/xpath.h
  include/libxml/xpathInternals.h xpath.c: cleaning up XPath
  error reporting that time.
* threads.c: applied the two patches for TLS threads
  on Windows from Jesse Pelton
* parser.c: tiny safety patch for xmlStrPrintf() make sure the
  return is always zero terminated. Should also help detecting
  passing wrong buffer size easilly.
* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
  updated the results to follow the errors string generated by
  last commit.
Daniel
This commit is contained in:
Daniel Veillard
2003-10-07 21:25:12 +00:00
parent 6edbfbbe66
commit d96f6d3429
25 changed files with 375 additions and 203 deletions

View File

@ -1,3 +1,17 @@
Tue Oct 7 23:19:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
* error.c include/libxml/xmlerror.h include/libxml/xpath.h
include/libxml/xpathInternals.h xpath.c: cleaning up XPath
error reporting that time.
* threads.c: applied the two patches for TLS threads
on Windows from Jesse Pelton
* parser.c: tiny safety patch for xmlStrPrintf() make sure the
return is always zero terminated. Should also help detecting
passing wrong buffer size easilly.
* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
updated the results to follow the errors string generated by
last commit.
Tue Oct 7 14:16:45 CEST 2003 Daniel Veillard <daniel@veillard.com>
* relaxng.c include/libxml/xmlerror.h: last cleanup of error

19
error.c
View File

@ -262,13 +262,13 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
if (input != NULL) {
if (input->filename)
channel(data, "%s:%d: ", input->filename, input->line);
else
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: ", input->line);
}
} else {
if (file != NULL)
channel(data, "%s:%d: ", file, line);
else
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: ", line);
}
if (name != NULL) {
@ -362,11 +362,24 @@ xmlReportError(xmlErrorPtr err, xmlParserCtxtPtr ctxt, const char *str,
if (cur != NULL) {
if (cur->filename)
channel(data, "%s:%d: \n", cur->filename, cur->line);
else
else if ((line != 0) && (domain == XML_FROM_PARSER))
channel(data, "Entity: line %d: \n", cur->line);
xmlParserPrintFileContextInternal(cur, channel, data);
}
}
if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
(err->int1 < 100) &&
(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
xmlChar buf[150];
int i;
channel(data, "%s\n", err->str1);
for (i=0;i < err->int1;i++)
buf[i] = ' ';
buf[i++] = '^';
buf[i] = 0;
channel(data, "%s\n", buf);
}
}
/**

View File

@ -375,7 +375,29 @@ typedef enum {
XML_RNGP_VALUE_EMPTY,
XML_RNGP_VALUE_NO_CONTENT,
XML_RNGP_XMLNS_NAME,
XML_RNGP_XML_NS
XML_RNGP_XML_NS,
XML_XPATH_EXPRESSION_OK = 1200,
XML_XPATH_NUMBER_ERROR,
XML_XPATH_UNFINISHED_LITERAL_ERROR,
XML_XPATH_START_LITERAL_ERROR,
XML_XPATH_VARIABLE_REF_ERROR,
XML_XPATH_UNDEF_VARIABLE_ERROR,
XML_XPATH_INVALID_PREDICATE_ERROR,
XML_XPATH_EXPR_ERROR,
XML_XPATH_UNCLOSED_ERROR,
XML_XPATH_UNKNOWN_FUNC_ERROR,
XML_XPATH_INVALID_OPERAND,
XML_XPATH_INVALID_TYPE,
XML_XPATH_INVALID_ARITY,
XML_XPATH_INVALID_CTXT_SIZE,
XML_XPATH_INVALID_CTXT_POSITION,
XML_XPATH_MEMORY_ERROR,
XML_XPTR_SYNTAX_ERROR,
XML_XPTR_RESOURCE_ERROR,
XML_XPTR_SUB_RESOURCE_ERROR,
XML_XPATH_UNDEF_PREFIX_ERROR,
XML_XPATH_ENCODING_ERROR,
XML_XPATH_INVALID_CHAR_ERROR
} xmlParserErrors;
/**
@ -389,7 +411,16 @@ typedef enum {
*/
typedef void (*xmlGenericErrorFunc) (void *ctx,
const char *msg,
...);
...);
/**
* xmlStructuredErrorFunc:
* @userData: user provided data for the error callback
* @error: the error being raised.
*
* Signature of the function to use when there is an error and
* the module handles the new error reporting mechanism.
*/
typedef void (*xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
/*
* Use the following function to reset the two global variables

View File

@ -13,6 +13,7 @@
#define __XML_XPATH_H__
#include <libxml/xmlversion.h>
#include <libxml/xmlerror.h>
#include <libxml/tree.h>
#include <libxml/hash.h>
@ -253,6 +254,12 @@ struct _xmlXPathContext {
/* temporary namespace lists kept for walking the namespace axis */
xmlNsPtr *tmpNsList; /* Array of namespaces */
int tmpNsNr; /* number of namespace in scope */
/* error reporting mechanism */
void *userData; /* user specific data block */
xmlStructuredErrorFunc error; /* the callback in case of errors */
xmlError lastError; /* the last error */
xmlNodePtr debugNode; /* the source node XSLT */
};
/*

View File

@ -250,8 +250,7 @@ XMLPUBFUN void * XMLCALL
* Macro to raise an XPath error and return.
*/
#define XP_ERROR(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return; }
{ xmlXPathErr(ctxt, X); return; }
/**
* XP_ERROR0:
@ -260,8 +259,7 @@ XMLPUBFUN void * XMLCALL
* Macro to raise an XPath error and return 0.
*/
#define XP_ERROR0(X) \
{ xmlXPatherror(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return(0); }
{ xmlXPathErr(ctxt, X); return(0); }
/**
* CHECK_TYPE:
@ -377,6 +375,10 @@ XMLPUBFUN void XMLCALL
int line,
int no);
XMLPUBFUN void XMLCALL
xmlXPathErr (xmlXPathParserContextPtr ctxt,
int error);
#ifdef LIBXML_DEBUG_ENABLED
XMLPUBFUN void XMLCALL
xmlXPathDebugDumpObject (FILE *output,

View File

@ -2449,6 +2449,7 @@ xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
va_start(args, msg);
ret = vsnprintf((char *) buf, len, (const char *) msg, args);
va_end(args);
buf[len - 1] = 0; /* be safe ! */
return(ret);
}

View File

@ -7,6 +7,6 @@
./test/VC/AttributeDefaultLegal:8: validity error : Attribute doc of bad2: invalid default value
<!ATTLIST doc bad2 IDREFS "abc:1 1abc_2">
^
./test/VC/AttributeDefaultLegal:11: validity error : No declaration for attribute val of element doc
./test/VC/AttributeDefaultLegal:11: element doc: validity error : No declaration for attribute val of element doc
<doc val="v1"/>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid2:4: validity error : No declaration for element p
./test/VC/ElementValid2:4: element p: validity error : No declaration for element p
<doc><p/></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid3:4: validity error : Element doc was declared EMPTY this one has content
./test/VC/ElementValid3:4: element doc: validity error : Element doc was declared EMPTY this one has content
<doc>Oops, this element was declared EMPTY</doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid4:7: validity error : Element c is not declared in doc list of possible children
./test/VC/ElementValid4:7: element doc: validity error : Element c is not declared in doc list of possible children
<doc> This <b>seems</b> Ok <a/> but this <c>was not declared</c></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid5:7: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
./test/VC/ElementValid5:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b* , c+), got (a b c b)
<doc><a/><b> but this</b><c>was not declared</c><b>seems</b></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid6:7: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
./test/VC/ElementValid6:7: element doc: validity error : Element doc content does not follow the DTD, expecting (a , b? , c+)?, got (a b)
<doc><a/><b>lacks c</b></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/ElementValid7:7: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
./test/VC/ElementValid7:7: element doc: validity error : Element doc content does not follow the DTD, expecting ((a | b)* , c+ , a , b? , c , a?), got (a b a c c a)
<doc><a/><b/><a/><c/><c/><a/></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/Enumeration:5: validity error : Value "v4" for attribute val of doc is not among the enumerated set
./test/VC/Enumeration:5: element doc: validity error : Value "v4" for attribute val of doc is not among the enumerated set
<doc val="v4"></doc>
^

View File

@ -1,3 +1,3 @@
./test/VC/NS2:9: validity error : No declaration for attribute attr of element doc
./test/VC/NS2:9: element doc: validity error : No declaration for attribute attr of element doc
<ns:doc ns:attr="val" xmlns:ns="http://www.example.org/test/">
^

View File

@ -1,9 +1,9 @@
./test/VC/NS3:9: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo is different from default "http://example.com/fooo"
xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
^
./test/VC/NS3:9: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
./test/VC/NS3:9: element foo: validity error : Value for attribute xmlns of foo must be "http://example.com/fooo"
xmlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"
^
./test/VC/NS3:9: validity error : Element foo namespace name for default namespace does not match the DTD
./test/VC/NS3:9: element foo: validity error : Element foo namespace name for default namespace does not match the DTD
mlns="http://example.com/foo" xmlns:foo="http://example.com/fo" foo:info="toto"/
^

View File

@ -1,7 +1,7 @@
./test/VC/OneID:4: validity error : Element doc has too may ID attributes defined : id
<!ATTLIST doc id ID #IMPLIED>
^
Element doc has too many ID attributes defined : id
./test/VC/OneID:0: validity error : Element doc has too many ID attributes defined : id
./test/VC/OneID:4: validity error : Element doc has 2 ID attribute defined in the internal subset : id
<!ATTLIST doc id ID #IMPLIED>
^

View File

@ -1,7 +1,7 @@
./test/VC/OneID2:3: validity error : Element doc has too may ID attributes defined : id
<!ATTLIST doc id ID #IMPLIED>
^
Element doc has too many ID attributes defined : id
Entity: line 0: validity error : Element doc has too many ID attributes defined : id
./test/VC/OneID2:3: validity error : Element doc has 2 ID attribute defined in the internal subset : id
<!ATTLIST doc id ID #IMPLIED>
^

View File

@ -1,7 +1,7 @@
test/VC/dtds/doc.dtd:2: validity error : Element doc has too may ID attributes defined : val
<!ATTLIST doc val ID #IMPLIED>
^
Element doc has too many ID attributes defined : val
./test/VC/OneID3:0: validity error : Element doc has too many ID attributes defined : val
test/VC/dtds/doc.dtd:2: validity error : Element doc has 2 ID attribute defined in the external subset : val
<!ATTLIST doc val ID #IMPLIED>
^

BIN
result/noent/slashdot16.xml Normal file

Binary file not shown.

BIN
result/slashdot16.xml Normal file

Binary file not shown.

View File

@ -1,3 +1,3 @@
./test/valid/rss.xml:177: validity error : Element rss does not carry attribute version
./test/valid/rss.xml:177: element rss: validity error : Element rss does not carry attribute version
</rss>
^

View File

@ -1,6 +1,6 @@
./test/valid/xlink.xml:450: validity error : ID dt-arc already defined
./test/valid/xlink.xml:450: element termdef: validity error : ID dt-arc already defined
<p><termdef id="dt-arc" term="Arc">An <term>arc</term> is contained within an e
^
./test/valid/xlink.xml:530: validity error : IDREF attribute def references an unknown ID "dt-xlg"
./test/valid/xlink.xml:530: element termref: validity error : IDREF attribute def references an unknown ID "dt-xlg"
^

101
threads.c
View File

@ -336,7 +336,8 @@ xmlNewGlobalState(void)
#ifdef HAVE_WIN32_THREADS
#if !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC)
#if !defined(HAVE_COMPILER_TLS)
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
typedef struct _xmlGlobalStateCleanupHelperParams
{
HANDLE thread;
@ -352,7 +353,20 @@ static void xmlGlobalStateCleanupHelper (void *p)
free(params);
_endthread();
}
#endif /* HAVE_COMPILER_TLS && LIBXML_STATIC */
#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
typedef struct _xmlGlobalStateCleanupHelperParams
{
void *memory;
struct _xmlGlobalStateCleanupHelperParams * prev;
struct _xmlGlobalStateCleanupHelperParams * next;
} xmlGlobalStateCleanupHelperParams;
static xmlGlobalStateCleanupHelperParams * cleanup_helpers_head = NULL;
static CRITICAL_SECTION cleanup_helpers_cs;
#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
#endif /* HAVE_COMPILER_TLS */
#endif /* HAVE_WIN32_THREADS */
/**
@ -387,23 +401,37 @@ xmlGetGlobalState(void)
return &tlstate;
#else /* HAVE_COMPILER_TLS */
xmlGlobalState *globalval;
xmlGlobalStateCleanupHelperParams * p;
if (run_once_init) {
run_once_init = 0;
xmlOnceInit();
}
if ((globalval = (xmlGlobalState *) TlsGetValue(globalkey)) == NULL) {
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
globalval = (xmlGlobalState *)TlsGetValue(globalkey);
#else
p = (xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
globalval = (xmlGlobalState *)(p ? p->memory : NULL);
#endif
if (globalval == NULL) {
xmlGlobalState *tsd = xmlNewGlobalState();
#if defined(LIBXML_STATIC)
xmlGlobalStateCleanupHelperParams *p =
(xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
p = (xmlGlobalStateCleanupHelperParams *) malloc(sizeof(xmlGlobalStateCleanupHelperParams));
p->memory = tsd;
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &p->thread, 0, TRUE, DUPLICATE_SAME_ACCESS);
#endif
TlsSetValue(globalkey, tsd);
#if defined(LIBXML_STATIC)
_beginthread(xmlGlobalStateCleanupHelper, 0, p);
#else
EnterCriticalSection(&cleanup_helpers_cs);
if (cleanup_helpers_head != NULL) {
cleanup_helpers_head->prev = p;
}
p->next = cleanup_helpers_head;
p->prev = NULL;
cleanup_helpers_head = p;
TlsSetValue(globalkey, p);
LeaveCriticalSection(&cleanup_helpers_cs);
#endif
return (tsd);
@ -513,6 +541,9 @@ xmlInitThreads(void)
#ifdef DEBUG_THREADS
xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
#endif
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
InitializeCriticalSection(&cleanup_helpers_cs);
#endif
}
/**
@ -527,6 +558,24 @@ xmlCleanupThreads(void)
#ifdef DEBUG_THREADS
xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
#endif
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS)
if (globalkey != TLS_OUT_OF_INDEXES) {
xmlGlobalStateCleanupHelperParams * p;
EnterCriticalSection(&cleanup_helpers_cs);
p = cleanup_helpers_head;
while (p != NULL) {
xmlGlobalStateCleanupHelperParams * temp = p;
p = p->next;
xmlFreeGlobalState(temp->memory);
free(temp);
}
cleanup_helpers_head = 0;
LeaveCriticalSection(&cleanup_helpers_cs);
TlsFree(globalkey);
globalkey = TLS_OUT_OF_INDEXES;
}
DeleteCriticalSection(&cleanup_helpers_cs);
#endif
}
#ifdef LIBXML_THREAD_ENABLED
@ -566,27 +615,39 @@ xmlOnceInit(void) {
*
* Returns TRUE always
*/
#if defined(HAVE_WIN32_THREADS) && !defined(LIBXML_STATIC)
#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
#if defined(LIBXML_STATIC_FOR_DLL)
BOOL WINAPI xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#else
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
switch(fdwReason) {
case DLL_THREAD_DETACH:
if (globalkey != TLS_OUT_OF_INDEXES) {
xmlGlobalState *globalval = (xmlGlobalState *)TlsGetValue(globalkey);
if (globalval) {
xmlFreeGlobalState(globalval);
TlsSetValue(globalkey, NULL);
xmlGlobalState *globalval = NULL;
xmlGlobalStateCleanupHelperParams * p =
(xmlGlobalStateCleanupHelperParams*)TlsGetValue(globalkey);
globalval = (xmlGlobalState *)(p ? p->memory : NULL);
if (globalval) {
xmlFreeGlobalState(globalval);
TlsSetValue(globalkey,NULL);
}
if (p)
{
EnterCriticalSection(&cleanup_helpers_cs);
if (p == cleanup_helpers_head)
cleanup_helpers_head = p->next;
else
p->prev->next = p->next;
if (p->next != NULL)
p->next->prev = p->prev;
LeaveCriticalSection(&cleanup_helpers_cs);
free(p);
}
}
break;
case DLL_PROCESS_DETACH:
if (globalkey != TLS_OUT_OF_INDEXES) {
TlsFree(globalkey);
globalkey = TLS_OUT_OF_INDEXES;
}
break;
}
return TRUE;
}
#endif

355
xpath.c
View File

@ -52,6 +52,11 @@
#include <libxml/threads.h>
#include <libxml/globals.h>
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
#if defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XPATH_ENABLED)
/************************************************************************
* *
@ -164,6 +169,161 @@ static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
static int xmlXPathDisableOptimizer = 0;
#endif
/************************************************************************
* *
* Error handling routines *
* *
************************************************************************/
static const char *xmlXPathErrorMessages[] = {
"Ok\n",
"Number encoding\n",
"Unfinished literal\n",
"Start of literal\n",
"Expected $ for variable reference\n",
"Undefined variable\n",
"Invalid predicate\n",
"Invalid expression\n",
"Missing closing curly brace\n",
"Unregistered function\n",
"Invalid operand\n",
"Invalid type\n",
"Invalid number of arguments\n",
"Invalid context size\n",
"Invalid context position\n",
"Memory allocation error\n",
"Syntax error\n",
"Resource error\n",
"Sub resource error\n",
"Undefined namespace prefix\n",
"Encoding error\n",
"Char out of XML range\n"
};
/**
* xmlXPathErrMemory:
* @ctxt: an XPath context
* @extra: extra informations
*
* Handle a redefinition of attribute error
*/
static void
xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
{
if (ctxt != NULL) {
if (extra) {
xmlChar buf[200];
xmlStrPrintf(buf, 200,
BAD_CAST "Memory allocation failed : %s\n",
extra);
ctxt->lastError.message = (char *) xmlStrdup(buf);
} else {
ctxt->lastError.message = (char *)
xmlStrdup(BAD_CAST "Memory allocation failed\n");
}
ctxt->lastError.domain = XML_FROM_XPATH;
ctxt->lastError.code = XML_ERR_NO_MEMORY;
if (ctxt->error != NULL)
ctxt->error(ctxt->userData, &ctxt->lastError);
} else {
if (extra)
__xmlRaiseError(NULL, NULL,
NULL, NULL, XML_FROM_XPATH,
XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
extra, NULL, NULL, 0, 0,
"Memory allocation failed : %s\n", extra);
else
__xmlRaiseError(NULL, NULL,
NULL, NULL, XML_FROM_XPATH,
XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0,
NULL, NULL, NULL, 0, 0,
"Memory allocation failed\n");
}
}
/**
* xmlXPathErrMemory:
* @ctxt: an XPath parser context
* @extra: extra informations
*
* Handle a redefinition of attribute error
*/
static void
xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra)
{
ctxt->error = XPATH_MEMORY_ERROR;
if (ctxt == NULL)
xmlXPathErrMemory(NULL, extra);
else
xmlXPathErrMemory(ctxt->context, extra);
}
/**
* xmlXPathErr:
* @ctxt: a XPath parser context
* @node: the node raising the error
* @error: the error code
* @msg: message
* @str1: extra info
* @str2: extra info
*
* Handle a Relax NG Parsing error
*/
void
xmlXPathErr(xmlXPathParserContextPtr ctxt, int error)
{
if (ctxt != NULL)
ctxt->error = error;
if ((ctxt == NULL) || (ctxt->context == NULL)) {
__xmlRaiseError(NULL, NULL,
NULL, NULL, XML_FROM_XPATH,
error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
XML_ERR_ERROR, NULL, 0,
NULL, NULL, NULL, 0, 0,
xmlXPathErrorMessages[error]);
return;
}
ctxt->context->lastError.domain = XML_FROM_XPATH;
ctxt->context->lastError.code = error + XML_XPATH_EXPRESSION_OK -
XPATH_EXPRESSION_OK;
ctxt->context->lastError.level = XML_ERR_FATAL;
ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
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, ctxt->context->debugNode, XML_FROM_XPATH,
error + XML_XPATH_EXPRESSION_OK - XPATH_EXPRESSION_OK,
XML_ERR_ERROR, NULL, 0,
(const char *) ctxt->base, NULL, NULL,
ctxt->cur - ctxt->base, 0,
xmlXPathErrorMessages[error]);
}
}
/**
* xmlXPatherror:
* @ctxt: the XPath Parser context
* @file: the file name
* @line: the line number
* @no: the error number
*
* Formats an error message.
*/
void
xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED, int no) {
xmlXPathErr(ctxt, no);
}
/************************************************************************
* *
* Parser Types *
@ -278,8 +438,7 @@ xmlXPathNewCompExpr(void) {
cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
if (cur == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewCompExpr : malloc failed\n");
xmlXPathErrMemory(NULL, "allocating component\n");
return(NULL);
}
memset(cur, 0, sizeof(xmlXPathCompExpr));
@ -288,8 +447,7 @@ xmlXPathNewCompExpr(void) {
cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
sizeof(xmlXPathStepOp));
if (cur->steps == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewCompExpr : malloc failed\n");
xmlXPathErrMemory(NULL, "allocating steps\n");
xmlFree(cur);
return(NULL);
}
@ -369,8 +527,7 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
comp->maxStep * sizeof(xmlXPathStepOp));
if (real == NULL) {
comp->maxStep /= 2;
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompExprAdd : realloc failed\n");
xmlXPathErrMemory(NULL, "adding step\n");
return(-1);
}
comp->steps = real;
@ -436,11 +593,6 @@ xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL
* *
************************************************************************/
#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
#define STRANGE \
xmlGenericError(xmlGenericErrorContext, \
"Internal error at %s:%d\n", \
@ -1247,96 +1399,6 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize)
}
}
/************************************************************************
* *
* Error handling routines *
* *
************************************************************************/
static const char *xmlXPathErrorMessages[] = {
"Ok",
"Number encoding",
"Unfinished literal",
"Start of literal",
"Expected $ for variable reference",
"Undefined variable",
"Invalid predicate",
"Invalid expression",
"Missing closing curly brace",
"Unregistered function",
"Invalid operand",
"Invalid type",
"Invalid number of arguments",
"Invalid context size",
"Invalid context position",
"Memory allocation error",
"Syntax error",
"Resource error",
"Sub resource error",
"Undefined namespace prefix",
"Encoding error",
"Char out of XML range"
};
/**
* xmlXPatherror:
* @ctxt: the XPath Parser context
* @file: the file name
* @line: the line number
* @no: the error number
*
* Formats an error message.
*/
void
xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file ATTRIBUTE_UNUSED,
int line ATTRIBUTE_UNUSED, int no) {
int n;
const xmlChar *cur;
const xmlChar *base;
cur = ctxt->cur;
base = ctxt->base;
if ((cur == NULL) || (base == NULL)) {
if ((ctxt->comp != NULL) && (ctxt->comp->expr != NULL)) {
xmlGenericError(xmlGenericErrorContext,
"XPath error %s in %s\n", xmlXPathErrorMessages[no],
ctxt->comp->expr);
} else {
xmlGenericError(xmlGenericErrorContext,
"XPath error %s\n", xmlXPathErrorMessages[no]);
}
return;
}
xmlGenericError(xmlGenericErrorContext,
"XPath error %s\n", xmlXPathErrorMessages[no]);
while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
cur--;
}
n = 0;
while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
cur--;
if ((*cur == '\n') || (*cur == '\r')) cur++;
base = cur;
n = 0;
while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
n++;
}
xmlGenericError(xmlGenericErrorContext, "\n");
cur = ctxt->cur;
while ((*cur == '\n') || (*cur == '\r'))
cur--;
n = 0;
while ((cur != base) && (n++ < 80)) {
xmlGenericError(xmlGenericErrorContext, " ");
base++;
}
xmlGenericError(xmlGenericErrorContext,"^\n");
}
/************************************************************************
* *
@ -1564,8 +1626,7 @@ xmlXPathNodeSetDupNs(xmlNodePtr node, xmlNsPtr ns) {
*/
cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (cur == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetDupNs : malloc failed\n");
xmlXPathErrMemory(NULL, "duplicating namespace\n");
return(NULL);
}
memset(cur, 0, sizeof(xmlNs));
@ -1614,8 +1675,7 @@ xmlXPathNodeSetCreate(xmlNodePtr val) {
ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetCreate: out of memory\n");
xmlXPathErrMemory(NULL, "creating nodeset\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
@ -1623,8 +1683,8 @@ xmlXPathNodeSetCreate(xmlNodePtr val) {
ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (ret->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetCreate: out of memory\n");
xmlXPathErrMemory(NULL, "creating nodeset\n");
xmlFree(ret);
return(NULL);
}
memset(ret->nodeTab, 0 ,
@ -1712,8 +1772,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAdd: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
memset(cur->nodeTab, 0 ,
@ -1726,8 +1785,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAdd: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
cur->nodeTab = temp;
@ -1767,8 +1825,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAdd: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
memset(cur->nodeTab, 0 ,
@ -1781,8 +1838,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAdd: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
cur->nodeTab = temp;
@ -1821,8 +1877,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (cur->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAddUnique: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
memset(cur->nodeTab, 0 ,
@ -1835,8 +1890,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetAddUnique: out of memory\n");
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
cur->nodeTab = temp;
@ -1903,8 +1957,7 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (val1->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetMerge: out of memory\n");
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
memset(val1->nodeTab, 0 ,
@ -1917,8 +1970,7 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetMerge: out of memory\n");
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
val1->nodeTab = temp;
@ -1964,8 +2016,7 @@ xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
sizeof(xmlNodePtr));
if (val1->nodeTab == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetMerge: out of memory\n");
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
memset(val1->nodeTab, 0 ,
@ -1978,8 +2029,7 @@ xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNodeSetMerge: out of memory\n");
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
val1->nodeTab = temp;
@ -2159,8 +2209,7 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewNodeSet: out of memory\n");
xmlXPathErrMemory(NULL, "creating nodeset\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -2186,8 +2235,7 @@ xmlXPathNewValueTree(xmlNodePtr val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewNodeSet: out of memory\n");
xmlXPathErrMemory(NULL, "creating result value tree\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -2240,8 +2288,7 @@ xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathWrapNodeSet: out of memory\n");
xmlXPathErrMemory(NULL, "creating node set object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3007,8 +3054,7 @@ xmlXPathNewFloat(double val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewFloat: out of memory\n");
xmlXPathErrMemory(NULL, "creating float object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3031,8 +3077,7 @@ xmlXPathNewBoolean(int val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewBoolean: out of memory\n");
xmlXPathErrMemory(NULL, "creating boolean object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3055,8 +3100,7 @@ xmlXPathNewString(const xmlChar *val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewString: out of memory\n");
xmlXPathErrMemory(NULL, "creating string object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3082,8 +3126,7 @@ xmlXPathWrapString (xmlChar *val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathWrapString: out of memory\n");
xmlXPathErrMemory(NULL, "creating string object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3106,8 +3149,7 @@ xmlXPathNewCString(const char *val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewCString: out of memory\n");
xmlXPathErrMemory(NULL, "creating string object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3143,8 +3185,7 @@ xmlXPathWrapExternal (void *val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathWrapExternal: out of memory\n");
xmlXPathErrMemory(NULL, "creating user object\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
@ -3170,8 +3211,7 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) {
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathObjectCopy: out of memory\n");
xmlXPathErrMemory(NULL, "copying object\n");
return(NULL);
}
memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
@ -3722,8 +3762,7 @@ xmlXPathNewContext(xmlDocPtr doc) {
ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewContext: out of memory\n");
xmlXPathErrMemory(NULL, "creating context\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
@ -3814,8 +3853,7 @@ xmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathNewParserContext: out of memory\n");
xmlXPathErrMemory(ctxt, "creating parser context\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
@ -3847,8 +3885,7 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompParserContext: out of memory\n");
xmlXPathErrMemory(ctxt, "creating evaluation context\n");
return(NULL);
}
memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
@ -3858,8 +3895,7 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
if (ret->valueTab == NULL) {
xmlFree(ret);
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompParserContext: out of memory\n");
xmlXPathErrMemory(ctxt, "creating evaluation context\n");
return(NULL);
}
ret->valueNr = 0;
@ -4210,6 +4246,7 @@ xmlXPathCompareNodeSets(int inf, int strict,
values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
if (values2 == NULL) {
xmlXPathErrMemory(NULL, "comparing nodesets\n");
xmlXPathFreeObject(arg1);
xmlXPathFreeObject(arg2);
return(0);
@ -4460,22 +4497,27 @@ xmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2, int neq) {
return(1);
values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
if (values1 == NULL)
if (values1 == NULL) {
xmlXPathErrMemory(NULL, "comparing nodesets\n");
return(0);
}
hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
if (hashs1 == NULL) {
xmlXPathErrMemory(NULL, "comparing nodesets\n");
xmlFree(values1);
return(0);
}
memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
if (values2 == NULL) {
xmlXPathErrMemory(NULL, "comparing nodesets\n");
xmlFree(hashs1);
xmlFree(values1);
return(0);
}
hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
if (hashs2 == NULL) {
xmlXPathErrMemory(NULL, "comparing nodesets\n");
xmlFree(hashs1);
xmlFree(values1);
xmlFree(values2);
@ -10608,6 +10650,7 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt) {
ctxt->valueTab = (xmlXPathObjectPtr *)
xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
if (ctxt->valueTab == NULL) {
xmlXPathPErrMemory(ctxt, "creating evaluation context\n");
xmlFree(ctxt);
}
ctxt->valueNr = 0;