Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gnulib-local / lib / libxml / valid.c
index a239e68..45a3f70 100644 (file)
@@ -31,11 +31,16 @@ static xmlElementPtr xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name,
 /* #define DEBUG_VALID_ALGO */
 /* #define DEBUG_REGEXP_ALGO */
 
-#define TODO                                                           \
+#define TODO                                                           \
     xmlGenericError(xmlGenericErrorContext,                            \
            "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);
 
+#ifdef LIBXML_VALID_ENABLED
+static int
+xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
+                                  const xmlChar *value);
+#endif
 /************************************************************************
  *                                                                     *
  *                     Error handling routines                         *
@@ -117,7 +122,7 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
         __xmlRaiseError(NULL, channel, data,
                         pctxt, NULL, XML_FROM_VALID, error,
                         XML_ERR_ERROR, NULL, 0, NULL, NULL, NULL, 0, 0,
-                        msg);
+                        "%s", msg);
 }
 
 #if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
@@ -296,7 +301,7 @@ vstateVPush(xmlValidCtxtPtr ctxt, xmlElementPtr elemDecl, xmlNodePtr node) {
        if (elemDecl->contModel == NULL)
            xmlValidBuildContentModel(ctxt, elemDecl);
        if (elemDecl->contModel != NULL) {
-           ctxt->vstateTab[ctxt->vstateNr].exec = 
+           ctxt->vstateTab[ctxt->vstateNr].exec =
                xmlRegNewExecCtxt(elemDecl->contModel, NULL, NULL);
        } else {
            ctxt->vstateTab[ctxt->vstateNr].exec = NULL;
@@ -618,7 +623,7 @@ xmlValidStateDebug(xmlValidCtxtPtr ctxt) {
 #define DEBUG_VALID_STATE(n,c) xmlValidStateDebug(ctxt);
 #define DEBUG_VALID_MSG(m)                                     \
     xmlGenericError(xmlGenericErrorContext, "%s\n", m);
-        
+
 #else
 #define DEBUG_VALID_STATE(n,c)
 #define DEBUG_VALID_MSG(m)
@@ -632,8 +637,6 @@ xmlValidStateDebug(xmlValidCtxtPtr ctxt) {
    else if ((doc->intSubset == NULL) &&                                \
            (doc->extSubset == NULL)) return(0)
 
-xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
-
 #ifdef LIBXML_REGEXP_ENABLED
 
 /************************************************************************
@@ -673,7 +676,7 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
            xmlAutomataStatePtr oldstate = ctxt->state;
            xmlChar fn[50];
            xmlChar *fullname;
-           
+
            fullname = xmlBuildQName(content->name, content->prefix, fn, 50);
            if (fullname == NULL) {
                xmlVErrMemory(ctxt, "Building content model");
@@ -698,9 +701,9 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
                    break;
                case XML_ELEMENT_CONTENT_MULT:
                    ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
-                                           ctxt->state, NULL);
+                                           ctxt->state, NULL);
                    xmlAutomataNewTransition(ctxt->am,
-                           ctxt->state, ctxt->state, fullname, NULL);
+                           ctxt->state, ctxt->state, fullname, NULL);
                    break;
            }
            if ((fullname != fn) && (fullname != content->name))
@@ -749,7 +752,7 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
            xmlElementContentOccur ocur;
 
            ocur = content->ocur;
-           if ((ocur == XML_ELEMENT_CONTENT_PLUS) || 
+           if ((ocur == XML_ELEMENT_CONTENT_PLUS) ||
                (ocur == XML_ELEMENT_CONTENT_MULT)) {
                ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
                        ctxt->state, NULL);
@@ -941,7 +944,7 @@ xmlNewDocElementContent(xmlDocPtr doc, const xmlChar *name,
            }
            break;
        default:
-           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "Internal: ELEMENT content corrupted invalid type\n",
                    NULL);
            return(NULL);
@@ -998,7 +1001,7 @@ xmlNewElementContent(const xmlChar *name, xmlElementContentType type) {
  * @cur:  An element content pointer.
  *
  * Build a copy of an element content description.
- * 
+ *
  * Returns the new xmlElementContentPtr or NULL in case of error.
  */
 xmlElementContentPtr
@@ -1025,7 +1028,7 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
        else
            ret->name = xmlStrdup(cur->name);
     }
-    
+
     if (cur->prefix != NULL) {
        if (dict)
            ret->prefix = xmlDictLookup(dict, cur->prefix, -1);
@@ -1055,7 +1058,7 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
                else
                    tmp->name = xmlStrdup(cur->name);
            }
-           
+
            if (cur->prefix != NULL) {
                if (dict)
                    tmp->prefix = xmlDictLookup(dict, cur->prefix, -1);
@@ -1079,7 +1082,7 @@ xmlCopyDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
  *
  * Build a copy of an element content description.
  * Deprecated, use xmlCopyDocElementContent instead
- * 
+ *
  * Returns the new xmlElementContentPtr or NULL in case of error.
  */
 xmlElementContentPtr
@@ -1111,7 +1114,7 @@ xmlFreeDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
            case XML_ELEMENT_CONTENT_OR:
                break;
            default:
-               xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+               xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                        "Internal: ELEMENT content corrupted invalid type\n",
                        NULL);
                return;
@@ -1197,7 +1200,7 @@ xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob)
                xmlDumpElementContent(buf, content->c2, 0);
            break;
        default:
-           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "Internal: ELEMENT content corrupted invalid type\n",
                    NULL);
     }
@@ -1394,7 +1397,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
     switch (type) {
         case XML_ELEMENT_TYPE_EMPTY:
            if (content != NULL) {
-               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                        "xmlAddElementDecl: content != NULL for EMPTY\n",
                        NULL);
                return(NULL);
@@ -1402,7 +1405,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
            break;
        case XML_ELEMENT_TYPE_ANY:
            if (content != NULL) {
-               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                        "xmlAddElementDecl: content != NULL for ANY\n",
                        NULL);
                return(NULL);
@@ -1410,7 +1413,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
            break;
        case XML_ELEMENT_TYPE_MIXED:
            if (content == NULL) {
-               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                        "xmlAddElementDecl: content == NULL for MIXED\n",
                        NULL);
                return(NULL);
@@ -1418,14 +1421,14 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
            break;
        case XML_ELEMENT_TYPE_ELEMENT:
            if (content == NULL) {
-               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+               xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                        "xmlAddElementDecl: content == NULL for ELEMENT\n",
                        NULL);
                return(NULL);
            }
            break;
        default:
-           xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                    "Internal: ELEMENT decl corrupted invalid type\n",
                    NULL);
            return(NULL);
@@ -1605,7 +1608,7 @@ xmlFreeElementTable(xmlElementTablePtr table) {
  * @elem:  An element
  *
  * Build a copy of an element.
- * 
+ *
  * Returns the new xmlElementPtr or NULL in case of error.
  */
 static xmlElementPtr
@@ -1639,7 +1642,7 @@ xmlCopyElement(xmlElementPtr elem) {
  * @table:  An element table
  *
  * Build a copy of an element table.
- * 
+ *
  * Returns the new xmlElementTablePtr or NULL in case of error.
  */
 xmlElementTablePtr
@@ -1704,7 +1707,7 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) {
            xmlBufferWriteChar(buf, ">\n");
            break;
        default:
-           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "Internal: ELEMENT struct corrupted invalid type\n",
                    NULL);
     }
@@ -1795,6 +1798,7 @@ xmlCopyEnumeration(xmlEnumerationPtr cur) {
 
     if (cur == NULL) return(NULL);
     ret = xmlCreateEnumeration((xmlChar *) cur->name);
+    if (ret == NULL) return(NULL);
 
     if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
     else ret->next = NULL;
@@ -1815,7 +1819,7 @@ static void
 xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
     if ((buf == NULL) || (cur == NULL))
         return;
-    
+
     xmlBufferWriteCHAR(buf, cur->name);
     if (cur->next == NULL)
        xmlBufferWriteChar(buf, ")");
@@ -1828,53 +1832,6 @@ xmlDumpEnumeration(xmlBufferPtr buf, xmlEnumerationPtr cur) {
 
 #ifdef LIBXML_VALID_ENABLED
 /**
- * xmlScanAttributeDeclCallback:
- * @attr:  the attribute decl
- * @list:  the list to update
- *
- * Callback called by xmlScanAttributeDecl when a new attribute
- * has to be entered in the list.
- */
-static void
-xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
-                            const xmlChar* name ATTRIBUTE_UNUSED) {
-    attr->nexth = *list;
-    *list = attr;
-}
-
-/**
- * xmlScanAttributeDecl:
- * @dtd:  pointer to the DTD
- * @elem:  the element name
- *
- * When inserting a new element scan the DtD for existing attributes
- * for that element and initialize the Attribute chain
- *
- * Returns the pointer to the first attribute decl in the chain,
- *         possibly NULL.
- */
-xmlAttributePtr
-xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
-    xmlAttributePtr ret = NULL;
-    xmlAttributeTablePtr table;
-
-    if (dtd == NULL) {
-       return(NULL);
-    }
-    if (elem == NULL) {
-       return(NULL);
-    }
-    table = (xmlAttributeTablePtr) dtd->attributes;
-    if (table == NULL) 
-        return(NULL);
-
-    /* WRONG !!! */
-    xmlHashScan3(table, NULL, NULL, elem,
-               (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
-    return(ret);
-}
-
-/**
  * xmlScanIDAttributeDecl:
  * @ctxt:  the validation context
  * @elem:  the element name
@@ -2017,14 +1974,14 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
         case XML_ATTRIBUTE_NOTATION:
            break;
        default:
-           xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(ctxt, XML_ERR_INTERNAL_ERROR,
                    "Internal: ATTRIBUTE struct corrupted invalid type\n",
                    NULL);
            xmlFreeEnumeration(tree);
            return(NULL);
     }
-    if ((defaultValue != NULL) && 
-        (!xmlValidateAttributeValue(type, defaultValue))) {
+    if ((defaultValue != NULL) &&
+        (!xmlValidateAttributeValueInternal(dtd->doc, type, defaultValue))) {
        xmlErrValidNode(ctxt, (xmlNodePtr) dtd, XML_DTD_ATTRIBUTE_DEFAULT,
                        "Attribute %s of %s: invalid default value\n",
                        elem, name, defaultValue);
@@ -2042,8 +1999,10 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
        (dtd->doc->intSubset != NULL) &&
        (dtd->doc->intSubset->attributes != NULL)) {
         ret = xmlHashLookup3(dtd->doc->intSubset->attributes, name, ns, elem);
-       if (ret != NULL)
+       if (ret != NULL) {
+           xmlFreeEnumeration(tree);
            return(NULL);
+       }
     }
 
     /*
@@ -2057,6 +2016,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
     if (table == NULL) {
        xmlVErrMemory(ctxt,
             "xmlAddAttributeDecl: Table creation failed!\n");
+       xmlFreeEnumeration(tree);
         return(NULL);
     }
 
@@ -2064,6 +2024,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt,
     ret = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute));
     if (ret == NULL) {
        xmlVErrMemory(ctxt, "malloc failed");
+       xmlFreeEnumeration(tree);
        return(NULL);
     }
     memset(ret, 0, sizeof(xmlAttribute));
@@ -2193,7 +2154,7 @@ xmlFreeAttributeTable(xmlAttributeTablePtr table) {
  * @attr:  An attribute
  *
  * Build a copy of an attribute.
- * 
+ *
  * Returns the new xmlAttributePtr or NULL in case of error.
  */
 static xmlAttributePtr
@@ -2226,7 +2187,7 @@ xmlCopyAttribute(xmlAttributePtr attr) {
  * @table:  An attribute table
  *
  * Build a copy of an attribute table.
- * 
+ *
  * Returns the new xmlAttributeTablePtr or NULL in case of error.
  */
 xmlAttributeTablePtr
@@ -2291,7 +2252,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
            xmlDumpEnumeration(buf, attr->tree);
            break;
        default:
-           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "Internal: ATTRIBUTE struct corrupted invalid type\n",
                    NULL);
     }
@@ -2308,7 +2269,7 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) {
            xmlBufferWriteChar(buf, " #FIXED");
            break;
        default:
-           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR, 
+           xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "Internal: ATTRIBUTE struct corrupted invalid def\n",
                    NULL);
     }
@@ -2438,7 +2399,7 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd,
      */
     if (xmlHashAddEntry(table, name, ret)) {
 #ifdef LIBXML_VALID_ENABLED
-       xmlErrValid(NULL, XML_DTD_NOTATION_REDEFINED, 
+       xmlErrValid(NULL, XML_DTD_NOTATION_REDEFINED,
                    "xmlAddNotationDecl: %s already defined\n",
                    (const char *) name);
 #endif /* LIBXML_VALID_ENABLED */
@@ -2465,7 +2426,7 @@ xmlFreeNotationTable(xmlNotationTablePtr table) {
  * @nota:  A notation
  *
  * Build a copy of a notation.
- * 
+ *
  * Returns the new xmlNotationPtr or NULL in case of error.
  */
 static xmlNotationPtr
@@ -2497,7 +2458,7 @@ xmlCopyNotation(xmlNotationPtr nota) {
  * @table:  A notation table
  *
  * Build a copy of a notation table.
- * 
+ *
  * Returns the new xmlNotationTablePtr or NULL in case of error.
  */
 xmlNotationTablePtr
@@ -2575,7 +2536,7 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
  * current scope
  */
 #define DICT_FREE(str)                                         \
-       if ((str) && ((!dict) ||                                \
+       if ((str) && ((!dict) ||                                \
            (xmlDictOwns(dict, (const xmlChar *)(str)) == 0)))  \
            xmlFree((char *)(str));
 
@@ -2613,7 +2574,7 @@ xmlFreeID(xmlIDPtr id) {
  *
  * Returns NULL if not, otherwise the new xmlIDPtr
  */
-xmlIDPtr 
+xmlIDPtr
 xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
          xmlAttrPtr attr) {
     xmlIDPtr ret;
@@ -2673,10 +2634,9 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
        /*
         * The id is already defined in this DTD.
         */
-       if ((ctxt != NULL) && (ctxt->error != NULL)) {
+       if (ctxt != NULL) {
            xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
-                           "ID %s already defined\n",
-                           value, NULL, NULL);
+                           "ID %s already defined\n", value, NULL, NULL);
        }
 #endif /* LIBXML_VALID_ENABLED */
        xmlFreeID(ret);
@@ -2719,14 +2679,15 @@ xmlIsID(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
         (!strcmp((char *) attr->ns->prefix, "xml")))
        return(1);
     if (doc == NULL) return(0);
-    if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
+    if ((doc->intSubset == NULL) && (doc->extSubset == NULL) &&
+        (doc->type != XML_HTML_DOCUMENT_NODE)) {
        return(0);
     } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
         if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
            ((xmlStrEqual(BAD_CAST "name", attr->name)) &&
-           ((elem == NULL) || (!xmlStrEqual(elem->name, BAD_CAST "input")))))
+           ((elem == NULL) || (xmlStrEqual(elem->name, BAD_CAST "a")))))
            return(1);
-       return(0);    
+       return(0);
     } else if (elem == NULL) {
        return(0);
     } else {
@@ -2779,23 +2740,24 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
 
     if (doc == NULL) return(-1);
     if (attr == NULL) return(-1);
+
     table = (xmlIDTablePtr) doc->ids;
-    if (table == NULL) 
+    if (table == NULL)
         return(-1);
 
-    if (attr == NULL)
-       return(-1);
     ID = xmlNodeListGetString(doc, attr->children, 1);
     if (ID == NULL)
-       return(-1);
+        return(-1);
+
     id = xmlHashLookup(table, ID);
     if (id == NULL || id->attr != attr) {
-       xmlFree(ID);
-       return(-1);
+        xmlFree(ID);
+        return(-1);
     }
+
     xmlHashRemoveEntry(table, ID, (xmlHashDeallocator) xmlFreeID);
     xmlFree(ID);
-       attr->atype = 0;
+    attr->atype = 0;
     return(0);
 }
 
@@ -2808,7 +2770,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
  *
  * Returns NULL if not found, otherwise the xmlAttrPtr defining the ID
  */
-xmlAttrPtr 
+xmlAttrPtr
 xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
     xmlIDTablePtr table;
     xmlIDPtr id;
@@ -2822,7 +2784,7 @@ xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
     }
 
     table = (xmlIDTablePtr) doc->ids;
-    if (table == NULL) 
+    if (table == NULL)
         return(NULL);
 
     id = xmlHashLookup(table, ID);
@@ -2843,7 +2805,7 @@ xmlGetID(xmlDocPtr doc, const xmlChar *ID) {
  *                             Refs                                    *
  *                                                                     *
  ************************************************************************/
-typedef struct xmlRemoveMemo_t 
+typedef struct xmlRemoveMemo_t
 {
        xmlListPtr l;
        xmlAttrPtr ap;
@@ -2851,7 +2813,7 @@ typedef struct xmlRemoveMemo_t
 
 typedef xmlRemoveMemo *xmlRemoveMemoPtr;
 
-typedef struct xmlValidateMemo_t 
+typedef struct xmlValidateMemo_t
 {
     xmlValidCtxtPtr ctxt;
     const xmlChar *name;
@@ -2934,7 +2896,7 @@ xmlDummyCompare(const void *data0 ATTRIBUTE_UNUSED,
  *
  * Returns NULL if not, otherwise the new xmlRefPtr
  */
-xmlRefPtr 
+xmlRefPtr
 xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
     xmlAttrPtr attr) {
     xmlRefPtr ret;
@@ -2998,19 +2960,32 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
            xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "xmlAddRef: Reference list creation failed!\n",
                    NULL);
-            return(NULL);
+           goto failed;
         }
         if (xmlHashAddEntry(table, value, ref_list) < 0) {
             xmlListDelete(ref_list);
            xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
                    "xmlAddRef: Reference list insertion failed!\n",
                    NULL);
-            return(NULL);
+           goto failed;
         }
     }
-/*    xmlListInsert(ref_list, ret); */
-    xmlListAppend(ref_list, ret);
+    if (xmlListAppend(ref_list, ret) != 0) {
+       xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+                   "xmlAddRef: Reference list insertion failed!\n",
+                   NULL);
+        goto failed;
+    }
     return(ret);
+failed:
+    if (ret != NULL) {
+        if (ret->value != NULL)
+           xmlFree((char *)ret->value);
+        if (ret->name != NULL)
+           xmlFree((char *)ret->name);
+        xmlFree(ret);
+    }
+    return(NULL);
 }
 
 /**
@@ -3049,7 +3024,7 @@ xmlIsRef(xmlDocPtr doc, xmlNodePtr elem, xmlAttrPtr attr) {
         return(0);
     } else if (doc->type == XML_HTML_DOCUMENT_NODE) {
         /* TODO @@@ */
-        return(0);    
+        return(0);
     } else {
         xmlAttributePtr attrDecl;
 
@@ -3085,21 +3060,21 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
 
     if (doc == NULL) return(-1);
     if (attr == NULL) return(-1);
+
     table = (xmlRefTablePtr) doc->refs;
-    if (table == NULL) 
+    if (table == NULL)
         return(-1);
 
-    if (attr == NULL)
-        return(-1);
     ID = xmlNodeListGetString(doc, attr->children, 1);
     if (ID == NULL)
         return(-1);
-    ref_list = xmlHashLookup(table, ID);
 
+    ref_list = xmlHashLookup(table, ID);
     if(ref_list == NULL) {
         xmlFree(ID);
         return (-1);
     }
+
     /* At this point, ref_list refers to a list of references which
      * have the same key as the supplied attr. Our list of references
      * is ordered by reference address and we don't have that information
@@ -3112,7 +3087,7 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
      */
     target.l = ref_list;
     target.ap = attr;
-    
+
     /* Remove the supplied attr from our list */
     xmlListWalk(ref_list, xmlWalkRemoveRef, &target);
 
@@ -3129,11 +3104,11 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
  * @doc:  pointer to the document
  * @ID:  the ID value
  *
- * Find the set of references for the supplied ID. 
+ * Find the set of references for the supplied ID.
  *
  * Returns NULL if not found, otherwise node set for the ID.
  */
-xmlListPtr 
+xmlListPtr
 xmlGetRefs(xmlDocPtr doc, const xmlChar *ID) {
     xmlRefTablePtr table;
 
@@ -3146,7 +3121,7 @@ xmlGetRefs(xmlDocPtr doc, const xmlChar *ID) {
     }
 
     table = (xmlRefTablePtr) doc->refs;
-    if (table == NULL) 
+    if (table == NULL)
         return(NULL);
 
     return (xmlHashLookup(table, ID));
@@ -3211,7 +3186,7 @@ xmlGetDtdElementDesc2(xmlDtdPtr dtd, const xmlChar *name, int create) {
        if (dtd->doc != NULL)
            dict = dtd->doc->dict;
 
-       if (!create) 
+       if (!create)
            return(NULL);
        /*
         * Create the Element table if needed.
@@ -3377,7 +3352,8 @@ int
 xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                        const xmlChar *notationName) {
     xmlNotationPtr notaDecl;
-    if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
+    if ((doc == NULL) || (doc->intSubset == NULL) ||
+        (notationName == NULL)) return(-1);
 
     notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
     if ((notaDecl == NULL) && (doc->extSubset != NULL))
@@ -3432,8 +3408,78 @@ xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
 }
 
 #ifdef LIBXML_VALID_ENABLED
+
+static int
+xmlIsDocNameStartChar(xmlDocPtr doc, int c) {
+    if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+        /*
+        * Use the new checks of production [4] [4a] amd [5] of the
+        * Update 5 of XML-1.0
+        */
+       if (((c >= 'a') && (c <= 'z')) ||
+           ((c >= 'A') && (c <= 'Z')) ||
+           (c == '_') || (c == ':') ||
+           ((c >= 0xC0) && (c <= 0xD6)) ||
+           ((c >= 0xD8) && (c <= 0xF6)) ||
+           ((c >= 0xF8) && (c <= 0x2FF)) ||
+           ((c >= 0x370) && (c <= 0x37D)) ||
+           ((c >= 0x37F) && (c <= 0x1FFF)) ||
+           ((c >= 0x200C) && (c <= 0x200D)) ||
+           ((c >= 0x2070) && (c <= 0x218F)) ||
+           ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+           ((c >= 0x3001) && (c <= 0xD7FF)) ||
+           ((c >= 0xF900) && (c <= 0xFDCF)) ||
+           ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+           ((c >= 0x10000) && (c <= 0xEFFFF)))
+           return(1);
+    } else {
+        if (IS_LETTER(c) || (c == '_') || (c == ':'))
+           return(1);
+    }
+    return(0);
+}
+
+static int
+xmlIsDocNameChar(xmlDocPtr doc, int c) {
+    if ((doc == NULL) || (doc->properties & XML_DOC_OLD10) == 0) {
+        /*
+        * Use the new checks of production [4] [4a] amd [5] of the
+        * Update 5 of XML-1.0
+        */
+       if (((c >= 'a') && (c <= 'z')) ||
+           ((c >= 'A') && (c <= 'Z')) ||
+           ((c >= '0') && (c <= '9')) || /* !start */
+           (c == '_') || (c == ':') ||
+           (c == '-') || (c == '.') || (c == 0xB7) || /* !start */
+           ((c >= 0xC0) && (c <= 0xD6)) ||
+           ((c >= 0xD8) && (c <= 0xF6)) ||
+           ((c >= 0xF8) && (c <= 0x2FF)) ||
+           ((c >= 0x300) && (c <= 0x36F)) || /* !start */
+           ((c >= 0x370) && (c <= 0x37D)) ||
+           ((c >= 0x37F) && (c <= 0x1FFF)) ||
+           ((c >= 0x200C) && (c <= 0x200D)) ||
+           ((c >= 0x203F) && (c <= 0x2040)) || /* !start */
+           ((c >= 0x2070) && (c <= 0x218F)) ||
+           ((c >= 0x2C00) && (c <= 0x2FEF)) ||
+           ((c >= 0x3001) && (c <= 0xD7FF)) ||
+           ((c >= 0xF900) && (c <= 0xFDCF)) ||
+           ((c >= 0xFDF0) && (c <= 0xFFFD)) ||
+           ((c >= 0x10000) && (c <= 0xEFFFF)))
+            return(1);
+    } else {
+        if ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
+            (c == '.') || (c == '-') ||
+           (c == '_') || (c == ':') ||
+           (IS_COMBINING(c)) ||
+           (IS_EXTENDER(c)))
+           return(1);
+    }
+    return(0);
+}
+
 /**
  * xmlValidateNameValue:
+ * @doc:  pointer to the document or NULL
  * @value:  an Name value
  *
  * Validate that the given value match Name production
@@ -3441,8 +3487,8 @@ xmlIsMixedElement(xmlDocPtr doc, const xmlChar *name) {
  * returns 1 if valid or 0 otherwise
  */
 
-int
-xmlValidateNameValue(const xmlChar *value) {
+static int
+xmlValidateNameValueInternal(xmlDocPtr doc, const xmlChar *value) {
     const xmlChar *cur;
     int val, len;
 
@@ -3450,18 +3496,12 @@ xmlValidateNameValue(const xmlChar *value) {
     cur = value;
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    if (!IS_LETTER(val) && (val != '_') &&
-        (val != ':')) {
+    if (!xmlIsDocNameStartChar(doc, val))
        return(0);
-    }
 
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-           (val == '.') || (val == '-') ||
-          (val == '_') || (val == ':') || 
-          (IS_COMBINING(val)) ||
-          (IS_EXTENDER(val))) {
+    while (xmlIsDocNameChar(doc, val)) {
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
     }
@@ -3472,7 +3512,22 @@ xmlValidateNameValue(const xmlChar *value) {
 }
 
 /**
- * xmlValidateNamesValue:
+ * xmlValidateNameValue:
+ * @value:  an Name value
+ *
+ * Validate that the given value match Name production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNameValue(const xmlChar *value) {
+    return(xmlValidateNameValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNamesValueInternal:
+ * @doc:  pointer to the document or NULL
  * @value:  an Names value
  *
  * Validate that the given value match Names production
@@ -3480,8 +3535,8 @@ xmlValidateNameValue(const xmlChar *value) {
  * returns 1 if valid or 0 otherwise
  */
 
-int
-xmlValidateNamesValue(const xmlChar *value) {
+static int
+xmlValidateNamesValueInternal(xmlDocPtr doc, const xmlChar *value) {
     const xmlChar *cur;
     int val, len;
 
@@ -3489,19 +3544,13 @@ xmlValidateNamesValue(const xmlChar *value) {
     cur = value;
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    
-    if (!IS_LETTER(val) && (val != '_') &&
-        (val != ':')) {
+
+    if (!xmlIsDocNameStartChar(doc, val))
        return(0);
-    }
 
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-           (val == '.') || (val == '-') ||
-          (val == '_') || (val == ':') || 
-          (IS_COMBINING(val)) ||
-          (IS_EXTENDER(val))) {
+    while (xmlIsDocNameChar(doc, val)) {
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
     }
@@ -3513,18 +3562,13 @@ xmlValidateNamesValue(const xmlChar *value) {
            cur += len;
        }
 
-       if (!IS_LETTER(val) && (val != '_') &&
-           (val != ':')) {
+       if (!xmlIsDocNameStartChar(doc, val))
            return(0);
-       }
+
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
 
-       while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-              (val == '.') || (val == '-') ||
-              (val == '_') || (val == ':') || 
-              (IS_COMBINING(val)) ||
-              (IS_EXTENDER(val))) {
+       while (xmlIsDocNameChar(doc, val)) {
            val = xmlStringCurrentChar(NULL, cur, &len);
            cur += len;
        }
@@ -3536,18 +3580,33 @@ xmlValidateNamesValue(const xmlChar *value) {
 }
 
 /**
- * xmlValidateNmtokenValue:
+ * xmlValidateNamesValue:
+ * @value:  an Names value
+ *
+ * Validate that the given value match Names production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNamesValue(const xmlChar *value) {
+    return(xmlValidateNamesValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNmtokenValueInternal:
+ * @doc:  pointer to the document or NULL
  * @value:  an Nmtoken value
  *
  * Validate that the given value match Nmtoken production
  *
  * [ VC: Name Token ]
- * 
+ *
  * returns 1 if valid or 0 otherwise
  */
 
-int
-xmlValidateNmtokenValue(const xmlChar *value) {
+static int
+xmlValidateNmtokenValueInternal(xmlDocPtr doc, const xmlChar *value) {
     const xmlChar *cur;
     int val, len;
 
@@ -3555,19 +3614,13 @@ xmlValidateNmtokenValue(const xmlChar *value) {
     cur = value;
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    
-    if (!IS_LETTER(val) && !IS_DIGIT(val) &&
-        (val != '.') && (val != '-') &&
-        (val != '_') && (val != ':') && 
-        (!IS_COMBINING(val)) &&
-        (!IS_EXTENDER(val)))
+
+    if (!xmlIsDocNameChar(doc, val))
        return(0);
 
-    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-           (val == '.') || (val == '-') ||
-          (val == '_') || (val == ':') || 
-          (IS_COMBINING(val)) ||
-          (IS_EXTENDER(val))) {
+    val = xmlStringCurrentChar(NULL, cur, &len);
+    cur += len;
+    while (xmlIsDocNameChar(doc, val)) {
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
     }
@@ -3578,18 +3631,35 @@ xmlValidateNmtokenValue(const xmlChar *value) {
 }
 
 /**
- * xmlValidateNmtokensValue:
+ * xmlValidateNmtokenValue:
+ * @value:  an Nmtoken value
+ *
+ * Validate that the given value match Nmtoken production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNmtokenValue(const xmlChar *value) {
+    return(xmlValidateNmtokenValueInternal(NULL, value));
+}
+
+/**
+ * xmlValidateNmtokensValueInternal:
+ * @doc:  pointer to the document or NULL
  * @value:  an Nmtokens value
  *
  * Validate that the given value match Nmtokens production
  *
  * [ VC: Name Token ]
- * 
+ *
  * returns 1 if valid or 0 otherwise
  */
 
-int
-xmlValidateNmtokensValue(const xmlChar *value) {
+static int
+xmlValidateNmtokensValueInternal(xmlDocPtr doc, const xmlChar *value) {
     const xmlChar *cur;
     int val, len;
 
@@ -3597,24 +3667,16 @@ xmlValidateNmtokensValue(const xmlChar *value) {
     cur = value;
     val = xmlStringCurrentChar(NULL, cur, &len);
     cur += len;
-    
+
     while (IS_BLANK(val)) {
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
     }
 
-    if (!IS_LETTER(val) && !IS_DIGIT(val) &&
-        (val != '.') && (val != '-') &&
-        (val != '_') && (val != ':') && 
-        (!IS_COMBINING(val)) &&
-        (!IS_EXTENDER(val)))
+    if (!xmlIsDocNameChar(doc, val))
        return(0);
 
-    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-           (val == '.') || (val == '-') ||
-          (val == '_') || (val == ':') || 
-          (IS_COMBINING(val)) ||
-          (IS_EXTENDER(val))) {
+    while (xmlIsDocNameChar(doc, val)) {
        val = xmlStringCurrentChar(NULL, cur, &len);
        cur += len;
     }
@@ -3627,18 +3689,13 @@ xmlValidateNmtokensValue(const xmlChar *value) {
        }
        if (val == 0) return(1);
 
-       if (!IS_LETTER(val) && !IS_DIGIT(val) &&
-           (val != '.') && (val != '-') &&
-           (val != '_') && (val != ':') && 
-           (!IS_COMBINING(val)) &&
-           (!IS_EXTENDER(val)))
+       if (!xmlIsDocNameChar(doc, val))
            return(0);
 
-       while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
-              (val == '.') || (val == '-') ||
-              (val == '_') || (val == ':') || 
-              (IS_COMBINING(val)) ||
-              (IS_EXTENDER(val))) {
+       val = xmlStringCurrentChar(NULL, cur, &len);
+       cur += len;
+
+       while (xmlIsDocNameChar(doc, val)) {
            val = xmlStringCurrentChar(NULL, cur, &len);
            cur += len;
        }
@@ -3650,6 +3707,22 @@ xmlValidateNmtokensValue(const xmlChar *value) {
 }
 
 /**
+ * xmlValidateNmtokensValue:
+ * @value:  an Nmtokens value
+ *
+ * Validate that the given value match Nmtokens production
+ *
+ * [ VC: Name Token ]
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+int
+xmlValidateNmtokensValue(const xmlChar *value) {
+    return(xmlValidateNmtokensValueInternal(NULL, value));
+}
+
+/**
  * xmlValidateNotationDecl:
  * @ctxt:  the validation context
  * @doc:  a document instance
@@ -3673,6 +3746,40 @@ xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATT
 }
 
 /**
+ * xmlValidateAttributeValueInternal:
+ * @doc: the document
+ * @type:  an attribute type
+ * @value:  an attribute value
+ *
+ * Validate that the given attribute value match  the proper production
+ *
+ * returns 1 if valid or 0 otherwise
+ */
+
+static int
+xmlValidateAttributeValueInternal(xmlDocPtr doc, xmlAttributeType type,
+                                  const xmlChar *value) {
+    switch (type) {
+       case XML_ATTRIBUTE_ENTITIES:
+       case XML_ATTRIBUTE_IDREFS:
+           return(xmlValidateNamesValueInternal(doc, value));
+       case XML_ATTRIBUTE_ENTITY:
+       case XML_ATTRIBUTE_IDREF:
+       case XML_ATTRIBUTE_ID:
+       case XML_ATTRIBUTE_NOTATION:
+           return(xmlValidateNameValueInternal(doc, value));
+       case XML_ATTRIBUTE_NMTOKENS:
+       case XML_ATTRIBUTE_ENUMERATION:
+           return(xmlValidateNmtokensValueInternal(doc, value));
+       case XML_ATTRIBUTE_NMTOKEN:
+           return(xmlValidateNmtokenValueInternal(doc, value));
+        case XML_ATTRIBUTE_CDATA:
+           break;
+    }
+    return(1);
+}
+
+/**
  * xmlValidateAttributeValue:
  * @type:  an attribute type
  * @value:  an attribute value
@@ -3692,31 +3799,13 @@ xmlValidateNotationDecl(xmlValidCtxtPtr ctxt ATTRIBUTE_UNUSED, xmlDocPtr doc ATT
  *
  * [ VC: Name Token ]
  * Values of type NMTOKEN must match the Nmtoken production; values
- * of type NMTOKENS must match Nmtokens. 
+ * of type NMTOKENS must match Nmtokens.
  *
  * returns 1 if valid or 0 otherwise
  */
-
 int
 xmlValidateAttributeValue(xmlAttributeType type, const xmlChar *value) {
-    switch (type) {
-       case XML_ATTRIBUTE_ENTITIES:
-       case XML_ATTRIBUTE_IDREFS:
-           return(xmlValidateNamesValue(value));
-       case XML_ATTRIBUTE_ENTITY:
-       case XML_ATTRIBUTE_IDREF:
-       case XML_ATTRIBUTE_ID:
-       case XML_ATTRIBUTE_NOTATION:
-           return(xmlValidateNameValue(value));
-       case XML_ATTRIBUTE_NMTOKENS:
-       case XML_ATTRIBUTE_ENUMERATION:
-           return(xmlValidateNmtokensValue(value));
-       case XML_ATTRIBUTE_NMTOKEN:
-           return(xmlValidateNmtokenValue(value));
-        case XML_ATTRIBUTE_CDATA:
-           break;
-    }
-    return(1);
+    return(xmlValidateAttributeValueInternal(NULL, type, value));
 }
 
 /**
@@ -3769,7 +3858,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
            if ((ent == NULL) && (doc->standalone == 1)) {
                doc->standalone = 0;
                ent = xmlGetDocEntity(doc, value);
-           } 
+           }
            if (ent == NULL) {
                xmlErrValidNode(ctxt, (xmlNodePtr) doc,
                                XML_DTD_UNKNOWN_ENTITY,
@@ -3880,7 +3969,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
        xmlChar fn[50];
        xmlChar *fullname;
-       
+
        fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
        if (fullname == NULL)
            return(NULL);
@@ -3965,13 +4054,10 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
     if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
        xmlChar fn[50];
        xmlChar *fullname;
-       
+
        fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
        if (fullname == NULL)
            return(NULL);
-       attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
-       if ((attrDecl == NULL) && (doc->extSubset != NULL))
-           attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
        if ((fullname != fn) && (fullname != elem->name))
            xmlFree(fullname);
     }
@@ -4034,11 +4120,12 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     int val;
     CHECK_DTD;
     if(attr == NULL) return(1);
-    
+
     /* Attribute Default Legal */
     /* Enumeration */
     if (attr->defaultValue != NULL) {
-       val = xmlValidateAttributeValue(attr->atype, attr->defaultValue);
+       val = xmlValidateAttributeValueInternal(doc, attr->atype,
+                                               attr->defaultValue);
        if (val == 0) {
            xmlErrValidNode(ctxt, (xmlNodePtr) attr, XML_DTD_ATTRIBUTE_DEFAULT,
               "Syntax of default value for attribute %s of %s is not valid\n",
@@ -4081,7 +4168,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
            }
        }
        if (nbId > 1) {
-           
+
            xmlErrValidNodeNr(ctxt, (xmlNodePtr) attr, XML_DTD_ID_SUBSET,
        "Element %s has %d ID attribute defined in the internal subset : %s\n",
                   attr->elem, nbId, attr->name);
@@ -4144,7 +4231,7 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     xmlElementPtr tst;
 
     CHECK_DTD;
-    
+
     if (elem == NULL) return(1);
 
 #if 0
@@ -4169,15 +4256,15 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                while (next != NULL) {
                    if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
                        if ((xmlStrEqual(next->name, name)) &&
-                           (xmlStrEqual(next->prefix, cur->prefix))) {
-                           if (cur->prefix == NULL) {
+                           (xmlStrEqual(next->prefix, cur->c1->prefix))) {
+                           if (cur->c1->prefix == NULL) {
                                xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
                   "Definition of %s has duplicate references of %s\n",
                                       elem->name, name, NULL);
                            } else {
                                xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
                   "Definition of %s has duplicate references of %s:%s\n",
-                                      elem->name, cur->prefix, name);
+                                      elem->name, cur->c1->prefix, name);
                            }
                            ret = 0;
                        }
@@ -4186,15 +4273,15 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                    if (next->c1 == NULL) break;
                    if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
                    if ((xmlStrEqual(next->c1->name, name)) &&
-                       (xmlStrEqual(next->c1->prefix, cur->prefix))) {
-                       if (cur->prefix == NULL) {
+                       (xmlStrEqual(next->c1->prefix, cur->c1->prefix))) {
+                       if (cur->c1->prefix == NULL) {
                            xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
               "Definition of %s has duplicate references to %s\n",
                                   elem->name, name, NULL);
                        } else {
                            xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
               "Definition of %s has duplicate references to %s:%s\n",
-                                  elem->name, cur->prefix, name);
+                                  elem->name, cur->c1->prefix, name);
                        }
                        ret = 0;
                    }
@@ -4261,7 +4348,7 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
 
 int
 xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
-                        xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value) 
+                        xmlNodePtr elem, xmlAttrPtr attr, const xmlChar *value)
 {
     xmlAttributePtr attrDecl =  NULL;
     int val;
@@ -4274,7 +4361,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
        xmlChar fn[50];
        xmlChar *fullname;
-       
+
        fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
        if (fullname == NULL)
            return(0);
@@ -4319,7 +4406,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     }
     attr->atype = attrDecl->atype;
 
-    val = xmlValidateAttributeValue(attrDecl->atype, value);
+    val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
     if (val == 0) {
            xmlErrValidNode(ctxt, elem, XML_DTD_ATTRIBUTE_VALUE,
           "Syntax of value for attribute %s of %s is not valid\n",
@@ -4358,7 +4445,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
        nota = xmlGetDtdNotationDesc(doc->intSubset, value);
        if (nota == NULL)
            nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-       
+
        if (nota == NULL) {
            xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_NOTATION,
        "Value \"%s\" for attribute %s of %s is not a declared Notation\n",
@@ -4451,7 +4538,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
     if (prefix != NULL) {
        xmlChar fn[50];
        xmlChar *fullname;
-       
+
        fullname = xmlBuildQName(elem->name, prefix, fn, 50);
        if (fullname == NULL) {
            xmlVErrMemory(ctxt, "Validating namespace");
@@ -4504,7 +4591,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
        return(0);
     }
 
-    val = xmlValidateAttributeValue(attrDecl->atype, value);
+    val = xmlValidateAttributeValueInternal(doc, attrDecl->atype, value);
     if (val == 0) {
        if (ns->prefix != NULL) {
            xmlErrValidNode(ctxt, elem, XML_DTD_INVALID_DEFAULT,
@@ -4555,7 +4642,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
        nota = xmlGetDtdNotationDesc(doc->intSubset, value);
        if (nota == NULL)
            nota = xmlGetDtdNotationDesc(doc->extSubset, value);
-       
+
        if (nota == NULL) {
            if (ns->prefix != NULL) {
                xmlErrValidNode(ctxt, elem, XML_DTD_UNKNOWN_NOTATION,
@@ -4691,7 +4778,7 @@ xmlValidateElementType(xmlValidCtxtPtr ctxt) {
     NODE = xmlValidateSkipIgnorable(NODE);
     if ((NODE == NULL) && (CONT == NULL))
        return(1);
-    if ((NODE == NULL) && 
+    if ((NODE == NULL) &&
        ((CONT->ocur == XML_ELEMENT_CONTENT_MULT) ||
         (CONT->ocur == XML_ELEMENT_CONTENT_OPT))) {
        return(1);
@@ -5150,7 +5237,7 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
     xmlElementContentPtr cont;
     const xmlChar *name;
 
-    if (elemDecl == NULL)
+    if ((elemDecl == NULL) || (parent == NULL) || (ctxt == NULL))
        return(-1);
     cont = elemDecl->content;
     name = elemDecl->name;
@@ -5200,7 +5287,7 @@ xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
                        if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
                            xmlChar fn[50];
                            xmlChar *fullname;
-                           
+
                            fullname = xmlBuildQName(cur->name,
                                                     cur->ns->prefix, fn, 50);
                            if (fullname == NULL) {
@@ -5314,7 +5401,7 @@ fail:
                        last = tmp;
                    }
                    if (cur->type == XML_CDATA_SECTION_NODE) {
-                       /* 
+                       /*
                         * E59 spaces in CDATA does not match the
                         * nonterminal S
                         */
@@ -5431,7 +5518,8 @@ xmlValidateOneCdataElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     int ret = 1;
     xmlNodePtr cur, child;
 
-    if ((ctxt == NULL) || (doc == NULL) || (elem == NULL))
+    if ((ctxt == NULL) || (doc == NULL) || (elem == NULL) ||
+        (elem->type != XML_ELEMENT_NODE))
        return(0);
 
     child = elem->children;
@@ -5512,7 +5600,7 @@ xmlValidateCheckMixed(xmlValidCtxtPtr ctxt,
            } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
                (cont->c1 == NULL) ||
                (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
-               xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT, 
+               xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT,
                        "Internal: MIXED struct corrupted\n",
                        NULL);
                break;
@@ -5536,7 +5624,7 @@ xmlValidateCheckMixed(xmlValidCtxtPtr ctxt,
            } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
                (cont->c1 == NULL) ||
                (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
-               xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT, 
+               xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT,
                        "Internal: MIXED struct corrupted\n",
                        NULL);
                break;
@@ -5565,7 +5653,7 @@ xmlValidGetElemDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     xmlElementPtr elemDecl = NULL;
     const xmlChar *prefix = NULL;
 
-    if ((ctxt == NULL) || (doc == NULL) || 
+    if ((ctxt == NULL) || (doc == NULL) ||
         (elem == NULL) || (elem->name == NULL))
         return(NULL);
     if (extsubset != NULL)
@@ -5709,7 +5797,7 @@ xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
  * xmlValidatePushCData:
  * @ctxt:  the validation context
  * @data:  some character data read
- * @len:  the lenght of the data
+ * @len:  the length of the data
  *
  * check the CData parsed for validation in the current stack
  *
@@ -5931,7 +6019,7 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
        return(0);
 
     /*
-     * If vstateNr is not zero that means continuous validation is 
+     * If vstateNr is not zero that means continuous validation is
      * activated, do not try to check the content model at that level.
      */
     if (ctxt->vstateNr == 0) {
@@ -5974,7 +6062,7 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                    if ((child->ns != NULL) && (child->ns->prefix != NULL)) {
                        xmlChar fn[50];
                        xmlChar *fullname;
-                       
+
                        fullname = xmlBuildQName(child->name, child->ns->prefix,
                                                 fn, 50);
                        if (fullname == NULL)
@@ -5992,7 +6080,7 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                            } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
                                (cont->c1 == NULL) ||
                                (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)){
-                               xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT, 
+                               xmlErrValid(NULL, XML_DTD_MIXED_CORRUPT,
                                        "Internal: MIXED struct corrupted\n",
                                        NULL);
                                break;
@@ -6015,7 +6103,7 @@ xmlValidateOneElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
                        } else if ((cont->type != XML_ELEMENT_CONTENT_OR) ||
                            (cont->c1 == NULL) ||
                            (cont->c1->type != XML_ELEMENT_CONTENT_PCDATA)) {
-                           xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT, 
+                           xmlErrValid(ctxt, XML_DTD_MIXED_CORRUPT,
                                    "Internal: MIXED struct corrupted\n",
                                    NULL);
                            break;
@@ -6095,7 +6183,7 @@ child_ok:
                }
            } else {
                xmlAttrPtr attrib;
-               
+
                attrib = elem->properties;
                while (attrib != NULL) {
                    if (xmlStrEqual(attrib->name, attr->name)) {
@@ -6110,18 +6198,18 @@ child_ok:
                             * allow to define the URI instead of the prefix :-(
                             */
                            if (nameSpace == NULL) {
-                               if (qualified < 0) 
+                               if (qualified < 0)
                                    qualified = 0;
                            } else if (!xmlStrEqual(nameSpace->prefix,
                                                    attr->prefix)) {
-                               if (qualified < 1) 
+                               if (qualified < 1)
                                    qualified = 1;
                            } else
                                goto found;
                        } else {
                            /*
                             * We should allow applications to define namespaces
-                            * for their application even if the DTD doesn't 
+                            * for their application even if the DTD doesn't
                             * carry one, otherwise, basically we would always
                             * break.
                             */
@@ -6194,7 +6282,7 @@ child_ok:
                }
            }
        }
-found:     
+found:
         attr = attr->nexth;
     }
     return(ret);
@@ -6241,7 +6329,7 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
            if ((root->ns != NULL) && (root->ns->prefix != NULL)) {
                xmlChar fn[50];
                xmlChar *fullname;
-               
+
                fullname = xmlBuildQName(root->name, root->ns->prefix, fn, 50);
                if (fullname == NULL) {
                    xmlVErrMemory(ctxt, NULL);
@@ -6252,7 +6340,7 @@ xmlValidateRoot(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
                    xmlFree(fullname);
                if (ret == 1)
                    goto name_ok;
-           } 
+           }
            if ((xmlStrEqual(doc->intSubset->name, BAD_CAST "HTML")) &&
                (xmlStrEqual(root->name, BAD_CAST "html")))
                goto name_ok;
@@ -6273,7 +6361,7 @@ name_ok:
  * @doc:  a document instance
  * @elem:  an element instance
  *
- * Try to validate the subtree under an element 
+ * Try to validate the subtree under an element
  *
  * returns 1 if valid or 0 otherwise
  */
@@ -6293,7 +6381,8 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) {
      * they don't really mean anything validation wise.
      */
     if ((elem->type == XML_XINCLUDE_START) ||
-       (elem->type == XML_XINCLUDE_END))
+       (elem->type == XML_XINCLUDE_END) ||
+       (elem->type == XML_NAMESPACE_DECL))
        return(1);
 
     CHECK_DTD;
@@ -6452,7 +6541,7 @@ xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt,
     memo.name = name;
 
     xmlListWalk(ref_list, xmlWalkValidateList, &memo);
-    
+
 }
 
 /**
@@ -6464,7 +6553,7 @@ xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt,
  * incremental validation steps have been completed
  *
  * basically it does the following checks described by the XML Rec
- * 
+ *
  * Check all the IDREF/IDREFS attributes definition for validity
  *
  * returns 1 if valid or 0 otherwise
@@ -6473,15 +6562,20 @@ xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt,
 int
 xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
     xmlRefTablePtr table;
+    unsigned int save;
 
     if (ctxt == NULL)
         return(0);
     if (doc == NULL) {
-        xmlErrValid(ctxt, XML_DTD_NO_DOC, 
+        xmlErrValid(ctxt, XML_DTD_NO_DOC,
                "xmlValidateDocumentFinal: doc == NULL\n", NULL);
        return(0);
     }
 
+    /* trick to get correct line id report */
+    save = ctxt->finishDtd;
+    ctxt->finishDtd = 0;
+
     /*
      * Check all the NOTATION/NOTATIONS attributes
      */
@@ -6495,6 +6589,8 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
     ctxt->doc = doc;
     ctxt->valid = 1;
     xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
+
+    ctxt->finishDtd = save;
     return(ctxt->valid);
 }
 
@@ -6589,7 +6685,7 @@ xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
        case XML_ATTRIBUTE_ENTITIES:
        case XML_ATTRIBUTE_NOTATION:
            if (cur->defaultValue != NULL) {
-               
+
                ret = xmlValidateAttributeValue2(ctxt, ctxt->doc, cur->name,
                                                 cur->atype, cur->defaultValue);
                if ((ret == 0) && (ctxt->valid == 1))
@@ -6646,9 +6742,9 @@ xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt,
  * subsets have been parsed
  *
  * basically it does the following checks described by the XML Rec
- * - check that ENTITY and ENTITIES type attributes default or 
+ * - check that ENTITY and ENTITIES type attributes default or
  *   possible values matches one of the defined entities.
- * - check that NOTATION type attributes default or 
+ * - check that NOTATION type attributes default or
  *   possible values matches one of the defined notations.
  *
  * returns 1 if valid or 0 if invalid and -1 if not well-formed
@@ -6660,7 +6756,7 @@ xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
     xmlAttributeTablePtr table;
     xmlEntitiesTablePtr entities;
 
-    if (doc == NULL) return(0);
+    if ((doc == NULL) || (ctxt == NULL)) return(0);
     if ((doc->intSubset == NULL) && (doc->extSubset == NULL))
        return(0);
     ctxt->doc = doc;
@@ -6719,7 +6815,7 @@ xmlValidateDocument(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
        xmlChar *sysID;
        if (doc->intSubset->SystemID != NULL) {
            sysID = xmlBuildURI(doc->intSubset->SystemID,
-                       doc->URL);
+                       doc->URL);
            if (sysID == NULL) {
                xmlErrValid(ctxt, XML_DTD_LOAD_ERROR,
                        "Could not build URI for external subset \"%s\"\n",
@@ -6792,17 +6888,17 @@ xmlValidGetPotentialChildren(xmlElementContent *ctree,
     if (*len >= max) return(*len);
 
     switch (ctree->type) {
-       case XML_ELEMENT_CONTENT_PCDATA: 
+       case XML_ELEMENT_CONTENT_PCDATA:
            for (i = 0; i < *len;i++)
                if (xmlStrEqual(BAD_CAST "#PCDATA", names[i])) return(*len);
            names[(*len)++] = BAD_CAST "#PCDATA";
            break;
-       case XML_ELEMENT_CONTENT_ELEMENT: 
+       case XML_ELEMENT_CONTENT_ELEMENT:
            for (i = 0; i < *len;i++)
                if (xmlStrEqual(ctree->name, names[i])) return(*len);
            names[(*len)++] = ctree->name;
            break;
-       case XML_ELEMENT_CONTENT_SEQ: 
+       case XML_ELEMENT_CONTENT_SEQ:
            xmlValidGetPotentialChildren(ctree->c1, names, len, max);
            xmlValidGetPotentialChildren(ctree->c2, names, len, max);
            break;
@@ -6811,7 +6907,7 @@ xmlValidGetPotentialChildren(xmlElementContent *ctree,
            xmlValidGetPotentialChildren(ctree->c2, names, len, max);
            break;
    }
-   
+
    return(*len);
 }
 
@@ -6853,19 +6949,19 @@ xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **names,
                          int max) {
     xmlValidCtxt vctxt;
     int nb_valid_elements = 0;
-    const xmlChar *elements[256];
+    const xmlChar *elements[256]={0};
     int nb_elements = 0, i;
     const xmlChar *name;
-    
+
     xmlNode *ref_node;
     xmlNode *parent;
     xmlNode *test_node;
-    
+
     xmlNode *prev_next;
     xmlNode *next_prev;
     xmlNode *parent_childs;
     xmlNode *parent_last;
-    
+
     xmlElement *element_desc;
 
     if (prev == NULL && next == NULL)
@@ -6890,7 +6986,7 @@ xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **names,
         element_desc = xmlGetDtdElementDesc(parent->doc->extSubset,
                                              parent->name);
     if (element_desc == NULL) return(-1);
-       
+
     /*
      * Do a backup of the current tree structure
      */
@@ -6901,16 +6997,19 @@ xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **names,
 
     /*
      * Creates a dummy node and insert it into the tree
-     */    
+     */
     test_node = xmlNewDocNode (ref_node->doc, NULL, BAD_CAST "<!dummy?>", NULL);
+    if (test_node == NULL)
+        return(-1);
+
     test_node->parent = parent;
     test_node->prev = prev;
     test_node->next = next;
     name = test_node->name;
-    
+
     if (prev) prev->next = test_node;
     else parent->children = test_node;
-               
+
     if (next) next->prev = test_node;
     else parent->last = test_node;
 
@@ -6920,7 +7019,7 @@ xmlValidGetValidElements(xmlNode *prev, xmlNode *next, const xmlChar **names,
      */
     nb_elements = xmlValidGetPotentialChildren(element_desc->content,
                       elements, &nb_elements, 256);
-    
+
     for (i = 0;i < nb_elements;i++) {
        test_node->name = elements[i];
        if (xmlValidateOneElement(&vctxt, parent->doc, parent)) {