1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-31 06:50:06 +03:00

parser: Implement xmlCtxtGetStatus

This allows access to ctxt->wellFormed, ctxt->nsWellFormed and
ctxt->valid. It also detects several fatal non-parser errors which
really should be another error level.
This commit is contained in:
Nick Wellnhofer 2024-06-26 19:28:28 +02:00
parent f505dcaea0
commit 193f4653a5
3 changed files with 76 additions and 2 deletions

2
buf.c
View File

@ -106,7 +106,7 @@ static void
xmlBufOverflowError(xmlBufPtr buf)
{
if (buf->error == 0)
buf->error = XML_BUF_OVERFLOW;
buf->error = XML_ERR_RESOURCE_LIMIT;
}

View File

@ -40,6 +40,11 @@ extern "C" {
*/
#define XML_DEFAULT_VERSION "1.0"
#define XML_STATUS_NOT_WELL_FORMED (1 << 0)
#define XML_STATUS_NOT_NS_WELL_FORMED (1 << 1)
#define XML_STATUS_DTD_VALIDATION_FAILED (1 << 2)
#define XML_STATUS_CATASTROPHIC_ERROR (1 << 3)
typedef enum {
XML_RESOURCE_UNKNOWN = 0,
XML_RESOURCE_MAIN_DOCUMENT,
@ -1423,6 +1428,8 @@ XMLPUBFUN const xmlChar *
xmlCtxtGetDeclaredEncoding(xmlParserCtxtPtr ctxt);
XMLPUBFUN int
xmlCtxtGetStandalone (xmlParserCtxtPtr ctxt);
XMLPUBFUN int
xmlCtxtGetStatus (xmlParserCtxtPtr ctxt);
XMLPUBFUN void
xmlCtxtSetErrorHandler (xmlParserCtxtPtr ctxt,
xmlStructuredErrorFunc handler,

View File

@ -253,6 +253,36 @@ xmlCtxtErrIO(xmlParserCtxtPtr ctxt, int code, const char *uri)
msg, str1, str2);
}
static int
xmlCtxtIsCatastrophicError(xmlParserCtxtPtr ctxt) {
int fatal = 0;
int code;
if (ctxt == NULL)
return(1);
if (ctxt->lastError.level != XML_ERR_FATAL)
return(0);
code = ctxt->lastError.code;
switch (code) {
case XML_ERR_NO_MEMORY:
case XML_ERR_RESOURCE_LIMIT:
case XML_ERR_SYSTEM:
case XML_ERR_ARGUMENT:
case XML_ERR_INTERNAL_ERROR:
fatal = 1;
break;
default:
if ((code >= 1500) && (code <= 1599))
fatal = 1;
break;
}
return(fatal);
}
/**
* xmlCtxtVErr:
* @ctxt: a parser context
@ -352,7 +382,10 @@ xmlCtxtVErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
ctxt->errNo = code;
if (level == XML_ERR_FATAL) {
ctxt->wellFormed = 0;
if (ctxt->recovery == 0)
if (xmlCtxtIsCatastrophicError(ctxt))
ctxt->disableSAX = 2; /* stop parser */
else if (ctxt->recovery == 0)
ctxt->disableSAX = 1;
}
}
@ -387,6 +420,40 @@ xmlCtxtErr(xmlParserCtxtPtr ctxt, xmlNodePtr node, xmlErrorDomain domain,
va_end(ap);
}
/**
* xmlCtxtGetStatus:
* @ctxt: an XML parser context
*
* Get well-formedness and validation status after parsing. Also
* reports catastrophic errors which are not related to parsing
* like out-of-memory, I/O or other errors.
*
* Returns a bitmask of XML_STATUS_* flags ORed together.
*/
int
xmlCtxtGetStatus(xmlParserCtxt *ctxt) {
int bits = 0;
if (xmlCtxtIsCatastrophicError(ctxt)) {
bits |= XML_STATUS_CATASTROPHIC_ERROR |
XML_STATUS_NOT_WELL_FORMED |
XML_STATUS_NOT_NS_WELL_FORMED;
if ((ctxt != NULL) && (ctxt->validate))
bits |= XML_STATUS_DTD_VALIDATION_FAILED;
return(bits);
}
if (!ctxt->wellFormed)
bits |= XML_STATUS_NOT_WELL_FORMED;
if (!ctxt->nsWellFormed)
bits |= XML_STATUS_NOT_NS_WELL_FORMED;
if ((ctxt->validate) && (!ctxt->valid))
bits |= XML_STATUS_DTD_VALIDATION_FAILED;
return(bits);
}
/**
* xmlFatalErr:
* @ctxt: an XML parser context