git diff 74f3154320df8950eceae4951975cc9dfc3a254d 9fb54d0a629b44e0f0c08eafb083458711c79ffe

diff --git a/SAX2.c b/SAX2.c
index b5c2e476..0f54b7f5 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -1184,8 +1184,19 @@ xmlSAX1Attribute(xmlParserCtxtPtr ctxt, const xmlChar *fullname,
                 xmlFree(val);
 	    }
 	} else {
+            /*
+             * When replacing entities, make sure that IDs in
+             * entities aren't registered. This also shouldn't be
+             * done when entities aren't replaced, but this would
+             * require to rework IDREF checks.
+             */
+            if (ctxt->input->entity != NULL)
+                ctxt->vctxt.flags |= XML_VCTXT_IN_ENTITY;
+
 	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt, ctxt->myDoc,
 					       ctxt->node, ret, value);
+
+            ctxt->vctxt.flags &= ~XML_VCTXT_IN_ENTITY;
 	}
     } else
 #endif /* LIBXML_VALID_ENABLED */
@@ -2052,8 +2063,19 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
             if (dup == NULL)
                 xmlSAX2ErrMemory(ctxt);
 
+            /*
+             * When replacing entities, make sure that IDs in
+             * entities aren't registered. This also shouldn't be
+             * done when entities aren't replaced, but this would
+             * require to rework IDREF checks.
+             */
+            if (ctxt->input->entity != NULL)
+                ctxt->vctxt.flags |= XML_VCTXT_IN_ENTITY;
+
 	    ctxt->valid &= xmlValidateOneAttribute(&ctxt->vctxt,
 	                             ctxt->myDoc, ctxt->node, ret, dup);
+
+            ctxt->vctxt.flags &= ~XML_VCTXT_IN_ENTITY;
 	}
     } else
 #endif /* LIBXML_VALID_ENABLED */
diff --git a/globals.c b/globals.c
index e0b05a24..a4c72e7e 100644
--- a/globals.c
+++ b/globals.c
@@ -18,6 +18,7 @@
 #include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/xmlIO.h>
+#include <libxml/HTMLparser.h>
 #include <libxml/parser.h>
 #include <libxml/threads.h>
 #include <libxml/tree.h>
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
index 00446bc5..cd40561d 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -139,7 +139,6 @@ typedef struct _xmlHashTable xmlRefTable;
 typedef xmlRefTable *xmlRefTablePtr;
 
 /* Notation */
-XML_DEPRECATED
 XMLPUBFUN xmlNotationPtr
 		xmlAddNotationDecl	(xmlValidCtxtPtr ctxt,
 					 xmlDtdPtr dtd,
@@ -204,7 +203,6 @@ XMLPUBFUN void
 #endif /* LIBXML_OUTPUT_ENABLED */
 
 /* Element */
-XML_DEPRECATED
 XMLPUBFUN xmlElementPtr
 		xmlAddElementDecl	(xmlValidCtxtPtr ctxt,
 					 xmlDtdPtr dtd,
@@ -240,7 +238,6 @@ XMLPUBFUN xmlEnumerationPtr
 		xmlCopyEnumeration	(xmlEnumerationPtr cur);
 
 /* Attribute */
-XML_DEPRECATED
 XMLPUBFUN xmlAttributePtr
 		xmlAddAttributeDecl	(xmlValidCtxtPtr ctxt,
 					 xmlDtdPtr dtd,
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 743d8213..cefd8f71 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -20,7 +20,7 @@ extern "C" {
  * Backward compatibility
  */
 #define initGenericErrorDefaultFunc(h) \
-    xmlSetGenericErrorFunc(NULL, (h) ? *(h) : NULL)
+    xmlSetGenericErrorFunc(NULL, (h) ? *((xmlGenericErrorFunc *) (h)) : NULL)
 
 /**
  * xmlErrorLevel:
diff --git a/include/private/parser.h b/include/private/parser.h
index d5f2fef9..3e7fa59a 100644
--- a/include/private/parser.h
+++ b/include/private/parser.h
@@ -20,6 +20,10 @@
  * Set if the validation context is part of a parser context.
  */
 #define XML_VCTXT_USE_PCTXT (1u << 1)
+/**
+ * Set when parsing entities.
+ */
+#define XML_VCTXT_IN_ENTITY (1u << 3)
 
 /*
  * TODO: Rename to avoid confusion with xmlParserInputFlags
diff --git a/parser.c b/parser.c
index e482d7f2..cdfa90c0 100644
--- a/parser.c
+++ b/parser.c
@@ -413,7 +413,7 @@ xmlSaturatedAdd(unsigned long *dst, unsigned long val) {
 }
 
 static void
-xmlSaturatedAddSizeT(unsigned long *dst, unsigned long val) {
+xmlSaturatedAddSizeT(unsigned long *dst, size_t val) {
     if (val > ULONG_MAX - *dst)
         *dst = ULONG_MAX;
     else
diff --git a/testparser.c b/testparser.c
index 1bb7684d..86130efe 100644
--- a/testparser.c
+++ b/testparser.c
@@ -188,7 +188,8 @@ testInvalidCharRecovery(void) {
     xmlDoc *doc;
     int err = 0;
 
-    doc = xmlReadDoc(BAD_CAST xml, NULL, NULL, XML_PARSE_RECOVER);
+    doc = xmlReadDoc(BAD_CAST xml, NULL, NULL,
+                     XML_PARSE_RECOVER | XML_PARSE_NOERROR);
 
     if (strcmp((char *) doc->children->children->content, "\x10") != 0) {
         fprintf(stderr, "Failed to recover from invalid char ref\n");
diff --git a/tree.c b/tree.c
index 2e8df00b..ddb8bdb3 100644
--- a/tree.c
+++ b/tree.c
@@ -1892,8 +1892,8 @@ xmlFreeProp(xmlAttrPtr cur) {
 	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
 
     /* Check for ID removal -> leading to invalid references ! */
-    if ((cur->doc != NULL) && (cur->atype == XML_ATTRIBUTE_ID)) {
-	    xmlRemoveID(cur->doc, cur);
+    if (cur->doc != NULL && cur->id != NULL) {
+        xmlRemoveID(cur->doc, cur);
     }
     if (cur->children != NULL) xmlFreeNodeList(cur->children);
     DICT_FREE(cur->name)
@@ -2736,7 +2736,7 @@ xmlNodeSetDoc(xmlNodePtr node, xmlDocPtr doc) {
              * TODO: ID attributes should also be added to the new
              * document, but it's not clear how to handle clashes.
              */
-            if (attr->atype == XML_ATTRIBUTE_ID)
+            if (attr->id != NULL)
                 xmlRemoveID(oldDoc, attr);
 
             break;
@@ -6919,7 +6919,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
                 return(NULL);
         }
 
-	if (prop->atype == XML_ATTRIBUTE_ID) {
+	if (prop->id != NULL) {
 	    xmlRemoveID(node->doc, prop);
 	    prop->atype = XML_ATTRIBUTE_ID;
 	}
diff --git a/valid.c b/valid.c
index 34b6757c..d54e20f7 100644
--- a/valid.c
+++ b/valid.c
@@ -1139,8 +1139,6 @@ xmlFreeElement(xmlElementPtr elem) {
  * @type:  the element type
  * @content:  the element content tree or NULL
  *
- * DEPRECATED: Internal function, don't use.
- *
  * Register a new element declaration
  *
  * Returns NULL if not, otherwise the entity
@@ -1651,8 +1649,6 @@ xmlFreeAttribute(xmlAttributePtr attr) {
  * @defaultValue:  the attribute default value
  * @tree:  if it's an enumeration, the associated list
  *
- * DEPRECATED: Internal function, don't use.
- *
  * Register a new attribute declaration
  * Note that @tree becomes the ownership of the DTD
  *
@@ -2064,8 +2060,6 @@ xmlFreeNotation(xmlNotationPtr nota) {
  * @PublicID:  the public identifier or NULL
  * @SystemID:  the system identifier or NULL
  *
- * DEPRECATED: Internal function, don't use.
- *
  * Register a new notation declaration
  *
  * Returns NULL if not, otherwise the entity
@@ -4296,7 +4290,7 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
 	       attr->name, elem->name, NULL);
 	return(0);
     }
-    if (attr->atype == XML_ATTRIBUTE_ID)
+    if (attr->id != NULL)
         xmlRemoveID(doc, attr);
     attr->atype = attrDecl->atype;
 
@@ -4319,7 +4313,8 @@ xmlValidateOneAttribute(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
     }
 
     /* Validity Constraint: ID uniqueness */
-    if (attrDecl->atype == XML_ATTRIBUTE_ID) {
+    if (attrDecl->atype == XML_ATTRIBUTE_ID &&
+        (ctxt == NULL || (ctxt->flags & XML_VCTXT_IN_ENTITY) == 0)) {
         if (xmlAddID(ctxt, doc, value, attr) == NULL)
 	    ret = 0;
     }
diff --git a/xmlIO.c b/xmlIO.c
index 4c58d81f..0ef19677 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -1037,6 +1037,32 @@ xmlIODefaultMatch(const char *filename ATTRIBUTE_UNUSED) {
     return(1);
 }
 
+#if defined(LIBXML_LZMA_ENABLED) || defined(LIBXML_ZLIB_ENABLED)
+
+#ifdef _WIN32
+typedef __int64 xmlFileOffset;
+#else
+typedef off_t xmlFileOffset;
+#endif
+
+static xmlFileOffset
+xmlSeek(int fd, xmlFileOffset offset, int whence) {
+#ifdef _WIN32
+    HANDLE h = (HANDLE) _get_osfhandle(fd);
+
+    /*
+     * Windows doesn't return an error on unseekable files like pipes.
+     */
+    if (h != INVALID_HANDLE_VALUE && GetFileType(h) != FILE_TYPE_DISK)
+        return -1;
+    return _lseeki64(fd, offset, whence);
+#else
+    return lseek(fd, offset, whence);
+#endif
+}
+
+#endif /* defined(LIBXML_LZMA_ENABLED) || defined(LIBXML_ZLIB_ENABLED) */
+
 /**
  * xmlInputFromFd:
  * @buf:  parser input buffer
@@ -1059,9 +1085,9 @@ xmlInputFromFd(xmlParserInputBufferPtr buf, int fd,
 #ifdef LIBXML_LZMA_ENABLED
     if (flags & XML_INPUT_UNZIP) {
         xzFile xzStream;
-        off_t pos;
+        xmlFileOffset pos;
 
-        pos = lseek(fd, 0, SEEK_CUR);
+        pos = xmlSeek(fd, 0, SEEK_CUR);
 
         copy = dup(fd);
         if (copy == -1)
@@ -1077,7 +1103,7 @@ xmlInputFromFd(xmlParserInputBufferPtr buf, int fd,
             if ((compressed) ||
                 /* Try to rewind if not gzip compressed */
                 (pos < 0) ||
-                (lseek(fd, pos, SEEK_SET) < 0)) {
+                (xmlSeek(fd, pos, SEEK_SET) < 0)) {
                 /*
                  * If a file isn't seekable, we pipe uncompressed
                  * input through xzlib.
@@ -1098,9 +1124,9 @@ xmlInputFromFd(xmlParserInputBufferPtr buf, int fd,
 #ifdef LIBXML_ZLIB_ENABLED
     if (flags & XML_INPUT_UNZIP) {
         gzFile gzStream;
-        off_t pos;
+        xmlFileOffset pos;
 
-        pos = lseek(fd, 0, SEEK_CUR);
+        pos = xmlSeek(fd, 0, SEEK_CUR);
 
         copy = dup(fd);
         if (copy == -1)
@@ -1116,7 +1142,7 @@ xmlInputFromFd(xmlParserInputBufferPtr buf, int fd,
             if ((compressed) ||
                 /* Try to rewind if not gzip compressed */
                 (pos < 0) ||
-                (lseek(fd, pos, SEEK_SET) < 0)) {
+                (xmlSeek(fd, pos, SEEK_SET) < 0)) {
                 /*
                  * If a file isn't seekable, we pipe uncompressed
                  * input through zlib.
diff --git a/xmlregexp.c b/xmlregexp.c
index 9d36c172..5f46db2a 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -416,14 +416,17 @@ static int xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt);
  */
 static void*
 xmlRegCalloc2(size_t dim1, size_t dim2, size_t elemSize) {
-    size_t totalSize;
+    size_t numElems, totalSize;
     void *ret;
 
     /* Check for overflow */
     if ((dim2 == 0) || (elemSize == 0) ||
         (dim1 > SIZE_MAX / dim2 / elemSize))
         return (NULL);
-    totalSize = dim1 * dim2 * elemSize;
+    numElems = dim1 * dim2;
+    if (numElems > XML_MAX_ITEMS)
+        return NULL;
+    totalSize = numElems * elemSize;
     ret = xmlMalloc(totalSize);
     if (ret != NULL)
         memset(ret, 0, totalSize);
