From d7cb33cf44aa688f24215c9cd398c1a26f0d25ff Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Thu, 13 Jan 2022 17:06:14 +0100 Subject: [PATCH] Rework validation context flags Use a bitmask instead of magic values to - keep track whether the validation context is part of a parser context - keep track whether xmlValidateDtdFinal was called This allows to add addtional flags later. Note that this deliberately changes the name of a public struct member, assuming that this was always private data never to be used by client code. --- HTMLparser.c | 2 +- SAX2.c | 10 ++++++---- include/libxml/valid.h | 14 +++++++------- parserInternals.c | 2 +- valid.c | 43 +++++++++++++++--------------------------- 5 files changed, 30 insertions(+), 41 deletions(-) diff --git a/HTMLparser.c b/HTMLparser.c index 3e8a1657..eb3a820a 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -5118,7 +5118,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) ctxt->linenumbers = xmlLineNumbersDefaultValue; ctxt->keepBlanks = xmlKeepBlanksDefaultValue; ctxt->html = 1; - ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; + ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT; ctxt->vctxt.userData = ctxt; ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.warning = xmlParserValidityWarning; diff --git a/SAX2.c b/SAX2.c index 03192465..edfb06f3 100644 --- a/SAX2.c +++ b/SAX2.c @@ -1747,7 +1747,8 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) * If it's the Document root, finish the DTD validation and * check the document root element for validity */ - if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { + if ((ctxt->validate) && + ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) { int chk; chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); @@ -1756,7 +1757,7 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) if (chk < 0) ctxt->wellFormed = 0; ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); - ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; + ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED; } #endif /* LIBXML_VALID_ENABLED */ @@ -2405,7 +2406,8 @@ xmlSAX2StartElementNs(void *ctx, * If it's the Document root, finish the DTD validation and * check the document root element for validity */ - if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) { + if ((ctxt->validate) && + ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) { int chk; chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); @@ -2414,7 +2416,7 @@ xmlSAX2StartElementNs(void *ctx, if (chk < 0) ctxt->wellFormed = 0; ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); - ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1; + ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED; } #endif /* LIBXML_VALID_ENABLED */ } diff --git a/include/libxml/valid.h b/include/libxml/valid.h index 2bc7b380..15c9772c 100644 --- a/include/libxml/valid.h +++ b/include/libxml/valid.h @@ -60,17 +60,17 @@ typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx, #ifdef IN_LIBXML /** - * XML_CTXT_FINISH_DTD_0: + * XML_VCTXT_DTD_VALIDATED: * - * Special value for finishDtd field when embedded in an xmlParserCtxt + * Set after xmlValidateDtdFinal was called. */ -#define XML_CTXT_FINISH_DTD_0 0xabcd1234 +#define XML_VCTXT_DTD_VALIDATED (1u << 0) /** - * XML_CTXT_FINISH_DTD_1: + * XML_VCTXT_USE_PCTXT: * - * Special value for finishDtd field when embedded in an xmlParserCtxt + * Set if the validation context is part of a parser context. */ -#define XML_CTXT_FINISH_DTD_1 0xabcd1235 +#define XML_VCTXT_USE_PCTXT (1u << 1) #endif /* @@ -90,7 +90,7 @@ struct _xmlValidCtxt { int nodeMax; /* Max depth of the parsing stack */ xmlNodePtr *nodeTab; /* array of nodes */ - unsigned int finishDtd; /* finished validating the Dtd ? */ + unsigned int flags; /* internal flags */ xmlDocPtr doc; /* the document */ int valid; /* temporary validity check result */ diff --git a/parserInternals.c b/parserInternals.c index c5c0b16d..cf5ad369 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -1733,7 +1733,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) ctxt->options |= XML_PARSE_NOBLANKS; } - ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; + ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT; ctxt->vctxt.userData = ctxt; ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.warning = xmlParserValidityWarning; diff --git a/valid.c b/valid.c index 8e596f1d..5cd1e676 100644 --- a/valid.c +++ b/valid.c @@ -64,10 +64,9 @@ xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra) if (ctxt != NULL) { channel = ctxt->error; data = ctxt->userData; - /* Use the special values to detect if it is part of a parsing + /* Look up flag to detect if it is part of a parsing context */ - if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { + if (ctxt->flags & XML_VCTXT_USE_PCTXT) { long delta = (char *) ctxt - (char *) ctxt->userData; if ((delta > 0) && (delta < 250)) pctxt = ctxt->userData; @@ -104,10 +103,9 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error, if (ctxt != NULL) { channel = ctxt->error; data = ctxt->userData; - /* Use the special values to detect if it is part of a parsing + /* Look up flag to detect if it is part of a parsing context */ - if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { + if (ctxt->flags & XML_VCTXT_USE_PCTXT) { long delta = (char *) ctxt - (char *) ctxt->userData; if ((delta > 0) && (delta < 250)) pctxt = ctxt->userData; @@ -151,10 +149,9 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt, if (ctxt != NULL) { channel = ctxt->error; data = ctxt->userData; - /* Use the special values to detect if it is part of a parsing + /* Look up flag to detect if it is part of a parsing context */ - if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { + if (ctxt->flags & XML_VCTXT_USE_PCTXT) { long delta = (char *) ctxt - (char *) ctxt->userData; if ((delta > 0) && (delta < 250)) pctxt = ctxt->userData; @@ -194,10 +191,9 @@ xmlErrValidNodeNr(xmlValidCtxtPtr ctxt, if (ctxt != NULL) { channel = ctxt->error; data = ctxt->userData; - /* Use the special values to detect if it is part of a parsing + /* Look up flag to detect if it is part of a parsing context */ - if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { + if (ctxt->flags & XML_VCTXT_USE_PCTXT) { long delta = (char *) ctxt - (char *) ctxt->userData; if ((delta > 0) && (delta < 250)) pctxt = ctxt->userData; @@ -235,10 +231,9 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt, if (ctxt != NULL) { channel = ctxt->warning; data = ctxt->userData; - /* Use the special values to detect if it is part of a parsing + /* Look up flag to detect if it is part of a parsing context */ - if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { + if (ctxt->flags & XML_VCTXT_USE_PCTXT) { long delta = (char *) ctxt - (char *) ctxt->userData; if ((delta > 0) && (delta < 250)) pctxt = ctxt->userData; @@ -1642,9 +1637,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, * and flag it by setting a special parent value * so the parser doesn't unallocate it. */ - if ((ctxt != NULL) && - ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || - (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1))) { + if ((ctxt != NULL) && (ctxt->flags & XML_VCTXT_USE_PCTXT)) { ret->content = content; if (content != NULL) content->parent = (xmlElementContentPtr) 1; @@ -2642,13 +2635,7 @@ xmlIsStreaming(xmlValidCtxtPtr ctxt) { if (ctxt == NULL) return(0); - /* - * These magic values are also abused to detect whether we're validating - * while parsing a document. In this case, userData points to the parser - * context. - */ - if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) && - (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1)) + if ((ctxt->flags & XML_VCTXT_USE_PCTXT) == 0) return(0); pctxt = ctxt->userData; return(pctxt->parseMode == XML_PARSE_READER); @@ -6677,8 +6664,8 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { } /* trick to get correct line id report */ - save = ctxt->finishDtd; - ctxt->finishDtd = 0; + save = ctxt->flags; + ctxt->flags &= ~XML_VCTXT_USE_PCTXT; /* * Check all the NOTATION/NOTATIONS attributes @@ -6694,7 +6681,7 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { ctxt->valid = 1; xmlHashScan(table, xmlValidateCheckRefCallback, ctxt); - ctxt->finishDtd = save; + ctxt->flags = save; return(ctxt->valid); }