Fixed a seg fault in xmlGetQNameProp: a format argument was missing. Fixed

* xmlschemas.c include/libxml/schemasInternals.h
  include/libxml/xmlerror.h: Fixed a seg fault in xmlGetQNameProp:
  a format argument was missing.
  Fixed wrong assignment of the owner of a wildcard in
  xmlSchemaBuildAttributeValidation (in the shorthandform of
  <complexType>; this caused a seg fault, due to a double-free
  of the wildcard.
  Added a check for circular attribute group references.
  Added a check for circular model group definition references.
  Fixed a dublicate xmlParserErrors enum value - see bug #151738.
diff --git a/xmlschemas.c b/xmlschemas.c
index a7e8d5e..ce4b558 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3243,9 +3243,16 @@
     xmlNsPtr ns;
     const xmlChar *ret, *prefix;
     int len;
+    xmlAttrPtr attr;
 
     *namespace = NULL;
-    val = xmlSchemaGetProp(ctxt, node, name);
+    attr = xmlSchemaGetPropNode(node, name);
+    if (attr == NULL)
+	return (NULL);
+    val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
+    /*
+    * TODO: Is the empty value valid for QNames?
+    */
     if (val == NULL)
         return (NULL);
 
@@ -3265,10 +3272,12 @@
 
     ns = xmlSearchNs(node->doc, node, prefix);
     if (ns == NULL) {
-        xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
-	    "Attribute '%s': The prefix '%s' of the QName "
-	    "'%s' has no corresponding namespace declaration is scope.\n",
-	    (const xmlChar *) name, prefix);
+        xmlSchemaPSimpleTypeErr(ctxt, XML_SCHEMAP_PREFIX_UNDEFINED, 
+	    NULL, NULL, (xmlNodePtr) attr, 
+	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, val,
+	    "The prefix '%s' of the QName value "
+	    "'%s' has no corresponding namespace declaration in scope",
+	    prefix, val);
     } else {
         *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
     }
@@ -5708,11 +5717,19 @@
     const xmlChar *name;
     const xmlChar *ref = NULL, *refNs = NULL;
     char buf[100];
+    int minOccurs, maxOccurs;
 
     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
         return (NULL);
-
-
+    /*
+    * TODO: Validate the element even if no item is created 
+    * (i.e. min/maxOccurs == 0).
+    */
+    minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
+    maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)");
+    if ((minOccurs == 0) && (maxOccurs == 0)) {
+	return (NULL);
+    }
     name = xmlSchemaGetProp(ctxt, node, "name");
     if (name == NULL) {
         ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
@@ -5738,10 +5755,9 @@
     type->id = xmlSchemaGetProp(ctxt, node, "id");
     type->ref = ref;
     type->refNs = refNs;
-
-    type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
-    type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(nonNegativeInteger | unbounded)");
-    xmlSchemaPCheckParticleCorrect_2(ctxt, type, 
+    type->minOccurs = minOccurs;
+    type->maxOccurs = maxOccurs;
+    xmlSchemaPCheckParticleCorrect_2(ctxt, type,
 	node, type->minOccurs, type->maxOccurs);    
 
     child = node->children;
@@ -8137,23 +8153,50 @@
                 xmlSchemaBuildAContentModel(type->subtypes, ctxt, name);
             break;
         case XML_SCHEMA_TYPE_GROUP:
-            if (type->subtypes == NULL) {
-	        xmlSchemaTypePtr rgroup;
-		if (type->ref != NULL) {
-		    rgroup = xmlSchemaGetGroup(ctxt->schema, type->ref,
-		    			   type->refNs);
-		    if (rgroup == NULL) {
-			xmlSchemaPResCompAttrErr(ctxt, 
-			    XML_SCHEMAP_SRC_RESOLVE, 
-			    NULL, type, NULL,
-			    "ref", type->ref, type->refNs, 
-			    XML_SCHEMA_TYPE_GROUP, NULL);		        
-			return;
-		    }
-		    xmlSchemaBuildAContentModel(rgroup, ctxt, name);
-		    break;
-		}
-            }
+	    /*
+	    * Handle model group definition references. 
+	    * NOTE: type->subtypes is the referenced model grop definition;
+	    * and type->subtypes->subtypes is the model group (i.e. <all> or 
+	    * <choice> or <sequence>).
+	    */
+	    if ((type->ref != NULL) && (type->subtypes != NULL) &&
+		(type->subtypes->subtypes != NULL)) {
+		xmlSchemaTypePtr modelGr;
+                xmlAutomataStatePtr start, end;
+
+		modelGr = type->subtypes->subtypes;
+                start = ctxt->state;
+                end = xmlAutomataNewState(ctxt->am);		
+                if (type->maxOccurs == 1) {
+		    ctxt->state = start;
+		    xmlSchemaBuildAContentModel(modelGr, ctxt, name);
+		    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+                } else {
+                    int counter;
+                    xmlAutomataStatePtr hop;
+                    int maxOccurs = type->maxOccurs == UNBOUNDED ?
+				    UNBOUNDED : type->maxOccurs - 1;
+                    int minOccurs =
+                        type->minOccurs < 1 ? 0 : type->minOccurs - 1;
+		    
+                    counter =
+                        xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
+                    hop = xmlAutomataNewState(ctxt->am);		                        
+                    ctxt->state = start;
+                    xmlSchemaBuildAContentModel(modelGr, ctxt, name);
+                    xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+                    xmlAutomataNewCountedTrans(ctxt->am, hop, start,
+			counter);
+                    xmlAutomataNewCounterTrans(ctxt->am, hop, end,
+			counter);
+                }
+                if (type->minOccurs == 0) {
+                    xmlAutomataNewEpsilon(ctxt->am, start, end);
+                }
+                ctxt->state = end;
+                break;
+	    }
+	    break;
         case XML_SCHEMA_TYPE_COMPLEX:
         case XML_SCHEMA_TYPE_COMPLEX_CONTENT:
             if (type->subtypes != NULL)
@@ -9295,6 +9338,7 @@
     xmlSchemaTypePtr anyType;
     int baseIsAnyType = 0;
     xmlChar *str = NULL;
+    int err = 0;
 
     anyType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
     /* 
@@ -9357,27 +9401,32 @@
     /*
     * Handle attribute wildcards.
     */	
-    if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, 
-	attrs, &type->attributeWildcard) == -1) {	    
-	if ((type->attributeWildcard != NULL) &&
-	    /* Either we used the short hand form... */
-	    ((type->subtypes == NULL) ||
-	    /* Or complexType -> restriction/extension */
-	    (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)))
-	    type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
-	return (-1);
-    }
+    err = xmlSchemaBuildCompleteAttributeWildcard(ctxt, 
+	attrs, &type->attributeWildcard);    
     /*
     * TODO: This "onwed_attr_wildcard" is quite sensless: we should
     * create the wildcard right from the start on the complexType,
     * rather than on the <restriction>/<extension>.
+    *
+    * This here simply checks if <complexType>-><restriction>|<extension>
+    * does exist and its wildcard is used or not.
     */
-    if ((type->attributeWildcard != NULL) &&
-	/* Either we used the short hand form... */
-	((type->subtypes == NULL) ||
-	/* Or complexType -> restriction/extension */
-	(type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)))
-	type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
+    if (type->attributeWildcard != NULL) {
+	if ((type->subtypes == NULL) ||
+	    ((type->subtypes->type != XML_SCHEMA_TYPE_COMPLEX_CONTENT) &&
+	     (type->subtypes->type != XML_SCHEMA_TYPE_SIMPLE_CONTENT)) ||
+	    (type->subtypes->subtypes == NULL) ||
+	    (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) {
+	    type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD;
+	}
+    }
+    /*
+    * Note that an error for the above call to 
+    * xmlSchemaBuildCompleteAttributeWildcard is processed here, since we
+    * needed to set XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD beforehand.
+    */
+    if (err == -1)
+	return (-1);
 
     if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) && 
 	((baseIsAnyType) ||
@@ -10957,6 +11006,38 @@
 #endif
 
 /**
+ * xmlSchemaGroupDefFixup:
+ * @typeDecl:  the schema model group definition
+ * @ctxt:  the schema parser context
+ *
+ * Fixes model group definitions.
+ */
+static void
+xmlSchemaGroupDefFixup(xmlSchemaTypePtr group,
+		       xmlSchemaParserCtxtPtr ctxt, 
+		       const xmlChar * name ATTRIBUTE_UNUSED)
+{    
+    group->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
+    if ((group->ref != NULL) && (group->subtypes == NULL)) {
+	xmlSchemaTypePtr groupDef;
+	/*
+	* Resolve the reference.
+	*/
+	groupDef = xmlSchemaGetGroup(ctxt->schema, group->ref,
+	    group->refNs);
+	if (groupDef == NULL) {
+	    xmlSchemaPResCompAttrErr(ctxt, 
+		XML_SCHEMAP_SRC_RESOLVE, 
+		NULL, group, NULL,
+		"ref", group->ref, group->refNs, 
+		XML_SCHEMA_TYPE_GROUP, NULL);
+	    return;
+	}
+	group->subtypes = groupDef;
+    }		
+}
+
+/**
  * xmlSchemaTypeFixup:
  * @typeDecl:  the schema type definition
  * @ctxt:  the schema parser context
@@ -11341,12 +11422,16 @@
 		xmlSchemaCheckSRCSimpleType(ctxt, typeDecl);
 		ctxt->ctxtType = ctxtType;
 		break;
-            case XML_SCHEMA_TYPE_SEQUENCE:
-            case XML_SCHEMA_TYPE_GROUP:
+            case XML_SCHEMA_TYPE_SEQUENCE:            
             case XML_SCHEMA_TYPE_ALL:
             case XML_SCHEMA_TYPE_CHOICE:
                 typeDecl->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
                 break;
+	    case XML_SCHEMA_TYPE_GROUP:
+		/*
+		* TODO: Handling was moved to xmlSchemaGroupDefFixup.
+		*/
+		break;
             case XML_SCHEMA_TYPE_LIST: 
 		xmlSchemaParseListRefFixup(typeDecl, ctxt);
 		typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
@@ -11623,6 +11708,234 @@
 }
 
 /**
+ * xmlSchemaGetCircModelGrDefRef:
+ * @ctxtGr: the searched model group
+ * @list: the list of model groups to be processed
+ *
+ * This one is intended to be used by
+ * xmlSchemaCheckGroupDefCircular only.
+ *
+ * Returns the circular model group definition reference, otherwise NULL.
+ */
+static xmlSchemaTypePtr
+xmlSchemaGetCircModelGrDefRef(xmlSchemaTypePtr ctxtGrDef,
+			  xmlSchemaTypePtr gr)
+{    
+    xmlSchemaTypePtr circ = NULL;
+    int marked;
+    /*
+    * We will search for an model group reference which
+    * references the context model group definition.
+    */        
+    while (gr != NULL) {
+	if (((gr->type == XML_SCHEMA_TYPE_GROUP) ||
+	     (gr->type == XML_SCHEMA_TYPE_ALL) ||
+	     (gr->type == XML_SCHEMA_TYPE_SEQUENCE) ||
+	     (gr->type == XML_SCHEMA_TYPE_CHOICE)) &&
+	    (gr->subtypes != NULL)) {		 
+	    marked = 0;
+	    if ((gr->type == XML_SCHEMA_TYPE_GROUP) &&
+		(gr->ref != NULL)) {
+		if (gr->subtypes == ctxtGrDef)
+		    return (gr);
+		else if (gr->subtypes->flags & 
+		    XML_SCHEMAS_TYPE_MARKED) {
+		    gr = gr->next;
+		    continue;
+		} else {
+		    /*
+		    * Mark to avoid infinite recursion on
+		    * circular references not yet examined.
+		    */
+		    gr->subtypes->flags |= XML_SCHEMAS_TYPE_MARKED;
+		    marked = 1;
+		} 
+		if (gr->subtypes->subtypes != NULL)
+		    circ = xmlSchemaGetCircModelGrDefRef(ctxtGrDef, 
+			gr->subtypes->subtypes);
+		    /*
+		    * Unmark the visited model group definition.
+		*/
+		if (marked)
+		    gr->subtypes->flags ^= XML_SCHEMAS_TYPE_MARKED;
+		if (circ != NULL)
+		    return (circ);
+	    } else {
+		circ = xmlSchemaGetCircModelGrDefRef(ctxtGrDef, 
+		    (xmlSchemaTypePtr) gr->subtypes);
+		if (circ != NULL)
+		    return (circ);
+	    }
+
+	}
+	gr = gr->next;
+    }
+    return (NULL);
+}
+
+/**
+ * xmlSchemaCheckGroupDefCircular:
+ * attrGr:  the model group definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Checks for circular references to model group definitions.
+ */
+static void
+xmlSchemaCheckGroupDefCircular(xmlSchemaTypePtr modelGrDef,
+			    xmlSchemaParserCtxtPtr ctxt, 
+			    const xmlChar * name ATTRIBUTE_UNUSED)
+{    
+    /*
+    * Schema Component Constraint: Model Group Correct
+    * 2 Circular groups are disallowed. That is, within the {particles} 
+    * of a group there must not be at any depth a particle whose {term} 
+    * is the group itself.
+    */
+    /*
+    * NOTE: "gr->subtypes" holds the referenced group.
+    */
+    if ((modelGrDef->type != XML_SCHEMA_TYPE_GROUP) || 
+	((modelGrDef->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0) ||
+	(modelGrDef->subtypes == NULL))
+	return;
+    else {
+	xmlSchemaTypePtr circ;
+
+	circ = xmlSchemaGetCircModelGrDefRef(modelGrDef, modelGrDef->subtypes);
+	if (circ != NULL) {
+	    /*
+	    * TODO: Report the referenced attr group as QName.
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_MG_PROPS_CORRECT_2,
+		NULL, NULL, circ->node,
+		"Circular reference to the model group definition '%s' "
+		"defined", modelGrDef->name);
+	    /*
+	    * NOTE: We will cut the reference to avoid further
+	    * confusion of the processor.
+	    * TODO: SPEC: Does the spec define how to process here?
+	    */
+	    circ->subtypes = NULL;
+	}
+    }
+}
+
+
+/**
+ * xmlSchemaGetCircAttrGrRef:
+ * @ctxtGr: the searched attribute group
+ * @attr: the current attribute list to be processed
+ *
+ * This one is intended to be used by
+ * xmlSchemaCheckSRCAttributeGroupCircular only.
+ *
+ * Returns the circular attribute grou reference, otherwise NULL.
+ */
+static xmlSchemaAttributeGroupPtr
+xmlSchemaGetCircAttrGrRef(xmlSchemaAttributeGroupPtr ctxtGr,
+			  xmlSchemaAttributePtr attr)
+{    
+    xmlSchemaAttributeGroupPtr circ = NULL, gr;
+    int marked;
+    /*
+    * We will search for an attribute group reference which
+    * references the context attribute group.
+    */    	
+    while (attr != NULL) {
+	marked = 0;
+	if (attr->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
+	    gr = (xmlSchemaAttributeGroupPtr) attr;
+	    if (gr->refItem != NULL)  {
+		if (gr->refItem == ctxtGr)
+		    return (gr);
+		else if (gr->refItem->flags & 
+		    XML_SCHEMAS_ATTRGROUP_MARKED) {
+		    attr = attr->next;
+		    continue;
+		} else {
+		    /*
+		    * Mark as visited to avoid infinite recursion on
+		    * circular references not yet examined.
+		    */
+		    gr->refItem->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
+		    marked = 1;
+		}
+	    }
+	    if (gr->attributes != NULL)
+		circ = xmlSchemaGetCircAttrGrRef(ctxtGr, gr->attributes);
+	    /*
+	    * Unmark the visited group's attributes.
+	    */
+	    if (marked)
+		gr->refItem->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
+	    if (circ != NULL)
+		return (circ);
+	}
+	attr = attr->next;
+    }
+    return (NULL);
+}
+				
+/**
+ * xmlSchemaCheckSRCAttributeGroupCircular:
+ * attrGr:  the attribute group definition
+ * @ctxt:  the parser context
+ * @name:  the name
+ *
+ * Checks for circular references of attribute groups.
+ */
+static void
+xmlSchemaCheckAttributeGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
+					xmlSchemaParserCtxtPtr ctxt, 
+					const xmlChar * name ATTRIBUTE_UNUSED)
+{    
+    /*
+    * Schema Representation Constraint: 
+    * Attribute Group Definition Representation OK
+    * 3 Circular group reference is disallowed outside <redefine>. 
+    * That is, unless this element information item's parent is 
+    * <redefine>, then among the [children], if any, there must 
+    * not be an <attributeGroup> with ref [attribute] which resolves 
+    * to the component corresponding to this <attributeGroup>. Indirect 
+    * circularity is also ruled out. That is, when QName resolution 
+    * (Schema Document) (§3.15.3) is applied to a ·QName· arising from 
+    * any <attributeGroup>s with a ref [attribute] among the [children], 
+    * it must not be the case that a ·QName· is encountered at any depth 
+    * which resolves to the component corresponding to this <attributeGroup>.
+    */
+    /*
+    * Only global components can be referenced.
+    */
+    if (((attrGr->flags & XML_SCHEMAS_ATTRGROUP_GLOBAL) == 0) || 
+	(attrGr->attributes == NULL))
+	return;
+    else {
+	xmlSchemaAttributeGroupPtr circ;
+
+	circ = xmlSchemaGetCircAttrGrRef(attrGr, attrGr->attributes);
+	if (circ != NULL) {
+	    /*
+	    * TODO: Report the referenced attr group as QName.
+	    */
+	    xmlSchemaPCustomErr(ctxt,
+		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
+		NULL, NULL, circ->node,
+		"Circular reference to the attribute group '%s' "
+		"defined", attrGr->name);
+	    /*
+	    * NOTE: We will cut the reference to avoid further
+	    * confusion of the processor.
+	    * BADSPEC: The spec should define how to process in this case.
+	    */
+	    circ->attributes = NULL;
+	    circ->refItem = NULL;
+	}
+    }
+}
+
+/**
  * xmlSchemaAttrGrpFixup:
  * @attrgrpDecl:  the schema attribute definition
  * @ctxt:  the schema parser context
@@ -11651,6 +11964,10 @@
 		XML_SCHEMA_TYPE_ATTRIBUTEGROUP, NULL);
             return;
         }
+	attrgrp->refItem = ref;
+	/*
+	* Check for self reference!
+	*/
         xmlSchemaAttrGrpFixup(ref, ctxt, NULL);
         attrgrp->attributes = ref->attributes;
 	attrgrp->attributeWildcard = ref->attributeWildcard;
@@ -11834,9 +12151,20 @@
                 ctxt);
 
     /*
+    * Check attribute groups for circular references.
+    */
+    xmlHashScan(ret->attrgrpDecl, (xmlHashScanner) 
+	xmlSchemaCheckAttributeGroupCircular, ctxt);
+
+    /*
+    * Then fixup all model group definitions.
+    */    
+    xmlHashScan(ret->groupDecl, (xmlHashScanner) xmlSchemaGroupDefFixup, ctxt);
+
+    /*
      * Then fixup all types properties
      */    
-    xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);    
+    xmlHashScan(ret->typeDecl, (xmlHashScanner) xmlSchemaTypeFixup, ctxt);
 
     /*
      * Then fix references of element declaration; apply constraints.
@@ -11844,6 +12172,13 @@
     xmlHashScanFull(ret->elemDecl,
                     (xmlHashScannerFull) xmlSchemaRefFixupCallback, ctxt);
 
+     /*
+    * Check model groups defnitions for circular references.
+    */
+    xmlHashScan(ret->groupDecl, (xmlHashScanner) 
+	xmlSchemaCheckGroupDefCircular, ctxt);
+
+
     /*
      * Then build the content model for all elements
      */