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
diff --git a/valid.c b/valid.c
index 4e9bcfb..48f7e15 100644
--- a/valid.c
+++ b/valid.c
@@ -3503,22 +3503,9 @@
  */
 
 static xmlNodePtr
-xmlValidateSkipIgnorable(xmlValidCtxtPtr ctxt, xmlNodePtr child) {
+xmlValidateSkipIgnorable(xmlNodePtr child) {
     while (child != NULL) {
 	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.  */
 	    case XML_PI_NODE:
 	    case XML_COMMENT_NODE:
@@ -3546,8 +3533,8 @@
  *
  * Try to validate the content model of an element internal function
  *
- * returns 1 if valid or 0 and -1 if PCDATA stuff is found,
- *         also update child and content values in-situ.
+ * returns 1 if valid or 0 ,-1 in case of error, and -2 if an entity
+ *           reference is found.
  */
 
 static int
@@ -3555,7 +3542,7 @@
     int ret = -1;
     int consumed = 1;
 
-    NODE = xmlValidateSkipIgnorable(ctxt, NODE);
+    NODE = xmlValidateSkipIgnorable(NODE);
     if ((NODE == NULL) && (CONT == NULL))
 	return(1);
     if ((NODE == NULL) && 
@@ -3564,6 +3551,8 @@
 	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
@@ -3615,7 +3604,10 @@
 		 */
 		do {
 		    NODE = NODE->next;
-		    NODE = xmlValidateSkipIgnorable(ctxt, NODE);
+		    NODE = xmlValidateSkipIgnorable(NODE);
+		    if ((NODE != NULL) &&
+			(NODE->type == XML_ENTITY_REF_NODE))
+			return(-2);
 		} while ((NODE != NULL) &&
 			 ((NODE->type != XML_ELEMENT_NODE) &&
 			  (NODE->type != XML_TEXT_NODE)));
@@ -3643,7 +3635,10 @@
 		 */
 		do {
 		    NODE = NODE->next;
-		    NODE = xmlValidateSkipIgnorable(ctxt, NODE);
+		    NODE = xmlValidateSkipIgnorable(NODE);
+		    if ((NODE != NULL) &&
+			(NODE->type == XML_ENTITY_REF_NODE))
+			return(-2);
 		} while ((NODE != NULL) &&
 			 ((NODE->type != XML_ELEMENT_NODE) &&
 			  (NODE->type != XML_TEXT_NODE)));
@@ -3852,10 +3847,10 @@
 xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
 		   xmlElementContentPtr cont) {
     int ret;
+    xmlNodePtr repl = NULL, last = NULL, tmp;
 
     /*
-     * TODO: handle the fact that entities references
-     * may appear at this level.
+     * Allocate the stack
      */
     ctxt->vstateMax = 8;
     ctxt->vstateTab = (xmlValidState *) xmlMalloc(
@@ -3863,7 +3858,7 @@
     if (ctxt->vstateTab == NULL) {
 	xmlGenericError(xmlGenericErrorContext,
 		"malloc failed !n");
-	return(0);
+	return(-1);
     }
     /*
      * The first entry in the stack is reserved to the current state
@@ -3876,10 +3871,95 @@
     OCCURS = 0;
     STATE = 0;
     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;
     xmlFree(ctxt->vstateTab);
-
     return(ret);
+
 }
 #endif /* ALLOW_UNDETERMINISTIC_MODELS */