mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
The last main work left on non-determinist validation:
- valid.c: fixed to validate within entities - test/VCM/v22.xml: added a specific testcase Daniel
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
Sat Apr 21 12:25:49 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
|
* valid.c: fixed to validate within entities
|
||||||
|
* test/VCM/v22.xml: added a specific testcase
|
||||||
|
|
||||||
Fri Apr 20 17:45:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
Fri Apr 20 17:45:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* valid.c: forgot an epsilon transition in for ()+
|
* valid.c: forgot an epsilon transition in for ()+
|
||||||
|
15
test/VCM/v22.xml
Normal file
15
test/VCM/v22.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE doc [
|
||||||
|
<!ELEMENT doc (a, b, c, b, c, d) >
|
||||||
|
<!ELEMENT a EMPTY>
|
||||||
|
<!ELEMENT b EMPTY>
|
||||||
|
<!ELEMENT c EMPTY>
|
||||||
|
<!ELEMENT d EMPTY>
|
||||||
|
<!ENTITY c "<c/>">
|
||||||
|
<!ENTITY bc "<b/>&c;">
|
||||||
|
]>
|
||||||
|
<doc>
|
||||||
|
<a/>
|
||||||
|
&bc;
|
||||||
|
&bc;
|
||||||
|
<d/>
|
||||||
|
</doc>
|
126
valid.c
126
valid.c
@ -3503,22 +3503,9 @@ xmlValidateElementTypeElement(xmlValidCtxtPtr ctxt, xmlNodePtr *child,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static xmlNodePtr
|
static xmlNodePtr
|
||||||
xmlValidateSkipIgnorable(xmlValidCtxtPtr ctxt, xmlNodePtr child) {
|
xmlValidateSkipIgnorable(xmlNodePtr child) {
|
||||||
while (child != NULL) {
|
while (child != NULL) {
|
||||||
switch (child->type) {
|
switch (child->type) {
|
||||||
/*
|
|
||||||
* If there is an entity declared and it's not empty
|
|
||||||
* Push the current node on the stack and process with the
|
|
||||||
* entity content.
|
|
||||||
*/
|
|
||||||
case XML_ENTITY_REF_NODE:
|
|
||||||
if ((child->children != NULL) &&
|
|
||||||
(child->children->children != NULL)) {
|
|
||||||
nodeVPush(ctxt, child);
|
|
||||||
child = child->children->children;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* These things are ignored (skipped) during validation. */
|
/* These things are ignored (skipped) during validation. */
|
||||||
case XML_PI_NODE:
|
case XML_PI_NODE:
|
||||||
case XML_COMMENT_NODE:
|
case XML_COMMENT_NODE:
|
||||||
@ -3546,8 +3533,8 @@ xmlValidateSkipIgnorable(xmlValidCtxtPtr ctxt, xmlNodePtr child) {
|
|||||||
*
|
*
|
||||||
* Try to validate the content model of an element internal function
|
* Try to validate the content model of an element internal function
|
||||||
*
|
*
|
||||||
* returns 1 if valid or 0 and -1 if PCDATA stuff is found,
|
* returns 1 if valid or 0 ,-1 in case of error, and -2 if an entity
|
||||||
* also update child and content values in-situ.
|
* reference is found.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -3555,7 +3542,7 @@ xmlValidateElementType(xmlValidCtxtPtr ctxt) {
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
int consumed = 1;
|
int consumed = 1;
|
||||||
|
|
||||||
NODE = xmlValidateSkipIgnorable(ctxt, NODE);
|
NODE = xmlValidateSkipIgnorable(NODE);
|
||||||
if ((NODE == NULL) && (CONT == NULL))
|
if ((NODE == NULL) && (CONT == NULL))
|
||||||
return(1);
|
return(1);
|
||||||
if ((NODE == NULL) &&
|
if ((NODE == NULL) &&
|
||||||
@ -3564,6 +3551,8 @@ xmlValidateElementType(xmlValidCtxtPtr ctxt) {
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
if (CONT == NULL) return(-1);
|
if (CONT == NULL) return(-1);
|
||||||
|
if (NODE->type == XML_ENTITY_REF_NODE)
|
||||||
|
return(-2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We arrive here when more states need to be examined
|
* We arrive here when more states need to be examined
|
||||||
@ -3615,7 +3604,10 @@ cont:
|
|||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
NODE = NODE->next;
|
NODE = NODE->next;
|
||||||
NODE = xmlValidateSkipIgnorable(ctxt, NODE);
|
NODE = xmlValidateSkipIgnorable(NODE);
|
||||||
|
if ((NODE != NULL) &&
|
||||||
|
(NODE->type == XML_ENTITY_REF_NODE))
|
||||||
|
return(-2);
|
||||||
} while ((NODE != NULL) &&
|
} while ((NODE != NULL) &&
|
||||||
((NODE->type != XML_ELEMENT_NODE) &&
|
((NODE->type != XML_ELEMENT_NODE) &&
|
||||||
(NODE->type != XML_TEXT_NODE)));
|
(NODE->type != XML_TEXT_NODE)));
|
||||||
@ -3643,7 +3635,10 @@ cont:
|
|||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
NODE = NODE->next;
|
NODE = NODE->next;
|
||||||
NODE = xmlValidateSkipIgnorable(ctxt, NODE);
|
NODE = xmlValidateSkipIgnorable(NODE);
|
||||||
|
if ((NODE != NULL) &&
|
||||||
|
(NODE->type == XML_ENTITY_REF_NODE))
|
||||||
|
return(-2);
|
||||||
} while ((NODE != NULL) &&
|
} while ((NODE != NULL) &&
|
||||||
((NODE->type != XML_ELEMENT_NODE) &&
|
((NODE->type != XML_ELEMENT_NODE) &&
|
||||||
(NODE->type != XML_TEXT_NODE)));
|
(NODE->type != XML_TEXT_NODE)));
|
||||||
@ -3852,10 +3847,10 @@ static int
|
|||||||
xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
|
xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
|
||||||
xmlElementContentPtr cont) {
|
xmlElementContentPtr cont) {
|
||||||
int ret;
|
int ret;
|
||||||
|
xmlNodePtr repl = NULL, last = NULL, tmp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: handle the fact that entities references
|
* Allocate the stack
|
||||||
* may appear at this level.
|
|
||||||
*/
|
*/
|
||||||
ctxt->vstateMax = 8;
|
ctxt->vstateMax = 8;
|
||||||
ctxt->vstateTab = (xmlValidState *) xmlMalloc(
|
ctxt->vstateTab = (xmlValidState *) xmlMalloc(
|
||||||
@ -3863,7 +3858,7 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
|
|||||||
if (ctxt->vstateTab == NULL) {
|
if (ctxt->vstateTab == NULL) {
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"malloc failed !n");
|
"malloc failed !n");
|
||||||
return(0);
|
return(-1);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* The first entry in the stack is reserved to the current state
|
* The first entry in the stack is reserved to the current state
|
||||||
@ -3876,10 +3871,95 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
|
|||||||
OCCURS = 0;
|
OCCURS = 0;
|
||||||
STATE = 0;
|
STATE = 0;
|
||||||
ret = xmlValidateElementType(ctxt);
|
ret = xmlValidateElementType(ctxt);
|
||||||
|
if (ret == -2) {
|
||||||
|
/*
|
||||||
|
* An entities reference appeared at this level.
|
||||||
|
* Buid a minimal representation of this node content
|
||||||
|
* sufficient to run the validation process on it
|
||||||
|
*/
|
||||||
|
DEBUG_VALID_MSG("Found an entity reference, linearizing");
|
||||||
|
while (child != NULL) {
|
||||||
|
switch (child->type) {
|
||||||
|
case XML_ENTITY_REF_NODE:
|
||||||
|
/*
|
||||||
|
* Push the current node to be able to roll back
|
||||||
|
* and process within the entity
|
||||||
|
*/
|
||||||
|
if ((child->children != NULL) &&
|
||||||
|
(child->children->children != NULL)) {
|
||||||
|
nodeVPush(ctxt, child);
|
||||||
|
child = child->children->children;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case XML_TEXT_NODE:
|
||||||
|
if (xmlIsBlankNode(child))
|
||||||
|
break;
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
/*
|
||||||
|
* Allocate a new node and minimally fills in
|
||||||
|
* what's required
|
||||||
|
*/
|
||||||
|
tmp = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
|
||||||
|
if (tmp == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlValidateElementContent : malloc failed\n");
|
||||||
|
xmlFreeNodeList(repl);
|
||||||
|
ret = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
tmp->type = child->type;
|
||||||
|
tmp->name = child->name;
|
||||||
|
tmp->ns = child->ns;
|
||||||
|
tmp->next = NULL;
|
||||||
|
if (repl == NULL)
|
||||||
|
repl = last = tmp;
|
||||||
|
else {
|
||||||
|
last->next = tmp;
|
||||||
|
last = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Switch to next element
|
||||||
|
*/
|
||||||
|
child = child->next;
|
||||||
|
while (child == NULL) {
|
||||||
|
child = nodeVPop(ctxt);
|
||||||
|
if (child == NULL)
|
||||||
|
break;
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relaunch the validation
|
||||||
|
*/
|
||||||
|
ctxt->vstate = &ctxt->vstateTab[0];
|
||||||
|
ctxt->vstateNr = 1;
|
||||||
|
CONT = cont;
|
||||||
|
NODE = repl;
|
||||||
|
DEPTH = 0;
|
||||||
|
OCCURS = 0;
|
||||||
|
STATE = 0;
|
||||||
|
ret = xmlValidateElementType(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
done:
|
||||||
|
/*
|
||||||
|
* Deallocate the copy if done, and free up the validation stack
|
||||||
|
*/
|
||||||
|
while (repl != NULL) {
|
||||||
|
tmp = repl->next;
|
||||||
|
xmlFree(repl);
|
||||||
|
repl = tmp;
|
||||||
|
}
|
||||||
ctxt->vstateMax = 0;
|
ctxt->vstateMax = 0;
|
||||||
xmlFree(ctxt->vstateTab);
|
xmlFree(ctxt->vstateTab);
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /* ALLOW_UNDETERMINISTIC_MODELS */
|
#endif /* ALLOW_UNDETERMINISTIC_MODELS */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user