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

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.
This commit is contained in:
Nick Wellnhofer
2022-01-13 17:06:14 +01:00
parent a075d256fd
commit d7cb33cf44
5 changed files with 30 additions and 41 deletions

View File

@ -5118,7 +5118,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
ctxt->linenumbers = xmlLineNumbersDefaultValue; ctxt->linenumbers = xmlLineNumbersDefaultValue;
ctxt->keepBlanks = xmlKeepBlanksDefaultValue; ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
ctxt->html = 1; ctxt->html = 1;
ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
ctxt->vctxt.userData = ctxt; ctxt->vctxt.userData = ctxt;
ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.error = xmlParserValidityError;
ctxt->vctxt.warning = xmlParserValidityWarning; ctxt->vctxt.warning = xmlParserValidityWarning;

10
SAX2.c
View File

@ -1747,7 +1747,8 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
* If it's the Document root, finish the DTD validation and * If it's the Document root, finish the DTD validation and
* check the document root element for validity * 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; int chk;
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
@ -1756,7 +1757,7 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
if (chk < 0) if (chk < 0)
ctxt->wellFormed = 0; ctxt->wellFormed = 0;
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 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 */ #endif /* LIBXML_VALID_ENABLED */
@ -2405,7 +2406,8 @@ xmlSAX2StartElementNs(void *ctx,
* If it's the Document root, finish the DTD validation and * If it's the Document root, finish the DTD validation and
* check the document root element for validity * 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; int chk;
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc); chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
@ -2414,7 +2416,7 @@ xmlSAX2StartElementNs(void *ctx,
if (chk < 0) if (chk < 0)
ctxt->wellFormed = 0; ctxt->wellFormed = 0;
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); 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 */ #endif /* LIBXML_VALID_ENABLED */
} }

View File

@ -60,17 +60,17 @@ typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx,
#ifdef IN_LIBXML #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 #endif
/* /*
@ -90,7 +90,7 @@ struct _xmlValidCtxt {
int nodeMax; /* Max depth of the parsing stack */ int nodeMax; /* Max depth of the parsing stack */
xmlNodePtr *nodeTab; /* array of nodes */ xmlNodePtr *nodeTab; /* array of nodes */
unsigned int finishDtd; /* finished validating the Dtd ? */ unsigned int flags; /* internal flags */
xmlDocPtr doc; /* the document */ xmlDocPtr doc; /* the document */
int valid; /* temporary validity check result */ int valid; /* temporary validity check result */

View File

@ -1733,7 +1733,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
ctxt->options |= XML_PARSE_NOBLANKS; 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.userData = ctxt;
ctxt->vctxt.error = xmlParserValidityError; ctxt->vctxt.error = xmlParserValidityError;
ctxt->vctxt.warning = xmlParserValidityWarning; ctxt->vctxt.warning = xmlParserValidityWarning;

43
valid.c
View File

@ -64,10 +64,9 @@ xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra)
if (ctxt != NULL) { if (ctxt != NULL) {
channel = ctxt->error; channel = ctxt->error;
data = ctxt->userData; 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 */ context */
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
long delta = (char *) ctxt - (char *) ctxt->userData; long delta = (char *) ctxt - (char *) ctxt->userData;
if ((delta > 0) && (delta < 250)) if ((delta > 0) && (delta < 250))
pctxt = ctxt->userData; pctxt = ctxt->userData;
@ -104,10 +103,9 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
if (ctxt != NULL) { if (ctxt != NULL) {
channel = ctxt->error; channel = ctxt->error;
data = ctxt->userData; 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 */ context */
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
long delta = (char *) ctxt - (char *) ctxt->userData; long delta = (char *) ctxt - (char *) ctxt->userData;
if ((delta > 0) && (delta < 250)) if ((delta > 0) && (delta < 250))
pctxt = ctxt->userData; pctxt = ctxt->userData;
@ -151,10 +149,9 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt,
if (ctxt != NULL) { if (ctxt != NULL) {
channel = ctxt->error; channel = ctxt->error;
data = ctxt->userData; 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 */ context */
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
long delta = (char *) ctxt - (char *) ctxt->userData; long delta = (char *) ctxt - (char *) ctxt->userData;
if ((delta > 0) && (delta < 250)) if ((delta > 0) && (delta < 250))
pctxt = ctxt->userData; pctxt = ctxt->userData;
@ -194,10 +191,9 @@ xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
if (ctxt != NULL) { if (ctxt != NULL) {
channel = ctxt->error; channel = ctxt->error;
data = ctxt->userData; 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 */ context */
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
long delta = (char *) ctxt - (char *) ctxt->userData; long delta = (char *) ctxt - (char *) ctxt->userData;
if ((delta > 0) && (delta < 250)) if ((delta > 0) && (delta < 250))
pctxt = ctxt->userData; pctxt = ctxt->userData;
@ -235,10 +231,9 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt,
if (ctxt != NULL) { if (ctxt != NULL) {
channel = ctxt->warning; channel = ctxt->warning;
data = ctxt->userData; 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 */ context */
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
long delta = (char *) ctxt - (char *) ctxt->userData; long delta = (char *) ctxt - (char *) ctxt->userData;
if ((delta > 0) && (delta < 250)) if ((delta > 0) && (delta < 250))
pctxt = ctxt->userData; pctxt = ctxt->userData;
@ -1642,9 +1637,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
* and flag it by setting a special parent value * and flag it by setting a special parent value
* so the parser doesn't unallocate it. * so the parser doesn't unallocate it.
*/ */
if ((ctxt != NULL) && if ((ctxt != NULL) && (ctxt->flags & XML_VCTXT_USE_PCTXT)) {
((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1))) {
ret->content = content; ret->content = content;
if (content != NULL) if (content != NULL)
content->parent = (xmlElementContentPtr) 1; content->parent = (xmlElementContentPtr) 1;
@ -2642,13 +2635,7 @@ xmlIsStreaming(xmlValidCtxtPtr ctxt) {
if (ctxt == NULL) if (ctxt == NULL)
return(0); return(0);
/* if ((ctxt->flags & XML_VCTXT_USE_PCTXT) == 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))
return(0); return(0);
pctxt = ctxt->userData; pctxt = ctxt->userData;
return(pctxt->parseMode == XML_PARSE_READER); return(pctxt->parseMode == XML_PARSE_READER);
@ -6677,8 +6664,8 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
} }
/* trick to get correct line id report */ /* trick to get correct line id report */
save = ctxt->finishDtd; save = ctxt->flags;
ctxt->finishDtd = 0; ctxt->flags &= ~XML_VCTXT_USE_PCTXT;
/* /*
* Check all the NOTATION/NOTATIONS attributes * Check all the NOTATION/NOTATIONS attributes
@ -6694,7 +6681,7 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
ctxt->valid = 1; ctxt->valid = 1;
xmlHashScan(table, xmlValidateCheckRefCallback, ctxt); xmlHashScan(table, xmlValidateCheckRefCallback, ctxt);
ctxt->finishDtd = save; ctxt->flags = save;
return(ctxt->valid); return(ctxt->valid);
} }