Update to libxml2 2.9.4 by merging commit 'd8083bf7' into klp-dev.

Bug: 32956747
Change-Id: I04c5bdea11733cc8dab6244f4a1bf33f0ff66277
(cherry-picked from 312a2fc2f0200bbb187771f25e08ed5afd447e40)
diff --git a/HTMLparser.c b/HTMLparser.c
index dd0c1ea..d1395fa 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -105,7 +105,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -132,7 +132,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, int val)
 {
@@ -303,6 +303,7 @@
 #define UPP(val) (toupper(ctxt->input->cur[(val)]))
 
 #define CUR_PTR ctxt->input->cur
+#define BASE_PTR ctxt->input->base
 
 #define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
 		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
@@ -1177,7 +1178,7 @@
     "onfocus",
     "onblur",
     "onsubmit",
-    "onrest",
+    "onreset",
     "onchange",
     "onselect"
 };
@@ -2471,6 +2472,10 @@
 	       (*in == '_') || (*in == '-') ||
 	       (*in == ':') || (*in == '.'))
 	    in++;
+
+	if (in == ctxt->input->end)
+	    return(NULL);
+
 	if ((*in > 0) && (*in < 0x80)) {
 	    count = in - ctxt->input->cur;
 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
@@ -2488,6 +2493,7 @@
     int len = 0, l;
     int c;
     int count = 0;
+    const xmlChar *base = ctxt->input->base;
 
     /*
      * Handler for more complex cases
@@ -2513,7 +2519,18 @@
 	len += l;
 	NEXTL(l);
 	c = CUR_CHAR(l);
+	if (ctxt->input->base != base) {
+	    /*
+	     * We changed encoding from an unknown encoding
+	     * Input buffer changed location, so we better start again
+	     */
+	    return(htmlParseNameComplex(ctxt));
+	}
     }
+
+    if (ctxt->input->base > ctxt->input->cur - len)
+	return(NULL);
+
     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
 }
 
@@ -2765,31 +2782,43 @@
 
 static xmlChar *
 htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
-    const xmlChar *q;
+    size_t len = 0, startPosition = 0;
     xmlChar *ret = NULL;
 
     if (CUR == '"') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"')) {
 	    NEXT;
+	    len++;
+	}
 	if (!IS_CHAR_CH(CUR)) {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 			 "Unfinished SystemLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
 	    NEXT;
         }
     } else if (CUR == '\'') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) {
 	    NEXT;
+	    len++;
+	}
 	if (!IS_CHAR_CH(CUR)) {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 			 "Unfinished SystemLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
 	    NEXT;
         }
     } else {
@@ -2813,32 +2842,47 @@
 
 static xmlChar *
 htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
-    const xmlChar *q;
+    size_t len = 0, startPosition = 0;
     xmlChar *ret = NULL;
     /*
      * Name ::= (Letter | '_') (NameChar)*
      */
     if (CUR == '"') {
         NEXT;
-	q = CUR_PTR;
-	while (IS_PUBIDCHAR_CH(CUR)) NEXT;
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+        while (IS_PUBIDCHAR_CH(CUR)) {
+            len++;
+            NEXT;
+        }
+
 	if (CUR != '"') {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
 	    NEXT;
 	}
     } else if (CUR == '\'') {
         NEXT;
-	q = CUR_PTR;
-	while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\''))
-	    NEXT;
+
+        if (CUR_PTR < BASE_PTR)
+            return(ret);
+        startPosition = CUR_PTR - BASE_PTR;
+
+        while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')){
+            len++;
+            NEXT;
+        }
+
 	if (CUR != '\'') {
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
 	} else {
-	    ret = xmlStrndup(q, CUR_PTR - q);
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
 	    NEXT;
 	}
     } else {
@@ -2948,8 +2992,9 @@
 
 
 /**
- * htmlParseCharData:
+ * htmlParseCharDataInternal:
  * @ctxt:  an HTML parser context
+ * @readahead: optional read ahead character in ascii range
  *
  * parse a CharData section.
  * if we are within a CDATA section ']]>' marks an end of section.
@@ -2958,12 +3003,15 @@
  */
 
 static void
-htmlParseCharData(htmlParserCtxtPtr ctxt) {
-    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
+htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
+    xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 6];
     int nbchar = 0;
     int cur, l;
     int chunk = 0;
 
+    if (readahead)
+        buf[nbchar++] = readahead;
+
     SHRINK;
     cur = CUR_CHAR(l);
     while (((cur != '<') || (ctxt->token == '<')) &&
@@ -3043,6 +3091,21 @@
 }
 
 /**
+ * htmlParseCharData:
+ * @ctxt:  an HTML parser context
+ *
+ * parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+static void
+htmlParseCharData(htmlParserCtxtPtr ctxt) {
+    htmlParseCharDataInternal(ctxt, 0);
+}
+
+/**
  * htmlParseExternalID:
  * @ctxt:  an HTML parser context
  * @publicID:  a xmlChar** receiving PubidLiteral
@@ -3245,12 +3308,17 @@
 	ctxt->instate = state;
 	return;
     }
+    len = 0;
+    buf[len] = 0;
     q = CUR_CHAR(ql);
+    if (!IS_CHAR(q))
+        goto unfinished;
     NEXTL(ql);
     r = CUR_CHAR(rl);
+    if (!IS_CHAR(r))
+        goto unfinished;
     NEXTL(rl);
     cur = CUR_CHAR(l);
-    len = 0;
     while (IS_CHAR(cur) &&
            ((cur != '>') ||
 	    (r != '-') || (q != '-'))) {
@@ -3281,18 +3349,20 @@
 	}
     }
     buf[len] = 0;
-    if (!IS_CHAR(cur)) {
-	htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
-	             "Comment not terminated \n<!--%.50s\n", buf, NULL);
-	xmlFree(buf);
-    } else {
+    if (IS_CHAR(cur)) {
         NEXT;
 	if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
 	    (!ctxt->disableSAX))
 	    ctxt->sax->comment(ctxt->userData, buf);
 	xmlFree(buf);
+	ctxt->instate = state;
+	return;
     }
-    ctxt->instate = state;
+
+unfinished:
+    htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+		 "Comment not terminated \n<!--%.50s\n", buf, NULL);
+    xmlFree(buf);
 }
 
 /**
@@ -3671,13 +3741,13 @@
     int i;
     int discardtag = 0;
 
-    if (ctxt->instate == XML_PARSER_EOF)
-        return(-1);
     if ((ctxt == NULL) || (ctxt->input == NULL)) {
 	htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
 		     "htmlParseStartTag: context error\n", NULL, NULL);
 	return -1;
     }
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(-1);
     if (CUR != '<') return -1;
     NEXT;
 
@@ -3690,6 +3760,14 @@
 	htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
 	             "htmlParseStartTag: invalid element name\n",
 		     NULL, NULL);
+	/* if recover preserve text on classic misconstructs */
+	if ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') ||
+	    (CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) {
+	    htmlParseCharDataInternal(ctxt, '<');
+	    return(-1);
+	}
+
+
 	/* Dump the bogus tag like browsers do */
 	while ((IS_CHAR_CH(CUR)) && (CUR != '>') &&
                (ctxt->instate != XML_PARSER_EOF))
@@ -4366,7 +4444,7 @@
 htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
     const xmlChar *name;
     const htmlElemDesc * info;
-    htmlParserNodeInfo node_info;
+    htmlParserNodeInfo node_info = { 0, };
     int failed;
 
     if ((ctxt == NULL) || (ctxt->input == NULL)) {
@@ -5701,17 +5779,17 @@
 				if (ctxt->keepBlanks) {
 				    if (ctxt->sax->characters != NULL)
 					ctxt->sax->characters(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				} else {
 				    if (ctxt->sax->ignorableWhitespace != NULL)
 					ctxt->sax->ignorableWhitespace(
-						ctxt->userData, &cur, 1);
+						ctxt->userData, &in->cur[0], 1);
 				}
 			    } else {
 				htmlCheckParagraph(ctxt);
 				if (ctxt->sax->characters != NULL)
 				    ctxt->sax->characters(
-					    ctxt->userData, &cur, 1);
+					    ctxt->userData, &in->cur[0], 1);
 			    }
 			}
 			ctxt->token = 0;
@@ -5991,7 +6069,7 @@
 		ctxt->sax->endDocument(ctxt->userData);
 	}
     }
-    if ((ctxt->myDoc != NULL) &&
+    if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL) &&
 	((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
 	 (ctxt->instate == XML_PARSER_EPILOG))) {
 	xmlDtdPtr dtd;
@@ -6288,12 +6366,16 @@
 
     /* set encoding */
     if (encoding) {
-        content = xmlMallocAtomic (xmlStrlen(content_line) + strlen(encoding) + 1);
-	if (content) {
-	    strcpy ((char *)content, (char *)content_line);
-            strcat ((char *)content, (char *)encoding);
-            htmlCheckEncoding (ctxt, content);
-	    xmlFree (content);
+        size_t l = strlen(encoding);
+
+	if (l < 1000) {
+	    content = xmlMallocAtomic (xmlStrlen(content_line) + l + 1);
+	    if (content) {
+		strcpy ((char *)content, (char *)content_line);
+		strcat ((char *)content, (char *)encoding);
+		htmlCheckEncoding (ctxt, content);
+		xmlFree (content);
+	    }
 	}
     }
 
@@ -6499,7 +6581,7 @@
  * DICT_FREE:
  * @str:  a string
  *
- * Free a string if it is not owned by the "dict" dictionnary in the
+ * Free a string if it is not owned by the "dict" dictionary in the
  * current scope
  */
 #define DICT_FREE(str)						\
@@ -6808,6 +6890,7 @@
 
     if (fd < 0)
         return (NULL);
+    xmlInitParser();
 
     xmlInitParser();
     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
@@ -6898,6 +6981,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     htmlCtxtReset(ctxt);
 
@@ -6931,6 +7015,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     htmlCtxtReset(ctxt);
 
@@ -6967,6 +7052,7 @@
         return (NULL);
     if (buffer == NULL)
         return (NULL);
+    xmlInitParser();
 
     htmlCtxtReset(ctxt);
 
@@ -7009,6 +7095,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     htmlCtxtReset(ctxt);
 
@@ -7053,6 +7140,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     htmlCtxtReset(ctxt);
 
diff --git a/HTMLtree.c b/HTMLtree.c
index 4d8e354..2fd0c9c 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -668,7 +668,8 @@
 	    xmlOutputBufferWriteString(buf, " ");
 	    xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
 	}
-    }  else if (cur->SystemID != NULL) {
+    } else if (cur->SystemID != NULL &&
+	       xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
 	xmlOutputBufferWriteString(buf, " SYSTEM ");
 	xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
     }
@@ -716,22 +717,49 @@
 		 (!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
 		 ((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
 		  (!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
-		xmlChar *escaped;
 		xmlChar *tmp = value;
+		/* xmlURIEscapeStr() escapes '"' so it can be safely used. */
+		xmlBufCCat(buf->buffer, "\"");
 
 		while (IS_BLANK_CH(*tmp)) tmp++;
 
-		/*
-		 * the < and > have already been escaped at the entity level
-		 * And doing so here breaks server side includes
-		 */
-		escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
-		if (escaped != NULL) {
-		    xmlBufWriteQuotedString(buf->buffer, escaped);
-		    xmlFree(escaped);
-		} else {
-		    xmlBufWriteQuotedString(buf->buffer, value);
+		/* URI Escape everything, except server side includes. */
+		for ( ; ; ) {
+		    xmlChar *escaped;
+		    xmlChar endChar;
+		    xmlChar *end = NULL;
+		    xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST "<!--");
+		    if (start != NULL) {
+			end = (xmlChar *)xmlStrstr(tmp, BAD_CAST "-->");
+			if (end != NULL) {
+			    *start = '\0';
+			}
+		    }
+
+		    /* Escape the whole string, or until start (set to '\0'). */
+		    escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
+		    if (escaped != NULL) {
+		        xmlBufCat(buf->buffer, escaped);
+		        xmlFree(escaped);
+		    } else {
+		        xmlBufCat(buf->buffer, tmp);
+		    }
+
+		    if (end == NULL) { /* Everything has been written. */
+			break;
+		    }
+
+		    /* Do not escape anything within server side includes. */
+		    *start = '<'; /* Restore the first character of "<!--". */
+		    end += 3; /* strlen("-->") */
+		    endChar = *end;
+		    *end = '\0';
+		    xmlBufCat(buf->buffer, start);
+		    *end = endChar;
+		    tmp = end;
 		}
+
+		xmlBufCCat(buf->buffer, "\"");
 	    } else {
 		xmlBufWriteQuotedString(buf->buffer, value);
 	    }
diff --git a/SAX2.c b/SAX2.c
index 4adf202..5cbb700 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -55,7 +55,7 @@
  * @ctxt:  an XML validation parser context
  * @msg:   a string to accompany the error message
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) {
     xmlStructuredErrorFunc schannel = NULL;
     const char *str1 = "out of memory\n";
@@ -93,7 +93,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const char *str1, const char *str2)
 {
@@ -133,7 +133,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -164,7 +164,7 @@
  *
  * Handle a parser warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg, const xmlChar *str1)
 {
@@ -189,7 +189,7 @@
  *
  * Handle a namespace error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -213,7 +213,7 @@
  *
  * Handle a namespace warning
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
              const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -994,12 +994,12 @@
 #ifdef LIBXML_HTML_ENABLED
 	if (ctxt->myDoc == NULL)
 	    ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
-	ctxt->myDoc->properties = XML_DOC_HTML;
-	ctxt->myDoc->parseFlags = ctxt->options;
 	if (ctxt->myDoc == NULL) {
 	    xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
 	    return;
 	}
+	ctxt->myDoc->properties = XML_DOC_HTML;
+	ctxt->myDoc->parseFlags = ctxt->options;
 #else
         xmlGenericError(xmlGenericErrorContext,
 		"libxml2 built without HTML support\n");
@@ -1078,7 +1078,7 @@
     }
 }
 
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 /**
  * xmlSAX2AttributeInternal:
  * @ctx: the user data (XML parser context)
@@ -1177,6 +1177,12 @@
 	    val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
 		                          0,0,0);
 	    ctxt->depth--;
+	    if (val == NULL) {
+	        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+		if (name != NULL)
+		    xmlFree(name);
+		return;
+	    }
 	} else {
 	    val = (xmlChar *) value;
 	}
@@ -1822,7 +1828,7 @@
 #endif
     nodePop(ctxt);
 }
-#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
+#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
 
 /*
  * xmlSAX2TextNode:
@@ -2145,6 +2151,7 @@
 	     */
 	    if (dup == NULL)
 	        dup = xmlStrndup(value, valueend - value);
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef LIBXML_VALID_ENABLED
 	    if (xmlValidateNCName(dup, 1) != 0) {
 	        xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
@@ -2152,6 +2159,7 @@
 			    (const char *) dup, NULL);
 	    }
 #endif
+#endif
 	    xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
 	} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
 	    /* might be worth duplicate entry points and not copy */
@@ -2570,6 +2578,10 @@
 	               (xmlDictOwns(ctxt->dict, lastChild->content))) {
 		lastChild->content = xmlStrdup(lastChild->content);
 	    }
+	    if (lastChild->content == NULL) {
+		xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
+		return;
+ 	    }
             if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
                 ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                 xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
diff --git a/buf.c b/buf.c
index d1756c4..07922ff 100644
--- a/buf.c
+++ b/buf.c
@@ -27,6 +27,7 @@
 #include <libxml/tree.h>
 #include <libxml/globals.h>
 #include <libxml/tree.h>
+#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
 #include "buf.h"
 
 #define WITH_BUFFER_COMPAT
@@ -299,7 +300,8 @@
     if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
         (scheme == XML_BUFFER_ALLOC_EXACT) ||
         (scheme == XML_BUFFER_ALLOC_HYBRID) ||
-        (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) {
+        (scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
+	(scheme == XML_BUFFER_ALLOC_BOUNDED)) {
 	buf->alloc = scheme;
         if (buf->buffer)
             buf->buffer->alloc = scheme;
@@ -458,6 +460,18 @@
     size = buf->use + len + 100;
 #endif
 
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+        /*
+	 * Used to provide parsing limits
+	 */
+        if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
+	    (buf->size >= XML_MAX_TEXT_LENGTH)) {
+	    xmlBufMemoryError(buf, "buffer error: text too long\n");
+	    return(0);
+	}
+	if (size >= XML_MAX_TEXT_LENGTH)
+	    size = XML_MAX_TEXT_LENGTH;
+    }
     if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
         size_t start_buf = buf->content - buf->contentIO;
 
@@ -565,7 +579,7 @@
  */
 
 xmlChar *
-xmlBufContent(const xmlBufPtr buf)
+xmlBufContent(const xmlBuf *buf)
 {
     if ((!buf) || (buf->error))
         return NULL;
@@ -583,7 +597,7 @@
  */
 
 xmlChar *
-xmlBufEnd(const xmlBufPtr buf)
+xmlBufEnd(xmlBufPtr buf)
 {
     if ((!buf) || (buf->error))
         return NULL;
@@ -739,6 +753,15 @@
     CHECK_COMPAT(buf)
 
     if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
+    if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+        /*
+	 * Used to provide parsing limits
+	 */
+        if (size >= XML_MAX_TEXT_LENGTH) {
+	    xmlBufMemoryError(buf, "buffer error: text too long\n");
+	    return(0);
+	}
+    }
 
     /* Don't resize if we don't have to */
     if (size < buf->size)
@@ -867,6 +890,15 @@
 
     needSize = buf->use + len + 2;
     if (needSize > buf->size){
+	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+	    /*
+	     * Used to provide parsing limits
+	     */
+	    if (needSize >= XML_MAX_TEXT_LENGTH) {
+		xmlBufMemoryError(buf, "buffer error: text too long\n");
+		return(-1);
+	    }
+	}
         if (!xmlBufResize(buf, needSize)){
 	    xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
@@ -938,6 +970,15 @@
     }
     needSize = buf->use + len + 2;
     if (needSize > buf->size){
+	if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+	    /*
+	     * Used to provide parsing limits
+	     */
+	    if (needSize >= XML_MAX_TEXT_LENGTH) {
+		xmlBufMemoryError(buf, "buffer error: text too long\n");
+		return(-1);
+	    }
+	}
         if (!xmlBufResize(buf, needSize)){
 	    xmlBufMemoryError(buf, "growing buffer");
             return XML_ERR_NO_MEMORY;
diff --git a/buf.h b/buf.h
index e8c7715..ebdc978 100644
--- a/buf.h
+++ b/buf.h
@@ -50,8 +50,8 @@
 int xmlBufAddLen(xmlBufPtr buf, size_t len);
 int xmlBufErase(xmlBufPtr buf, size_t len);
 
-/* const xmlChar * xmlBufContent(const xmlBufPtr buf); */
-/* const xmlChar * xmlBufEnd(const xmlBufPtr buf); */
+/* const xmlChar * xmlBufContent(const xmlBuf *buf); */
+/* const xmlChar * xmlBufEnd(xmlBufPtr buf); */
 
 xmlChar * xmlBufDetach(xmlBufPtr buf);
 
diff --git a/c14n.c b/c14n.c
index afd95b3..ca77f92 100644
--- a/c14n.c
+++ b/c14n.c
@@ -547,14 +547,15 @@
     if (ns->prefix != NULL) {
         xmlOutputBufferWriteString(ctx->buf, " xmlns:");
         xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
-        xmlOutputBufferWriteString(ctx->buf, "=\"");
+        xmlOutputBufferWriteString(ctx->buf, "=");
     } else {
-        xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");
+        xmlOutputBufferWriteString(ctx->buf, " xmlns=");
     }
     if(ns->href != NULL) {
-	xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
+	xmlBufWriteQuotedString(ctx->buf->buffer, ns->href);
+    } else {
+    	xmlOutputBufferWriteString(ctx->buf, "\"\"");
     }
-    xmlOutputBufferWriteString(ctx->buf, "\"");
     return (1);
 }
 
diff --git a/catalog.c b/catalog.c
index 8e34cd2..6dfdfbb 100644
--- a/catalog.c
+++ b/catalog.c
@@ -47,9 +47,9 @@
 #define MAX_CATAL_DEPTH	50
 
 #ifdef _WIN32
-# define PATH_SEAPARATOR ';'
+# define PATH_SEPARATOR ';'
 #else
-# define PATH_SEAPARATOR ':'
+# define PATH_SEPARATOR ':'
 #endif
 
 /**
@@ -238,7 +238,7 @@
  *
  * Handle a catalog error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error,
                const char *msg, const xmlChar *str1, const xmlChar *str2,
 	       const xmlChar *str3)
@@ -994,6 +994,11 @@
     content = (xmlChar*)xmlMallocAtomic(size + 10);
     if (content == NULL) {
         xmlCatalogErrMemory("allocating catalog data");
+#ifdef HAVE_STAT
+	close(fd);
+#else
+	fclose(fd);
+#endif
         return (NULL);
     }
 #ifdef HAVE_STAT
@@ -3242,7 +3247,7 @@
 	while (xmlIsBlank_ch(*cur)) cur++;
 	if (*cur != 0) {
 	    paths = cur;
-	    while ((*cur != 0) && (*cur != PATH_SEAPARATOR) && (!xmlIsBlank_ch(*cur)))
+	    while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur)))
 		cur++;
 	    path = xmlStrndup((const xmlChar *)paths, cur - paths);
 #ifdef _WIN32
@@ -3258,7 +3263,7 @@
 		xmlFree(path);
 	    }
 	}
-	while (*cur == PATH_SEAPARATOR)
+	while (*cur == PATH_SEPARATOR)
 	    cur++;
     }
 }
@@ -3550,8 +3555,8 @@
 		xmlGenericError(xmlGenericErrorContext,
 			"Setting catalog preference to SYSTEM\n");
 		break;
-	    case XML_CATA_PREFER_NONE:
-		break;
+	    default:
+		return(ret);
 	}
     }
     xmlCatalogDefaultPrefer = prefer;
diff --git a/config.h b/config.h
index df227b0..7449acd 100644
--- a/config.h
+++ b/config.h
@@ -1,5 +1,8 @@
 /* config.h.  Generated from config.h.in by configure.  */
-/* config.h.in.  Generated from configure.in by autoheader.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Type cast for the gethostbyname() argument */
+#define GETHOSTBYNAME_ARG_CAST /**/
 
 /* Define to 1 if you have the <ansidecl.h> header file. */
 /* #undef HAVE_ANSIDECL_H */
@@ -154,7 +157,7 @@
 #define HAVE_RAND 1
 
 /* Define to 1 if you have the `rand_r' function. */
-// #define HAVE_RAND_R 1
+/* #undef HAVE_RAND_R */
 
 /* Define to 1 if you have the <resolv.h> header file. */
 #define HAVE_RESOLV_H 1
@@ -261,7 +264,7 @@
 #define HAVE_VSPRINTF 1
 
 /* Define to 1 if you have the <zlib.h> header file. */
-/* #undef HAVE_ZLIB_H */
+/* #undef HAVE_ZLIB_H */ /* Because otherwise LIBXML_ZLIB_ENABLED is ignored! */
 
 /* Define to 1 if you have the `_stat' function. */
 /* #undef HAVE__STAT */
@@ -297,14 +300,20 @@
 /* Define to the version of this package. */
 #define PACKAGE_VERSION ""
 
+/* Type cast for the send() function 2nd arg */
+#define SEND_ARG2_CAST /**/
+
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Support for IPv6 */
 #define SUPPORT_IP6 /**/
 
+/* Define if va_list is an array type */
+#define VA_LIST_IS_ARRAY 1
+
 /* Version number of package */
-#define VERSION "2.9.1"
+#define VERSION "2.9.2"
 
 /* Determine what socket length (socklen_t) data type is */
 #define XML_SOCKLEN_T socklen_t
diff --git a/debugXML.c b/debugXML.c
index c8efe6a..a1b550a 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -44,10 +44,10 @@
     int depth;                  /* current depth */
     xmlDocPtr doc;              /* current document */
     xmlNodePtr node;		/* current node */
-    xmlDictPtr dict;		/* the doc dictionnary */
+    xmlDictPtr dict;		/* the doc dictionary */
     int check;                  /* do just checkings */
     int errors;                 /* number of errors found */
-    int nodict;			/* if the document has no dictionnary */
+    int nodict;			/* if the document has no dictionary */
     int options;		/* options */
 };
 
@@ -164,7 +164,7 @@
 		    NULL, NULL, NULL, 0, 0,
 		    "%s", msg);
 }
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra)
 {
     ctxt->errors++;
@@ -174,7 +174,7 @@
 		    NULL, NULL, NULL, 0, 0,
 		    msg, extra);
 }
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra)
 {
     ctxt->errors++;
@@ -243,7 +243,7 @@
  * @ctxt: the debug context
  * @name: the name
  *
- * Do debugging on the name, for example the dictionnary status and
+ * Do debugging on the name, for example the dictionary status and
  * conformance to the Name production.
  */
 static void
@@ -254,16 +254,18 @@
 	    xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
 	    return;
 	}
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
         if (xmlValidateName(name, 0)) {
 	    xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
 			 "Name is not an NCName '%s'", (const char *) name);
 	}
+#endif
 	if ((ctxt->dict != NULL) &&
 	    (!xmlDictOwns(ctxt->dict, name)) &&
             ((ctxt->doc == NULL) ||
              ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) {
 	    xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT,
-			 "Name is not from the document dictionnary '%s'",
+			 "Name is not from the document dictionary '%s'",
 			 (const char *) name);
 	}
     }
@@ -290,7 +292,7 @@
             /* desactivated right now as it raises too many errors */
 	    if (doc->type == XML_DOCUMENT_NODE)
 		xmlDebugErr(ctxt, XML_CHECK_NO_DICT,
-			    "Document has no dictionnary\n");
+			    "Document has no dictionary\n");
 #endif
 	    ctxt->nodict = 1;
 	}
@@ -2946,7 +2948,7 @@
         } else if (!strcmp(command, "save")) {
             xmlShellSave(ctxt, arg, NULL, NULL);
         } else if (!strcmp(command, "write")) {
-	    if ((arg == NULL) || (arg[0] == 0))
+	    if (arg[0] == 0)
 		xmlGenericError(xmlGenericErrorContext,
                         "Write command requires a filename argument\n");
 	    else
@@ -3241,7 +3243,12 @@
                 ctxt->node = (xmlNodePtr) ctxt->doc;
             } else {
 #ifdef LIBXML_XPATH_ENABLED
+                int l;
+
                 ctxt->pctxt->node = ctxt->node;
+		l = strlen(arg);
+		if ((l >= 2) && (arg[l - 1] == '/'))
+		    arg[l - 1] = 0;
                 list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
 #else
                 list = NULL;
diff --git a/dict.c b/dict.c
index 5f71d55..c0585fe 100644
--- a/dict.c
+++ b/dict.c
@@ -87,7 +87,7 @@
 #endif /* WITH_BIG_KEY */
 
 /*
- * An entry in the dictionnary
+ * An entry in the dictionary
  */
 typedef struct _xmlDictEntry xmlDictEntry;
 typedef xmlDictEntry *xmlDictEntryPtr;
@@ -110,7 +110,7 @@
     xmlChar array[1];
 };
 /*
- * The entire dictionnary
+ * The entire dictionary
  */
 struct _xmlDict {
     int ref_counter;
@@ -229,7 +229,7 @@
 
 /*
  * xmlDictAddString:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @name: the name of the userdata
  * @len: the length of the name
  *
@@ -291,7 +291,7 @@
 
 /*
  * xmlDictAddQString:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @prefix: the prefix of the userdata
  * @plen: the prefix length
  * @name: the name of the userdata
@@ -486,7 +486,10 @@
 	value += 30 * (*prefix);
 
     if (len > 10) {
-        value += name[len - (plen + 1 + 1)];
+        int offset = len - (plen + 1 + 1);
+	if (offset < 0)
+	    offset = len - (10 + 1);
+	value += name[offset];
         len = 10;
 	if (plen > 10)
 	    plen = 10;
@@ -530,7 +533,7 @@
  *
  * Create a new dictionary
  *
- * Returns the newly created dictionnary, or NULL if an error occured.
+ * Returns the newly created dictionary, or NULL if an error occured.
  */
 xmlDictPtr
 xmlDictCreate(void) {
@@ -570,14 +573,14 @@
 
 /**
  * xmlDictCreateSub:
- * @sub: an existing dictionnary
+ * @sub: an existing dictionary
  *
  * Create a new dictionary, inheriting strings from the read-only
- * dictionnary @sub. On lookup, strings are first searched in the
- * new dictionnary, then in @sub, and if not found are created in the
- * new dictionnary.
+ * dictionary @sub. On lookup, strings are first searched in the
+ * new dictionary, then in @sub, and if not found are created in the
+ * new dictionary.
  *
- * Returns the newly created dictionnary, or NULL if an error occured.
+ * Returns the newly created dictionary, or NULL if an error occured.
  */
 xmlDictPtr
 xmlDictCreateSub(xmlDictPtr sub) {
@@ -596,7 +599,7 @@
 
 /**
  * xmlDictReference:
- * @dict: the dictionnary
+ * @dict: the dictionary
  *
  * Increment the reference counter of a dictionary
  *
@@ -617,10 +620,10 @@
 
 /**
  * xmlDictGrow:
- * @dict: the dictionnary
- * @size: the new size of the dictionnary
+ * @dict: the dictionary
+ * @size: the new size of the dictionary
  *
- * resize the dictionnary
+ * resize the dictionary
  *
  * Returns 0 in case of success, -1 in case of failure
  */
@@ -752,7 +755,7 @@
 
 /**
  * xmlDictFree:
- * @dict: the dictionnary
+ * @dict: the dictionary
  *
  * Free the hash @dict and its contents. The userdata is
  * deallocated with @f if provided.
@@ -814,11 +817,11 @@
 
 /**
  * xmlDictLookup:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @name: the name of the userdata
  * @len: the length of the name, if -1 it is recomputed
  *
- * Add the @name to the dictionnary @dict if not present.
+ * Add the @name to the dictionary @dict if not present.
  *
  * Returns the internal copy of the name or NULL in case of internal error
  */
@@ -954,11 +957,11 @@
 
 /**
  * xmlDictExists:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @name: the name of the userdata
  * @len: the length of the name, if -1 it is recomputed
  *
- * Check if the @name exists in the dictionnary @dict.
+ * Check if the @name exists in the dictionary @dict.
  *
  * Returns the internal copy of the name or NULL if not found.
  */
@@ -1062,7 +1065,7 @@
 
 /**
  * xmlDictQLookup:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @prefix: the prefix
  * @name: the name
  *
@@ -1167,7 +1170,7 @@
 
 /**
  * xmlDictOwns:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @str: the string
  *
  * check if a string is owned by the disctionary
@@ -1194,11 +1197,11 @@
 
 /**
  * xmlDictSize:
- * @dict: the dictionnary
+ * @dict: the dictionary
  *
  * Query the number of elements installed in the hash @dict.
  *
- * Returns the number of elements in the dictionnary or
+ * Returns the number of elements in the dictionary or
  * -1 in case of error
  */
 int
@@ -1212,7 +1215,7 @@
 
 /**
  * xmlDictSetLimit:
- * @dict: the dictionnary
+ * @dict: the dictionary
  * @limit: the limit in bytes
  *
  * Set a size limit for the dictionary
@@ -1233,7 +1236,7 @@
 
 /**
  * xmlDictGetUsage:
- * @dict: the dictionnary
+ * @dict: the dictionary
  *
  * Get how much memory is used by a dictionary for strings
  * Added in 2.9.0
diff --git a/elfgcchack.h b/elfgcchack.h
index 85c49d6..8c52884 100644
--- a/elfgcchack.h
+++ b/elfgcchack.h
@@ -1061,7 +1061,7 @@
 #endif
 #endif
 
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
 #ifdef bottom_tree
 #undef xmlAddPrevSibling
 extern __typeof (xmlAddPrevSibling) xmlAddPrevSibling __attribute((alias("xmlAddPrevSibling__internal_alias")));
@@ -8885,7 +8885,7 @@
 #endif
 #endif
 
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef bottom_SAX2
 #undef xmlSAX2EndElement
 extern __typeof (xmlSAX2EndElement) xmlSAX2EndElement __attribute((alias("xmlSAX2EndElement__internal_alias")));
@@ -9131,7 +9131,7 @@
 #endif
 #endif
 
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef bottom_SAX2
 #undef xmlSAX2StartElement
 extern __typeof (xmlSAX2StartElement) xmlSAX2StartElement __attribute((alias("xmlSAX2StartElement__internal_alias")));
@@ -15363,7 +15363,7 @@
 #endif
 #endif
 
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef bottom_tree
 #undef xmlValidateNCName
 extern __typeof (xmlValidateNCName) xmlValidateNCName __attribute((alias("xmlValidateNCName__internal_alias")));
@@ -16769,6 +16769,18 @@
 
 #if defined(LIBXML_XPATH_ENABLED)
 #ifdef bottom_xpath
+#undef xmlXPathNodeEval
+extern __typeof (xmlXPathNodeEval) xmlXPathNodeEval __attribute((alias("xmlXPathNodeEval__internal_alias")));
+#else
+#ifndef xmlXPathNodeEval
+extern __typeof (xmlXPathNodeEval) xmlXPathNodeEval__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeEval xmlXPathNodeEval__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
 #undef xmlXPathNodeLeading
 extern __typeof (xmlXPathNodeLeading) xmlXPathNodeLeading __attribute((alias("xmlXPathNodeLeading__internal_alias")));
 #else
@@ -17273,6 +17285,18 @@
 
 #if defined(LIBXML_XPATH_ENABLED)
 #ifdef bottom_xpath
+#undef xmlXPathSetContextNode
+extern __typeof (xmlXPathSetContextNode) xmlXPathSetContextNode __attribute((alias("xmlXPathSetContextNode__internal_alias")));
+#else
+#ifndef xmlXPathSetContextNode
+extern __typeof (xmlXPathSetContextNode) xmlXPathSetContextNode__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSetContextNode xmlXPathSetContextNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
 #undef xmlXPathStartsWithFunction
 extern __typeof (xmlXPathStartsWithFunction) xmlXPathStartsWithFunction __attribute((alias("xmlXPathStartsWithFunction__internal_alias")));
 #else
diff --git a/encoding.c b/encoding.c
index 7330e90..e49c7f8 100644
--- a/encoding.c
+++ b/encoding.c
@@ -93,7 +93,7 @@
  *
  * n encoding error
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val)
 {
     __xmlRaiseError(NULL, NULL, NULL, NULL, NULL,
@@ -2384,6 +2384,7 @@
     return (written? written : ret);
 }
 
+#ifdef LIBXML_OUTPUT_ENABLED
 /**
  * xmlCharEncOutput:
  * @output: a parser output buffer
@@ -2612,6 +2613,7 @@
     }
     return(ret);
 }
+#endif
 
 /**
  * xmlCharEncOutFunc:
@@ -2851,14 +2853,25 @@
 xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
     int ret = 0;
     int tofree = 0;
+    int i, handler_in_list = 0;
+
     if (handler == NULL) return(-1);
     if (handler->name == NULL) return(-1);
+    if (handlers != NULL) {
+        for (i = 0;i < nbCharEncodingHandler; i++) {
+            if (handler == handlers[i]) {
+	        handler_in_list = 1;
+		break;
+	    }
+	}
+    }
 #ifdef LIBXML_ICONV_ENABLED
     /*
      * Iconv handlers can be used only once, free the whole block.
      * and the associated icon resources.
      */
-    if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
+    if ((handler_in_list == 0) &&
+        ((handler->iconv_out != NULL) || (handler->iconv_in != NULL))) {
         tofree = 1;
 	if (handler->iconv_out != NULL) {
 	    if (iconv_close(handler->iconv_out))
@@ -2873,7 +2886,8 @@
     }
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
-    if ((handler->uconv_out != NULL) || (handler->uconv_in != NULL)) {
+    if ((handler_in_list == 0) &&
+        ((handler->uconv_out != NULL) || (handler->uconv_in != NULL))) {
         tofree = 1;
 	if (handler->uconv_out != NULL) {
 	    closeIcuConverter(handler->uconv_out);
diff --git a/entities.c b/entities.c
index 0c484a7..64808ff 100644
--- a/entities.c
+++ b/entities.c
@@ -83,7 +83,7 @@
  *
  * Handle an out of memory condition
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlEntitiesErr(xmlParserErrors code, const char *msg)
 {
     __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL);
@@ -502,7 +502,7 @@
  * Returns A pointer to the entity structure or NULL if not found.
  */
 xmlEntityPtr
-xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
+xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name) {
     xmlEntityPtr cur;
     xmlEntitiesTablePtr table;
 
@@ -783,7 +783,7 @@
  * Returns A newly allocated string with the substitution done.
  */
 xmlChar *
-xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input) {
     const xmlChar *cur = input;
     xmlChar *buffer = NULL;
     xmlChar *out = NULL;
diff --git a/error.c b/error.c
index cbcf5c9..9606f13 100644
--- a/error.c
+++ b/error.c
@@ -18,7 +18,7 @@
 
 void XMLCDECL xmlGenericErrorDefaultFunc	(void *ctx ATTRIBUTE_UNUSED,
 				 const char *msg,
-				 ...);
+				 ...) LIBXML_ATTR_FORMAT(2,3);
 
 #define XML_GET_VAR_STR(msg, str) {				\
     int       size, prev_size = -1;				\
@@ -177,7 +177,9 @@
     xmlChar  content[81]; /* space for 80 chars + line terminator */
     xmlChar *ctnt;
 
-    if (input == NULL) return;
+    if ((input == NULL) || (input->cur == NULL))
+        return;
+
     cur = input->cur;
     base = input->base;
     /* skip backwards over any end-of-lines */
diff --git a/hash.c b/hash.c
index 0145109..f9a2017 100644
--- a/hash.c
+++ b/hash.c
@@ -984,6 +984,9 @@
 	return(NULL);
 
     ret = xmlHashCreate(table->size);
+    if (ret == NULL)
+        return(NULL);
+
     if (table->table) {
 	for(i = 0; i < table->size; i++) {
 	    if (table->table[i].valid == 0)
diff --git a/include/libxml/SAX2.h b/include/libxml/SAX2.h
index daafd17..a55212e 100644
--- a/include/libxml/SAX2.h
+++ b/include/libxml/SAX2.h
@@ -98,7 +98,9 @@
 		xmlSAX2StartDocument		(void *ctx);
 XMLPUBFUN void XMLCALL
 		xmlSAX2EndDocument		(void *ctx);
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+    defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || \
+    defined(LIBXML_LEGACY_ENABLED)
 XMLPUBFUN void XMLCALL
 		xmlSAX2StartElement		(void *ctx,
 						 const xmlChar *fullname,
@@ -106,7 +108,7 @@
 XMLPUBFUN void XMLCALL
 		xmlSAX2EndElement		(void *ctx,
 						 const xmlChar *name);
-#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED */
+#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED or LIBXML_LEGACY_ENABLED */
 XMLPUBFUN void XMLCALL
 		xmlSAX2StartElementNs		(void *ctx,
 						 const xmlChar *localname,
diff --git a/include/libxml/dict.h b/include/libxml/dict.h
index 7022ec8..b83db59 100644
--- a/include/libxml/dict.h
+++ b/include/libxml/dict.h
@@ -1,5 +1,5 @@
 /*
- * Summary: string dictionnary
+ * Summary: string dictionary
  * Description: dictionary of reusable strings, just used to avoid allocation
  *         and freeing operations.
  *
@@ -11,6 +11,18 @@
 #ifndef __XML_DICT_H__
 #define __XML_DICT_H__
 
+#ifdef __cplusplus
+#define __XML_EXTERNC	extern "C"
+#else
+#define __XML_EXTERNC
+#endif
+
+/*
+ * The dictionary.
+ */
+__XML_EXTERNC typedef struct _xmlDict xmlDict;
+__XML_EXTERNC typedef xmlDict *xmlDictPtr;
+
 #include <limits.h>
 #include <libxml/xmlversion.h>
 #include <libxml/tree.h>
@@ -20,12 +32,6 @@
 #endif
 
 /*
- * The dictionnary.
- */
-typedef struct _xmlDict xmlDict;
-typedef xmlDict *xmlDictPtr;
-
-/*
  * Initializer
  */
 XMLPUBFUN int XMLCALL  xmlInitializeDict(void);
@@ -48,7 +54,7 @@
 			xmlDictFree	(xmlDictPtr dict);
 
 /*
- * Lookup of entry in the dictionnary.
+ * Lookup of entry in the dictionary.
  */
 XMLPUBFUN const xmlChar * XMLCALL
 			xmlDictLookup	(xmlDictPtr dict,
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index 1e91189..47b4573 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -57,7 +57,7 @@
     const xmlChar           *URI;	/* the full URI as computed */
     int                    owner;	/* does the entity own the childrens */
     int			 checked;	/* was the entity content checked */
-					/* this is also used to count entites
+					/* this is also used to count entities
 					 * references done from that entity
 					 * and if it contains '<' */
 };
@@ -103,7 +103,7 @@
 XMLPUBFUN xmlEntityPtr XMLCALL
 			xmlGetPredefinedEntity	(const xmlChar *name);
 XMLPUBFUN xmlEntityPtr XMLCALL
-			xmlGetDocEntity		(xmlDocPtr doc,
+			xmlGetDocEntity		(const xmlDoc *doc,
 						 const xmlChar *name);
 XMLPUBFUN xmlEntityPtr XMLCALL
 			xmlGetDtdEntity		(xmlDocPtr doc,
@@ -120,7 +120,7 @@
 			xmlEncodeEntitiesReentrant(xmlDocPtr doc,
 						 const xmlChar *input);
 XMLPUBFUN xmlChar * XMLCALL
-			xmlEncodeSpecialChars	(xmlDocPtr doc,
+			xmlEncodeSpecialChars	(const xmlDoc *doc,
 						 const xmlChar *input);
 XMLPUBFUN xmlEntitiesTablePtr XMLCALL
 			xmlCreateEntitiesTable	(void);
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index 9d688e0..a9305aa 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -39,7 +39,9 @@
  * Returns the new xmlParserInputBufferPtr in case of success or NULL if no
  *         method was found.
  */
-typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI, xmlCharEncoding enc);
+typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI,
+									   xmlCharEncoding enc);
+
 
 /**
  * xmlOutputBufferCreateFilenameFunc:
@@ -52,7 +54,9 @@
  * Returns the new xmlOutputBufferPtr in case of success or NULL if no
  *         method was found.
  */
-typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI, xmlCharEncodingHandlerPtr encoder, int compression);
+typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI,
+								 xmlCharEncodingHandlerPtr encoder,
+								 int compression);
 
 XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
 XMLCALL xmlParserInputBufferCreateFilenameDefault (xmlParserInputBufferCreateFilenameFunc func);
@@ -185,7 +189,8 @@
 XMLPUBFUN xmlOutputBufferCreateFilenameFunc XMLCALL
 	xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func);
 XMLPUBFUN xmlParserInputBufferCreateFilenameFunc XMLCALL
-	xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func);
+	xmlThrDefParserInputBufferCreateFilenameDefault(
+				xmlParserInputBufferCreateFilenameFunc func);
 
 /** DOC_DISABLE */
 /*
@@ -297,7 +302,8 @@
 #else
 XMLPUBVAR xmlBufferAllocationScheme xmlBufferAllocScheme;
 #endif
-XMLPUBFUN xmlBufferAllocationScheme XMLCALL xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
+XMLPUBFUN xmlBufferAllocationScheme XMLCALL
+	xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
 
 XMLPUBFUN int * XMLCALL __xmlDefaultBufferSize(void);
 #ifdef LIBXML_THREAD_ENABLED
@@ -479,7 +485,8 @@
 XMLPUBVAR xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
 #endif
 
-XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * XMLCALL __xmlParserInputBufferCreateFilenameValue(void);
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * XMLCALL \
+				__xmlParserInputBufferCreateFilenameValue(void);
 #ifdef LIBXML_THREAD_ENABLED
 #define xmlParserInputBufferCreateFilenameValue \
 (*(__xmlParserInputBufferCreateFilenameValue()))
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 3f5730d..47fbec0 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -260,7 +260,7 @@
     void              *catalogs;      /* document's own catalog */
     int                recovery;      /* run in recovery mode */
     int                progressive;   /* is this a progressive parsing */
-    xmlDictPtr         dict;          /* dictionnary for the parser */
+    xmlDictPtr         dict;          /* dictionary for the parser */
     const xmlChar *   *atts;          /* array for the attributes callbacks */
     int                maxatts;       /* the size of the array */
     int                docdict;       /* use strings from dict to build tree */
@@ -1099,7 +1099,7 @@
     XML_PARSE_SAX1	= 1<<9,	/* use the SAX1 interface internally */
     XML_PARSE_XINCLUDE	= 1<<10,/* Implement XInclude substitition  */
     XML_PARSE_NONET	= 1<<11,/* Forbid network access */
-    XML_PARSE_NODICT	= 1<<12,/* Do not reuse the context dictionnary */
+    XML_PARSE_NODICT	= 1<<12,/* Do not reuse the context dictionary */
     XML_PARSE_NSCLEAN	= 1<<13,/* remove redundant namespaces declarations */
     XML_PARSE_NOCDATA	= 1<<14,/* merge CDATA as text nodes */
     XML_PARSE_NOXINCNODE= 1<<15,/* do not generate XINCLUDE START/END nodes */
diff --git a/include/libxml/parserInternals.h b/include/libxml/parserInternals.h
index 6065320..f30fc68 100644
--- a/include/libxml/parserInternals.h
+++ b/include/libxml/parserInternals.h
@@ -351,7 +351,7 @@
 						 xmlParserErrors xmlerr,
 						 const char *msg,
 						 const xmlChar * str1,
-						 const xmlChar * str2);
+						 const xmlChar * str2) LIBXML_ATTR_FORMAT(3,0);
 #endif
 
 /**
diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h
index bdb0a7d..f269c9e 100644
--- a/include/libxml/relaxng.h
+++ b/include/libxml/relaxng.h
@@ -32,7 +32,9 @@
  *
  * Signature of an error callback from a Relax-NG validation
  */
-typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx,
+						      const char *msg,
+						      ...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * xmlRelaxNGValidityWarningFunc:
@@ -42,7 +44,9 @@
  *
  * Signature of a warning callback from a Relax-NG validation
  */
-typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx,
+							const char *msg,
+							...) LIBXML_ATTR_FORMAT(2,3);
 
 /**
  * A schemas validation context
diff --git a/include/libxml/schemasInternals.h b/include/libxml/schemasInternals.h
index 4f0ca9a..c7cf552 100644
--- a/include/libxml/schemasInternals.h
+++ b/include/libxml/schemasInternals.h
@@ -28,52 +28,52 @@
 
 typedef enum {
     XML_SCHEMAS_UNKNOWN = 0,
-    XML_SCHEMAS_STRING,
-    XML_SCHEMAS_NORMSTRING,
-    XML_SCHEMAS_DECIMAL,
-    XML_SCHEMAS_TIME,
-    XML_SCHEMAS_GDAY,
-    XML_SCHEMAS_GMONTH,
-    XML_SCHEMAS_GMONTHDAY,
-    XML_SCHEMAS_GYEAR,
-    XML_SCHEMAS_GYEARMONTH,
-    XML_SCHEMAS_DATE,
-    XML_SCHEMAS_DATETIME,
-    XML_SCHEMAS_DURATION,
-    XML_SCHEMAS_FLOAT,
-    XML_SCHEMAS_DOUBLE,
-    XML_SCHEMAS_BOOLEAN,
-    XML_SCHEMAS_TOKEN,
-    XML_SCHEMAS_LANGUAGE,
-    XML_SCHEMAS_NMTOKEN,
-    XML_SCHEMAS_NMTOKENS,
-    XML_SCHEMAS_NAME,
-    XML_SCHEMAS_QNAME,
-    XML_SCHEMAS_NCNAME,
-    XML_SCHEMAS_ID,
-    XML_SCHEMAS_IDREF,
-    XML_SCHEMAS_IDREFS,
-    XML_SCHEMAS_ENTITY,
-    XML_SCHEMAS_ENTITIES,
-    XML_SCHEMAS_NOTATION,
-    XML_SCHEMAS_ANYURI,
-    XML_SCHEMAS_INTEGER,
-    XML_SCHEMAS_NPINTEGER,
-    XML_SCHEMAS_NINTEGER,
-    XML_SCHEMAS_NNINTEGER,
-    XML_SCHEMAS_PINTEGER,
-    XML_SCHEMAS_INT,
-    XML_SCHEMAS_UINT,
-    XML_SCHEMAS_LONG,
-    XML_SCHEMAS_ULONG,
-    XML_SCHEMAS_SHORT,
-    XML_SCHEMAS_USHORT,
-    XML_SCHEMAS_BYTE,
-    XML_SCHEMAS_UBYTE,
-    XML_SCHEMAS_HEXBINARY,
-    XML_SCHEMAS_BASE64BINARY,
-    XML_SCHEMAS_ANYTYPE,
-    XML_SCHEMAS_ANYSIMPLETYPE
+    XML_SCHEMAS_STRING = 1,
+    XML_SCHEMAS_NORMSTRING = 2,
+    XML_SCHEMAS_DECIMAL = 3,
+    XML_SCHEMAS_TIME = 4,
+    XML_SCHEMAS_GDAY = 5,
+    XML_SCHEMAS_GMONTH = 6,
+    XML_SCHEMAS_GMONTHDAY = 7,
+    XML_SCHEMAS_GYEAR = 8,
+    XML_SCHEMAS_GYEARMONTH = 9,
+    XML_SCHEMAS_DATE = 10,
+    XML_SCHEMAS_DATETIME = 11,
+    XML_SCHEMAS_DURATION = 12,
+    XML_SCHEMAS_FLOAT = 13,
+    XML_SCHEMAS_DOUBLE = 14,
+    XML_SCHEMAS_BOOLEAN = 15,
+    XML_SCHEMAS_TOKEN = 16,
+    XML_SCHEMAS_LANGUAGE = 17,
+    XML_SCHEMAS_NMTOKEN = 18,
+    XML_SCHEMAS_NMTOKENS = 19,
+    XML_SCHEMAS_NAME = 20,
+    XML_SCHEMAS_QNAME = 21,
+    XML_SCHEMAS_NCNAME = 22,
+    XML_SCHEMAS_ID = 23,
+    XML_SCHEMAS_IDREF = 24,
+    XML_SCHEMAS_IDREFS = 25,
+    XML_SCHEMAS_ENTITY = 26,
+    XML_SCHEMAS_ENTITIES = 27,
+    XML_SCHEMAS_NOTATION = 28,
+    XML_SCHEMAS_ANYURI = 29,
+    XML_SCHEMAS_INTEGER = 30,
+    XML_SCHEMAS_NPINTEGER = 31,
+    XML_SCHEMAS_NINTEGER = 32,
+    XML_SCHEMAS_NNINTEGER = 33,
+    XML_SCHEMAS_PINTEGER = 34,
+    XML_SCHEMAS_INT = 35,
+    XML_SCHEMAS_UINT = 36,
+    XML_SCHEMAS_LONG = 37,
+    XML_SCHEMAS_ULONG = 38,
+    XML_SCHEMAS_SHORT = 39,
+    XML_SCHEMAS_USHORT = 40,
+    XML_SCHEMAS_BYTE = 41,
+    XML_SCHEMAS_UBYTE = 42,
+    XML_SCHEMAS_HEXBINARY = 43,
+    XML_SCHEMAS_BASE64BINARY = 44,
+    XML_SCHEMAS_ANYTYPE = 45,
+    XML_SCHEMAS_ANYSIMPLETYPE = 46
 } xmlSchemaValType;
 
 /*
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 7e06686..4a9b3bc 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -76,7 +76,8 @@
     XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
     XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
     XML_BUFFER_ALLOC_IO,	/* special allocation scheme used for I/O */
-    XML_BUFFER_ALLOC_HYBRID	/* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_HYBRID,	/* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
 } xmlBufferAllocationScheme;
 
 /**
@@ -116,8 +117,8 @@
  * A few public routines for xmlBuf. As those are expected to be used
  * mostly internally the bulk of the routines are internal in buf.h
  */
-XMLPUBFUN xmlChar* XMLCALL       xmlBufContent	(const xmlBufPtr buf);
-XMLPUBFUN xmlChar* XMLCALL       xmlBufEnd      (const xmlBufPtr buf);
+XMLPUBFUN xmlChar* XMLCALL       xmlBufContent	(const xmlBuf* buf);
+XMLPUBFUN xmlChar* XMLCALL       xmlBufEnd      (xmlBufPtr buf);
 XMLPUBFUN size_t XMLCALL         xmlBufUse      (const xmlBufPtr buf);
 XMLPUBFUN size_t XMLCALL         xmlBufShrink	(xmlBufPtr buf, size_t len);
 
@@ -654,7 +655,11 @@
 /*
  * Some helper functions
  */
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || \
+    defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || \
+    defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || \
+    defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 XMLPUBFUN int XMLCALL
 		xmlValidateNCName	(const xmlChar *value,
 					 int space);
@@ -731,14 +736,14 @@
 XMLPUBFUN void XMLCALL
 		xmlBufferEmpty		(xmlBufferPtr buf);
 XMLPUBFUN const xmlChar* XMLCALL
-		xmlBufferContent	(const xmlBufferPtr buf);
+		xmlBufferContent	(const xmlBuffer *buf);
 XMLPUBFUN xmlChar* XMLCALL
 		xmlBufferDetach         (xmlBufferPtr buf);
 XMLPUBFUN void XMLCALL
 		xmlBufferSetAllocationScheme(xmlBufferPtr buf,
 					 xmlBufferAllocationScheme scheme);
 XMLPUBFUN int XMLCALL
-		xmlBufferLength		(const xmlBufferPtr buf);
+		xmlBufferLength		(const xmlBuffer *buf);
 
 /*
  * Creating/freeing new structures.
@@ -754,7 +759,7 @@
 					 const xmlChar *ExternalID,
 					 const xmlChar *SystemID);
 XMLPUBFUN xmlDtdPtr XMLCALL
-		xmlGetIntSubset		(xmlDocPtr doc);
+		xmlGetIntSubset		(const xmlDoc *doc);
 XMLPUBFUN void XMLCALL
 		xmlFreeDtd		(xmlDtdPtr cur);
 #ifdef LIBXML_LEGACY_ENABLED
@@ -842,7 +847,7 @@
 					 const xmlChar *content);
 #endif
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlNewDocText		(xmlDocPtr doc,
+		xmlNewDocText		(const xmlDoc *doc,
 					 const xmlChar *content);
 XMLPUBFUN xmlNodePtr XMLCALL
 		xmlNewText		(const xmlChar *content);
@@ -873,20 +878,20 @@
 		xmlNewCharRef		(xmlDocPtr doc,
 					 const xmlChar *name);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlNewReference		(xmlDocPtr doc,
+		xmlNewReference		(const xmlDoc *doc,
 					 const xmlChar *name);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlCopyNode		(const xmlNodePtr node,
+		xmlCopyNode		(xmlNodePtr node,
 					 int recursive);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlDocCopyNode		(const xmlNodePtr node,
+		xmlDocCopyNode		(xmlNodePtr node,
 					 xmlDocPtr doc,
 					 int recursive);
 XMLPUBFUN xmlNodePtr XMLCALL
 		xmlDocCopyNodeList	(xmlDocPtr doc,
-					 const xmlNodePtr node);
+					 xmlNodePtr node);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlCopyNodeList		(const xmlNodePtr node);
+		xmlCopyNodeList		(xmlNodePtr node);
 #ifdef LIBXML_TREE_ENABLED
 XMLPUBFUN xmlNodePtr XMLCALL
 		xmlNewTextChild		(xmlNodePtr parent,
@@ -906,19 +911,19 @@
  * Navigating.
  */
 XMLPUBFUN long XMLCALL
-		xmlGetLineNo		(xmlNodePtr node);
+		xmlGetLineNo		(const xmlNode *node);
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
 XMLPUBFUN xmlChar * XMLCALL
-		xmlGetNodePath		(xmlNodePtr node);
+		xmlGetNodePath		(const xmlNode *node);
 #endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) */
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlDocGetRootElement	(xmlDocPtr doc);
+		xmlDocGetRootElement	(const xmlDoc *doc);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlGetLastChild		(xmlNodePtr parent);
+		xmlGetLastChild		(const xmlNode *parent);
 XMLPUBFUN int XMLCALL
-		xmlNodeIsText		(xmlNodePtr node);
+		xmlNodeIsText		(const xmlNode *node);
 XMLPUBFUN int XMLCALL
-		xmlIsBlankNode		(xmlNodePtr node);
+		xmlIsBlankNode		(const xmlNode *node);
 
 /*
  * Changing the structure.
@@ -945,7 +950,7 @@
 					 xmlNodePtr cur);
 #endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
-    defined(LIBXML_SCHEMAS_ENABLED)
+    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
 XMLPUBFUN xmlNodePtr XMLCALL
 		xmlAddPrevSibling	(xmlNodePtr cur,
 					 xmlNodePtr elem);
@@ -986,10 +991,11 @@
 		xmlSearchNsByHref	(xmlDocPtr doc,
 					 xmlNodePtr node,
 					 const xmlChar *href);
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED)
 XMLPUBFUN xmlNsPtr * XMLCALL
-		xmlGetNsList		(xmlDocPtr doc,
-					 xmlNodePtr node);
+		xmlGetNsList		(const xmlDoc *doc,
+					 const xmlNode *node);
 #endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) */
 
 XMLPUBFUN void XMLCALL
@@ -1003,7 +1009,8 @@
 /*
  * Changing the content.
  */
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \
+    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
 XMLPUBFUN xmlAttrPtr XMLCALL
 		xmlSetProp		(xmlNodePtr node,
 					 const xmlChar *name,
@@ -1013,39 +1020,40 @@
 					 xmlNsPtr ns,
 					 const xmlChar *name,
 					 const xmlChar *value);
-#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \
+	  defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
 XMLPUBFUN xmlChar * XMLCALL
-		xmlGetNoNsProp		(xmlNodePtr node,
+		xmlGetNoNsProp		(const xmlNode *node,
 					 const xmlChar *name);
 XMLPUBFUN xmlChar * XMLCALL
-		xmlGetProp		(xmlNodePtr node,
+		xmlGetProp		(const xmlNode *node,
 					 const xmlChar *name);
 XMLPUBFUN xmlAttrPtr XMLCALL
-		xmlHasProp		(xmlNodePtr node,
+		xmlHasProp		(const xmlNode *node,
 					 const xmlChar *name);
 XMLPUBFUN xmlAttrPtr XMLCALL
-		xmlHasNsProp		(xmlNodePtr node,
+		xmlHasNsProp		(const xmlNode *node,
 					 const xmlChar *name,
 					 const xmlChar *nameSpace);
 XMLPUBFUN xmlChar * XMLCALL
-		xmlGetNsProp		(xmlNodePtr node,
+		xmlGetNsProp		(const xmlNode *node,
 					 const xmlChar *name,
 					 const xmlChar *nameSpace);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlStringGetNodeList	(xmlDocPtr doc,
+		xmlStringGetNodeList	(const xmlDoc *doc,
 					 const xmlChar *value);
 XMLPUBFUN xmlNodePtr XMLCALL
-		xmlStringLenGetNodeList	(xmlDocPtr doc,
+		xmlStringLenGetNodeList	(const xmlDoc *doc,
 					 const xmlChar *value,
 					 int len);
 XMLPUBFUN xmlChar * XMLCALL
 		xmlNodeListGetString	(xmlDocPtr doc,
-					 xmlNodePtr list,
+					 const xmlNode *list,
 					 int inLine);
 #ifdef LIBXML_TREE_ENABLED
 XMLPUBFUN xmlChar * XMLCALL
-		xmlNodeListGetRawString	(xmlDocPtr doc,
-					 xmlNodePtr list,
+		xmlNodeListGetRawString	(const xmlDoc *doc,
+					 const xmlNode *list,
 					 int inLine);
 #endif /* LIBXML_TREE_ENABLED */
 XMLPUBFUN void XMLCALL
@@ -1065,19 +1073,19 @@
 					 const xmlChar *content,
 					 int len);
 XMLPUBFUN xmlChar * XMLCALL
-		xmlNodeGetContent	(xmlNodePtr cur);
+		xmlNodeGetContent	(const xmlNode *cur);
 
 XMLPUBFUN int XMLCALL
 		xmlNodeBufGetContent	(xmlBufferPtr buffer,
-					 xmlNodePtr cur);
+					 const xmlNode *cur);
 XMLPUBFUN int XMLCALL
 		xmlBufGetNodeContent	(xmlBufPtr buf,
-					 xmlNodePtr cur);
+					 const xmlNode *cur);
 
 XMLPUBFUN xmlChar * XMLCALL
-		xmlNodeGetLang		(xmlNodePtr cur);
+		xmlNodeGetLang		(const xmlNode *cur);
 XMLPUBFUN int XMLCALL
-		xmlNodeGetSpacePreserve	(xmlNodePtr cur);
+		xmlNodeGetSpacePreserve	(const xmlNode *cur);
 #ifdef LIBXML_TREE_ENABLED
 XMLPUBFUN void XMLCALL
 		xmlNodeSetLang		(xmlNodePtr cur,
@@ -1087,8 +1095,8 @@
 					 int val);
 #endif /* LIBXML_TREE_ENABLED */
 XMLPUBFUN xmlChar * XMLCALL
-		xmlNodeGetBase		(xmlDocPtr doc,
-					 xmlNodePtr cur);
+		xmlNodeGetBase		(const xmlDoc *doc,
+					 const xmlNode *cur);
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
 XMLPUBFUN void XMLCALL
 		xmlNodeSetBase		(xmlNodePtr cur,
@@ -1234,7 +1242,7 @@
  * Compression.
  */
 XMLPUBFUN int XMLCALL
-		xmlGetDocCompressMode	(xmlDocPtr doc);
+		xmlGetDocCompressMode	(const xmlDoc *doc);
 XMLPUBFUN void XMLCALL
 		xmlSetDocCompressMode	(xmlDocPtr doc,
 					 int mode);
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 6c241a8..3e41744 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -209,7 +209,7 @@
 
 xmlParserInputBufferPtr
 	__xmlParserInputBufferCreateFilename(const char *URI,
-										xmlCharEncoding enc);
+						xmlCharEncoding enc);
 
 #ifdef LIBXML_OUTPUT_ENABLED
 /*
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 537a396..037c16d 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -86,7 +86,7 @@
     char       *str2;	/* extra string information */
     char       *str3;	/* extra string information */
     int		int1;	/* extra number information */
-    int		int2;	/* column number of the error or 0 if N/A (todo: rename this field when we would break ABI) */
+    int		int2;	/* error column # or 0 if N/A (todo: rename field when we would brk ABI) */
     void       *ctxt;   /* the parser context if available */
     void       *node;   /* the node in the tree */
 };
@@ -937,7 +937,7 @@
 				 int code,
 				 xmlNodePtr node,
 				 const char *msg,
-				 const char *extra);
+				 const char *extra) LIBXML_ATTR_FORMAT(4,0);
 #endif
 #ifdef __cplusplus
 }
diff --git a/include/libxml/xmlstring.h b/include/libxml/xmlstring.h
index 2036236..2d0b2d1 100644
--- a/include/libxml/xmlstring.h
+++ b/include/libxml/xmlstring.h
@@ -97,13 +97,13 @@
 XMLPUBFUN int XMLCALL
                 xmlStrPrintf             (xmlChar *buf,
                                          int len,
-                                         const xmlChar *msg,
-                                         ...);
+                                         const char *msg,
+                                         ...) LIBXML_ATTR_FORMAT(3,4);
 XMLPUBFUN int XMLCALL
                 xmlStrVPrintf                (xmlChar *buf,
                                          int len,
-                                         const xmlChar *msg,
-                                         va_list ap);
+                                         const char *msg,
+                                         va_list ap) LIBXML_ATTR_FORMAT(3,0);
 
 XMLPUBFUN int XMLCALL
         xmlGetUTF8Char                   (const unsigned char *utf,
diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h
index 1264867..321d5eb 100644
--- a/include/libxml/xmlversion.h
+++ b/include/libxml/xmlversion.h
@@ -29,28 +29,28 @@
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.9.1"
+#define LIBXML_DOTTED_VERSION "2.9.2"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20901
+#define LIBXML_VERSION 20902
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20901"
+#define LIBXML_VERSION_STRING "20902"
 
 /**
  * LIBXML_VERSION_EXTRA:
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXML_VERSION_EXTRA "-GITv2.9.1"
+#define LIBXML_VERSION_EXTRA "-GITv2.9.2-48-g4b31d61"
 
 /**
  * LIBXML_TEST_VERSION:
@@ -58,7 +58,7 @@
  * Macro to check that the libxml version in use is compatible with
  * the version the software has been compiled against
  */
-#define LIBXML_TEST_VERSION xmlCheckVersion(20901);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20902);
 
 #ifndef VMS
 #if 0
@@ -435,7 +435,7 @@
  */
 
 #ifndef LIBXML_ATTR_ALLOC_SIZE
-# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
 #  define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
 # else
 #  define LIBXML_ATTR_ALLOC_SIZE(x)
diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h
index 70c9db9..76a6b48 100644
--- a/include/libxml/xpathInternals.h
+++ b/include/libxml/xpathInternals.h
@@ -229,7 +229,7 @@
  * Empties a node-set.
  */
 #define xmlXPathEmptyNodeSet(ns)					\
-    { while ((ns)->nodeNr > 0) (ns)->nodeTab[(ns)->nodeNr--] = NULL; }
+    { while ((ns)->nodeNr > 0) (ns)->nodeTab[--(ns)->nodeNr] = NULL; }
 
 /**
  * CHECK_ERROR:
diff --git a/legacy.c b/legacy.c
index e941cb0..86362bf 100644
--- a/legacy.c
+++ b/legacy.c
@@ -1151,7 +1151,7 @@
 endElement(void *ctx, const xmlChar * name ATTRIBUTE_UNUSED)
 {
     DEPRECATED("endElement")
-        xmlSAX2EndElement(ctx, name);
+    xmlSAX2EndElement(ctx, name);
 }
 
 /**
diff --git a/libxml.h b/libxml.h
index 2da9044..88e515f 100644
--- a/libxml.h
+++ b/libxml.h
@@ -9,6 +9,8 @@
 #ifndef __XML_LIBXML_H__
 #define __XML_LIBXML_H__
 
+#include <libxml/xmlstring.h>
+
 #ifndef NO_LARGEFILE_SOURCE
 #ifndef _LARGEFILE_SOURCE
 #define _LARGEFILE_SOURCE
@@ -68,7 +70,7 @@
  * internal error reporting routines, shared but not partof the API.
  */
 void __xmlIOErr(int domain, int code, const char *extra);
-void __xmlLoaderErr(void *ctx, const char *msg, const char *filename);
+void __xmlLoaderErr(void *ctx, const char *msg, const char *filename) LIBXML_ATTR_FORMAT(2,0);
 #ifdef LIBXML_HTML_ENABLED
 /*
  * internal function of HTML parser needed for xmlParseInNodeContext
@@ -93,6 +95,7 @@
 int __xmlRandom(void);
 #endif
 
+XMLPUBFUN xmlChar * XMLCALL xmlEscapeFormatString(xmlChar **msg);
 int xmlNop(void);
 
 #ifdef IN_LIBXML
diff --git a/nanoftp.c b/nanoftp.c
index 077bfe2..2135ab9 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -775,7 +775,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	return(res);
@@ -803,7 +803,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	return(res);
@@ -834,7 +834,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	return(res);
@@ -908,6 +908,8 @@
 	    return (-1);
 	}
 	if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
+	    if (result)
+		freeaddrinfo (result);
 	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
 	    return (-1);
 	}
@@ -928,9 +930,9 @@
 #endif
     {
 	if (proxy)
-	    hp = gethostbyname (proxy);
+	    hp = gethostbyname (GETHOSTBYNAME_ARG_CAST proxy);
 	else
-	    hp = gethostbyname (ctxt->hostname);
+	    hp = gethostbyname (GETHOSTBYNAME_ARG_CAST ctxt->hostname);
 	if (hp == NULL) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed");
 	    return (-1);
@@ -1028,7 +1030,7 @@
 #ifdef DEBUG_FTP
 	    xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-	    res = send(ctxt->controlFd, buf, len, 0);
+	    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 	    if (res < 0) {
 		__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 		closesocket(ctxt->controlFd);
@@ -1050,7 +1052,7 @@
 #ifdef DEBUG_FTP
 		    xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-		    res = send(ctxt->controlFd, buf, len, 0);
+		    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 		    if (res < 0) {
 			__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 			closesocket(ctxt->controlFd);
@@ -1091,7 +1093,7 @@
 #ifdef DEBUG_FTP
 		xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-		res = send(ctxt->controlFd, buf, len, 0);
+		res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
 		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1122,7 +1124,7 @@
 #ifdef DEBUG_FTP
 		xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-		res = send(ctxt->controlFd, buf, len, 0);
+		res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
 		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1144,7 +1146,7 @@
 #ifdef DEBUG_FTP
 		xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-		res = send(ctxt->controlFd, buf, len, 0);
+		res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 		if (res < 0) {
 		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
 		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1244,7 +1246,13 @@
     if (port <= 0)
 	return(NULL);
     ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
+    if (ctxt == NULL)
+        return(NULL);
     ctxt->hostname = xmlMemStrdup(server);
+    if (ctxt->hostname == NULL) {
+	xmlNanoFTPFreeCtxt(ctxt);
+	return(NULL);
+    }
     if (port != 0)
 	ctxt->port = port;
     res = xmlNanoFTPConnect(ctxt);
@@ -1288,7 +1296,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	return(res);
@@ -1321,8 +1329,8 @@
     int len;
     int res;
 
-    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) || (file == NULL)) return(-1);
-    if (file == NULL) return (0);
+    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) ||
+        (file == NULL)) return(-1);
 
     /*
      * Expected response code for DELE:
@@ -1339,7 +1347,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	return(res);
@@ -1411,7 +1419,7 @@
 #ifdef DEBUG_FTP
 	xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-	res = send(ctxt->controlFd, buf, len, 0);
+	res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 	if (res < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1512,7 +1520,7 @@
 	xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
 
-	res = send(ctxt->controlFd, buf, len, 0);
+	res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
 	if (res < 0) {
 	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1749,7 +1757,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1844,7 +1852,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1864,7 +1872,7 @@
 #ifdef DEBUG_FTP
     xmlGenericError(xmlGenericErrorContext, "%s", buf);
 #endif
-    res = send(ctxt->controlFd, buf, len, 0);
+    res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
 	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
 	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
diff --git a/nanohttp.c b/nanohttp.c
index ac47ea6..e109ad7 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -461,7 +461,7 @@
 
     if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
         while (total_sent < outlen) {
-            int nsent = send(ctxt->fd, xmt_ptr + total_sent,
+            int nsent = send(ctxt->fd, SEND_ARG2_CAST (xmt_ptr + total_sent),
                              outlen - total_sent, 0);
 
             if (nsent > 0)
@@ -1003,6 +1003,7 @@
             0) {
             /* Solaris error code */
             __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
+            closesocket(s);
             return INVALID_SOCKET;
         }
 #endif
@@ -1121,7 +1122,7 @@
 #endif
 #if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
     {
-	h = gethostbyname (host);
+	h = gethostbyname (GETHOSTBYNAME_ARG_CAST host);
 	if (h == NULL) {
 
 /*
@@ -1362,17 +1363,17 @@
     xmlNanoHTTPInit();
 
 retry:
-    if (redirURL == NULL)
+    if (redirURL == NULL) {
 	ctxt = xmlNanoHTTPNewCtxt(URL);
-    else {
+	if (ctxt == NULL)
+	    return(NULL);
+    } else {
 	ctxt = xmlNanoHTTPNewCtxt(redirURL);
+	if (ctxt == NULL)
+	    return(NULL);
 	ctxt->location = xmlMemStrdup(redirURL);
     }
 
-    if ( ctxt == NULL ) {
-	return ( NULL );
-    }
-
     if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
 	__xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
         xmlNanoHTTPFreeCtxt(ctxt);
diff --git a/parser.c b/parser.c
index ee429f3..53a6b7f 100644
--- a/parser.c
+++ b/parser.c
@@ -94,6 +94,8 @@
 xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
 	                  const xmlChar *base, xmlParserCtxtPtr pctx);
 
+static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+
 /************************************************************************
  *									*
  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
@@ -130,6 +132,35 @@
         return (0);
     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
         return (1);
+
+    /*
+     * This may look absurd but is needed to detect
+     * entities problems
+     */
+    if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
+	(ent->content != NULL) && (ent->checked == 0) &&
+	(ctxt->errNo != XML_ERR_ENTITY_LOOP)) {
+	unsigned long oldnbent = ctxt->nbentities;
+	xmlChar *rep;
+
+	ent->checked = 1;
+
+        ++ctxt->depth;
+	rep = xmlStringDecodeEntities(ctxt, ent->content,
+				  XML_SUBSTITUTE_REF, 0, 0, 0);
+        --ctxt->depth;
+	if (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
+	    ent->content[0] = 0;
+	}
+
+	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+	if (rep != NULL) {
+	    if (xmlStrchr(rep, '<'))
+		ent->checked |= 1;
+	    xmlFree(rep);
+	    rep = NULL;
+	}
+    }
     if (replacement != 0) {
 	if (replacement < XML_MAX_TEXT_LENGTH)
 	    return(0);
@@ -189,9 +220,12 @@
             return (0);
     } else {
         /*
-         * strange we got no data for checking just return
+         * strange we got no data for checking
          */
-        return (0);
+	if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
+	     (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
+	    (ctxt->nbentities <= 10000))
+	    return (0);
     }
     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
     return (1);
@@ -316,7 +350,6 @@
 xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
 {
     const char *errmsg;
-    char errstr[129] = "";
 
     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
         (ctxt->instate == XML_PARSER_EOF))
@@ -503,15 +536,17 @@
         default:
             errmsg = "Unregistered error message";
     }
-    if (info == NULL)
-        snprintf(errstr, 128, "%s\n", errmsg);
-    else
-        snprintf(errstr, 128, "%s: %%s\n", errmsg);
     if (ctxt != NULL)
 	ctxt->errNo = error;
-    __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
-                    XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0],
-                    info);
+    if (info == NULL) {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
+                        errmsg);
+    } else {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
+                        errmsg, info);
+    }
     if (ctxt != NULL) {
 	ctxt->wellFormed = 0;
 	if (ctxt->recovery == 0)
@@ -527,7 +562,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                const char *msg)
 {
@@ -555,7 +590,7 @@
  *
  * Handle a warning.
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -593,7 +628,7 @@
  *
  * Handle a validity error.
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -633,7 +668,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, int val)
 {
@@ -663,7 +698,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar *str1, int val,
 		  const xmlChar *str2)
@@ -693,7 +728,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar * val)
 {
@@ -722,7 +757,7 @@
  *
  * Handle a non fatal parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, const xmlChar * val)
 {
@@ -747,7 +782,7 @@
  *
  * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error,
          const char *msg,
          const xmlChar * info1, const xmlChar * info2,
@@ -776,7 +811,7 @@
  *
  * Handle a namespace warning error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error,
          const char *msg,
          const xmlChar * info1, const xmlChar * info2,
@@ -1745,7 +1780,7 @@
 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
 			  xmlParserMaxDepth);
-	ctxt->instate = XML_PARSER_EOF;
+	xmlHaltParser(ctxt);
 	return(-1);
     }
     ctxt->nodeTab[ctxt->nodeNr] = value;
@@ -1980,6 +2015,7 @@
 #define CUR (*ctxt->input->cur)
 #define NXT(val) ctxt->input->cur[(val)]
 #define CUR_PTR ctxt->input->cur
+#define BASE_PTR ctxt->input->base
 
 #define CMP4( s, c1, c2, c3, c4 ) \
   ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \
@@ -2039,14 +2075,24 @@
 	xmlGROW (ctxt);
 
 static void xmlGROW (xmlParserCtxtPtr ctxt) {
-    if ((((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
-         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
+    unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
+    unsigned long curBase = ctxt->input->cur - ctxt->input->base;
+
+    if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
+         (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
          ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
-        ctxt->instate = XML_PARSER_EOF;
+        xmlHaltParser(ctxt);
+	return;
     }
     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+    if ((ctxt->input->cur > ctxt->input->end) ||
+        (ctxt->input->cur < ctxt->input->base)) {
+        xmlHaltParser(ctxt);
+        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound");
+	return;
+    }
     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
 	    xmlPopInput(ctxt);
@@ -2106,6 +2152,8 @@
 	while (IS_BLANK_CH(*cur)) {
 	    if (*cur == '\n') {
 		ctxt->input->line++; ctxt->input->col = 1;
+	    } else {
+		ctxt->input->col++;
 	    }
 	    cur++;
 	    res++;
@@ -2120,7 +2168,8 @@
 	int cur;
 	do {
 	    cur = CUR;
-	    while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
+	    while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
+	           (ctxt->instate != XML_PARSER_EOF))) {
 		NEXT;
 		cur = CUR;
 		res++;
@@ -2134,7 +2183,8 @@
 	     * Need to handle support of entities branching here
 	     */
 	    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
-	} while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+	} while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
+	         (ctxt->instate != XML_PARSER_EOF));
     }
     return(res);
 }
@@ -2584,6 +2634,7 @@
 				      name, NULL);
 		    ctxt->valid = 0;
 		}
+		xmlParserEntityCheck(ctxt, 0, NULL, 0);
 	    } else if (ctxt->input->free != deallocblankswrapper) {
 		    input = xmlNewBlanksWrapperInputStream(ctxt, entity);
 		    if (xmlPushInput(ctxt, input) < 0)
@@ -2595,6 +2646,23 @@
 		    xmlCharEncoding enc;
 
 		    /*
+		     * Note: external parameter entities will not be loaded, it
+		     * is not required for a non-validating parser, unless the
+		     * option of validating, or substituting entities were
+		     * given. Doing so is far more secure as the parser will
+		     * only process data coming from the document entity by
+		     * default.
+		     */
+                    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
+		        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
+			((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
+			((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
+			((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
+			(ctxt->replaceEntities == 0) &&
+			(ctxt->validate == 0))
+			return;
+
+		    /*
 		     * handle the extra spaces added before and after
 		     * c.f. http://www.w3.org/TR/REC-xml#as-PE
 		     * this is done independently.
@@ -2737,6 +2805,7 @@
 	    if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
 	        (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
 	        goto int_error;
+	    xmlParserEntityCheck(ctxt, 0, ent, 0);
 	    if (ent != NULL)
 	        ctxt->nbentities += ent->checked / 2;
 	    if ((ent != NULL) &&
@@ -2756,6 +2825,10 @@
 			                      0, 0, 0);
 		ctxt->depth--;
 
+		if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) ||
+		    (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR))
+		    goto int_error;
+
 		if (rep != NULL) {
 		    current = rep;
 		    while (*current != 0) { /* non input consuming loop */
@@ -2788,11 +2861,26 @@
 	    ent = xmlParseStringPEReference(ctxt, &str);
 	    if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
 	        goto int_error;
+	    xmlParserEntityCheck(ctxt, 0, ent, 0);
 	    if (ent != NULL)
 	        ctxt->nbentities += ent->checked / 2;
 	    if (ent != NULL) {
                 if (ent->content == NULL) {
-		    xmlLoadEntityContent(ctxt, ent);
+		    /*
+		     * Note: external parsed entities will not be loaded,
+		     * it is not required for a non-validating parser to
+		     * complete external PEreferences coming from the
+		     * internal subset
+		     */
+		    if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
+			((ctxt->options & XML_PARSE_DTDVALID) != 0) ||
+			(ctxt->validate != 0)) {
+			xmlLoadEntityContent(ctxt, ent);
+		    } else {
+			xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
+		  "not validating will not read content for PE entity %s\n",
+		                      ent->name, NULL);
+		    }
 		}
 		ctxt->depth++;
 		rep = xmlStringDecodeEntities(ctxt, ent->content, what,
@@ -3404,6 +3492,7 @@
     int len = 0, l;
     int c;
     int count = 0;
+    size_t startPosition = 0;
 
 #ifdef DEBUG
     nbParseNCNameComplex++;
@@ -3413,6 +3502,7 @@
      * Handler for more complex cases
      */
     GROW;
+    startPosition = CUR_PTR - BASE_PTR;
     c = CUR_CHAR(l);
     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
 	(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
@@ -3437,7 +3527,14 @@
 	c = CUR_CHAR(l);
 	if (c == 0) {
 	    count = 0;
+	    /*
+	     * when shrinking to extend the buffer we really need to preserve
+	     * the part of the name we already parsed. Hence rolling back
+	     * by current lenght.
+	     */
+	    ctxt->input->cur -= l;
 	    GROW;
+	    ctxt->input->cur += l;
             if (ctxt->instate == XML_PARSER_EOF)
                 return(NULL);
 	    c = CUR_CHAR(l);
@@ -3448,7 +3545,7 @@
         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
         return(NULL);
     }
-    return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+    return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
 }
 
 /**
@@ -3468,7 +3565,7 @@
 
 static const xmlChar *
 xmlParseNCName(xmlParserCtxtPtr ctxt) {
-    const xmlChar *in;
+    const xmlChar *in, *e;
     const xmlChar *ret;
     int count = 0;
 
@@ -3480,16 +3577,19 @@
      * Accelerator for simple ASCII names
      */
     in = ctxt->input->cur;
-    if (((*in >= 0x61) && (*in <= 0x7A)) ||
-	((*in >= 0x41) && (*in <= 0x5A)) ||
-	(*in == '_')) {
+    e = ctxt->input->end;
+    if ((((*in >= 0x61) && (*in <= 0x7A)) ||
+	 ((*in >= 0x41) && (*in <= 0x5A)) ||
+	 (*in == '_')) && (in < e)) {
 	in++;
-	while (((*in >= 0x61) && (*in <= 0x7A)) ||
-	       ((*in >= 0x41) && (*in <= 0x5A)) ||
-	       ((*in >= 0x30) && (*in <= 0x39)) ||
-	       (*in == '_') || (*in == '-') ||
-	       (*in == '.'))
+	while ((((*in >= 0x61) && (*in <= 0x7A)) ||
+	        ((*in >= 0x41) && (*in <= 0x5A)) ||
+	        ((*in >= 0x30) && (*in <= 0x39)) ||
+	        (*in == '_') || (*in == '-') ||
+	        (*in == '.')) && (in < e))
 	    in++;
+	if (in >= e)
+	    goto complex;
 	if ((*in > 0) && (*in < 0x80)) {
 	    count = in - ctxt->input->cur;
             if ((count > XML_MAX_NAME_LENGTH) &&
@@ -3507,6 +3607,7 @@
 	    return(ret);
 	}
     }
+complex:
     return(xmlParseNCNameComplex(ctxt));
 }
 
@@ -3544,7 +3645,7 @@
     }
     /* failure (or end of input buffer), check with full function */
     ret = xmlParseName (ctxt);
-    /* strings coming from the dictionnary direct compare possible */
+    /* strings coming from the dictionary direct compare possible */
     if (ret == other) {
 	return (const xmlChar*) 1;
     }
@@ -3885,8 +3986,10 @@
 	 * an entity declaration, it is bypassed and left as is.
 	 * so XML_SUBSTITUTE_REF is not set here.
 	 */
+        ++ctxt->depth;
 	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
 				      0, 0, 0);
+        --ctxt->depth;
 	if (orig != NULL)
 	    *orig = buf;
 	else
@@ -4011,9 +4114,11 @@
 		} else if ((ent != NULL) &&
 		           (ctxt->replaceEntities != 0)) {
 		    if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) {
+			++ctxt->depth;
 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 						      XML_SUBSTITUTE_REF,
 						      0, 0, 0);
+			--ctxt->depth;
 			if (rep != NULL) {
 			    current = rep;
 			    while (*current != 0) { /* non input consuming */
@@ -4049,8 +4154,10 @@
 			(ent->content != NULL) && (ent->checked == 0)) {
 			unsigned long oldnbent = ctxt->nbentities;
 
+			++ctxt->depth;
 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 						  XML_SUBSTITUTE_REF, 0, 0, 0);
+			--ctxt->depth;
 
 			ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
 			if (rep != NULL) {
@@ -5075,7 +5182,7 @@
     }
     if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
 	xmlNsErr(ctxt, XML_NS_ERR_COLON,
-		 "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
+		 "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
     }
     return(name);
 }
@@ -5344,7 +5451,7 @@
 	}
 	if (xmlStrchr(name, ':') != NULL) {
 	    xmlNsErr(ctxt, XML_NS_ERR_COLON,
-		     "colon are forbidden from notation names '%s'\n",
+		     "colons are forbidden from notation names '%s'\n",
 		     name, NULL, NULL);
 	}
 	SKIP_BLANKS;
@@ -5420,7 +5527,7 @@
 	    skipped = SKIP_BLANKS;
 	    if (skipped == 0) {
 		xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
-			       "Space required after '%'\n");
+			       "Space required after '%%'\n");
 	    }
 	    isParameter = 1;
 	}
@@ -5433,7 +5540,7 @@
 	}
 	if (xmlStrchr(name, ':') != NULL) {
 	    xmlNsErr(ctxt, XML_NS_ERR_COLON,
-		     "colon are forbidden from entities names '%s'\n",
+		     "colons are forbidden from entities names '%s'\n",
 		     name, NULL, NULL);
 	}
         skipped = SKIP_BLANKS;
@@ -5603,6 +5710,7 @@
 	if (RAW != '>') {
 	    xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
 	            "xmlParseEntityDecl: entity %s not terminated\n", name);
+	    xmlHaltParser(ctxt);
 	} else {
 	    if (input != ctxt->input) {
 		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6604,6 +6712,7 @@
 	if (!IS_BLANK_CH(CUR)) {
 	    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
 		           "Space required after 'ELEMENT'\n");
+	    return(-1);
 	}
         SKIP_BLANKS;
         name = xmlParseName(ctxt);
@@ -6714,6 +6823,8 @@
 	SKIP_BLANKS;
 	if (RAW != '[') {
 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	    xmlHaltParser(ctxt);
+	    return;
 	} else {
 	    if (ctxt->input->id != id) {
 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6753,6 +6864,7 @@
 
 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+		xmlHaltParser(ctxt);
 		break;
 	    }
 	}
@@ -6774,6 +6886,8 @@
 	SKIP_BLANKS;
 	if (RAW != '[') {
 	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+	    xmlHaltParser(ctxt);
+	    return;
 	} else {
 	    if (ctxt->input->id != id) {
 		xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6829,6 +6943,8 @@
 
     } else {
 	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+	xmlHaltParser(ctxt);
+	return;
     }
 
     if (RAW == 0)
@@ -6842,7 +6958,9 @@
 	"All markup of the conditional section is not in the same entity\n",
 				 NULL, NULL);
 	}
-        SKIP(3);
+	if ((ctxt-> instate != XML_PARSER_EOF) &&
+	    ((ctxt->input->cur + 3) <= ctxt->input->end))
+	    SKIP(3);
     }
 }
 
@@ -6897,6 +7015,14 @@
 	    xmlParsePI(ctxt);
 	}
     }
+
+    /*
+     * detect requirement to exit there and act accordingly
+     * and avoid having instate overriden later on
+     */
+    if (ctxt->instate == XML_PARSER_EOF)
+        return;
+
     /*
      * This is only for internal subset. On external entities,
      * the replacement is done before parsing stage
@@ -7028,7 +7154,7 @@
 	    /*
 	     * The XML REC instructs us to stop parsing right here
 	     */
-	    ctxt->instate = XML_PARSER_EOF;
+	    xmlHaltParser(ctxt);
 	    return;
 	}
     }
@@ -7180,7 +7306,8 @@
      * far more secure as the parser will only process data coming from
      * the document entity by default.
      */
-    if ((ent->checked == 0) &&
+    if (((ent->checked == 0) ||
+         ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
          (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
 	unsigned long oldnbent = ctxt->nbentities;
@@ -7286,6 +7413,7 @@
 		   (ret != XML_WAR_UNDECLARED_ENTITY)) {
 	    xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
 		     "Entity '%s' failed to parse\n", ent->name);
+	    xmlParserEntityCheck(ctxt, 0, ent, 0);
 	} else if (list != NULL) {
 	    xmlFreeNodeList(list);
 	    list = NULL;
@@ -7392,7 +7520,7 @@
 		/*
 		 * We are copying here, make sure there is no abuse
 		 */
-		ctxt->sizeentcopy += ent->length;
+		ctxt->sizeentcopy += ent->length + 5;
 		if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
 		    return;
 
@@ -7440,7 +7568,7 @@
 		/*
 		 * We are copying here, make sure there is no abuse
 		 */
-		ctxt->sizeentcopy += ent->length;
+		ctxt->sizeentcopy += ent->length + 5;
 		if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
 		    return;
 
@@ -7626,6 +7754,7 @@
 		ctxt->sax->reference(ctxt->userData, name);
 	    }
 	}
+	xmlParserEntityCheck(ctxt, 0, ent, 0);
 	ctxt->valid = 0;
     }
 
@@ -7658,8 +7787,8 @@
     else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
 	     (ent != NULL) && 
 	     (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
-	if ((ent->checked & 1) || ((ent->checked == 0) &&
-	     (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
+	if (((ent->checked & 1) || (ent->checked == 0)) &&
+	     (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
 	    xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
 	"'<' in entity '%s' is not allowed in attributes values\n", name);
         }
@@ -7753,7 +7882,7 @@
 
 
     /*
-     * Predefined entites override any extra definition
+     * Predefined entities override any extra definition
      */
     if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
         ent = xmlGetPredefinedEntity(name);
@@ -7819,6 +7948,7 @@
 			  "Entity '%s' not defined\n",
 			  name);
 	}
+	xmlParserEntityCheck(ctxt, 0, ent, 0);
 	/* TODO ? check regressions ctxt->valid = 0; */
     }
 
@@ -7978,6 +8108,7 @@
 			  name, NULL);
 	    ctxt->valid = 0;
 	}
+	xmlParserEntityCheck(ctxt, 0, NULL, 0);
     } else {
 	/*
 	 * Internal checking in case the entity quest barfed
@@ -8010,7 +8141,7 @@
 		     * The XML REC instructs us to stop parsing
 		     * right here
 		     */
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 		    return;
 		}
 	    }
@@ -8217,6 +8348,7 @@
 			  name, NULL);
 	    ctxt->valid = 0;
 	}
+	xmlParserEntityCheck(ctxt, 0, NULL, 0);
     } else {
 	/*
 	 * Internal checking in case the entity quest barfed
@@ -8364,6 +8496,7 @@
      */
     if (RAW != '>') {
 	xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
+	return;
     }
     NEXT;
 }
@@ -8714,7 +8847,7 @@
  * @prefix:  the prefix to lookup
  *
  * Lookup the namespace name for the @prefix (which ca be NULL)
- * The prefix must come from the @ctxt->dict dictionnary
+ * The prefix must come from the @ctxt->dict dictionary
  *
  * Returns the namespace name or NULL if not bound
  */
@@ -8906,9 +9039,12 @@
     xmlChar limit = 0;
     const xmlChar *in = NULL, *start, *end, *last;
     xmlChar *ret = NULL;
+    int line, col;
 
     GROW;
     in = (xmlChar *) CUR_PTR;
+    line = ctxt->input->line;
+    col = ctxt->input->col;
     if (*in != '"' && *in != '\'') {
         xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
         return (NULL);
@@ -8921,6 +9057,7 @@
      * pure ASCII.
      */
     limit = *in++;
+    col++;
     end = ctxt->input->end;
     start = in;
     if (in >= end) {
@@ -8940,6 +9077,11 @@
 	while ((in < end) && (*in != limit) &&
 	       ((*in == 0x20) || (*in == 0x9) ||
 	        (*in == 0xA) || (*in == 0xD))) {
+	    if (*in == 0xA) {
+	        line++; col = 1;
+	    } else {
+	        col++;
+	    }
 	    in++;
 	    start = in;
 	    if (in >= end) {
@@ -8963,6 +9105,7 @@
 	}
 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
+	    col++;
 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
 	    if (in >= end) {
 		const xmlChar *oldbase = ctxt->input->base;
@@ -8991,6 +9134,11 @@
 	while ((in < end) && (*in != limit) &&
 	       ((*in == 0x20) || (*in == 0x9) ||
 	        (*in == 0xA) || (*in == 0xD))) {
+	    if (*in == 0xA) {
+	        line++, col = 1;
+	    } else {
+	        col++;
+	    }
 	    in++;
 	    if (in >= end) {
 		const xmlChar *oldbase = ctxt->input->base;
@@ -9023,6 +9171,7 @@
 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
 	       (*in <= 0x7f) && (*in != '&') && (*in != '<')) {
 	    in++;
+	    col++;
 	    if (in >= end) {
 		const xmlChar *oldbase = ctxt->input->base;
 		GROW;
@@ -9052,6 +9201,7 @@
 	if (*in != limit) goto need_complex;
     }
     in++;
+    col++;
     if (len != NULL) {
         *len = last - start;
         ret = (xmlChar *) start;
@@ -9060,6 +9210,8 @@
         ret = xmlStrndup(start, last - start);
     }
     CUR_PTR = in;
+    ctxt->input->line = line;
+    ctxt->input->col = col;
     if (alloc) *alloc = 0;
     return ret;
 need_complex:
@@ -9225,7 +9377,7 @@
     const xmlChar **atts = ctxt->atts;
     int maxatts = ctxt->maxatts;
     int nratts, nbatts, nbdef;
-    int i, j, nbNs, attval, oldline, oldcol;
+    int i, j, nbNs, attval, oldline, oldcol, inputNr;
     const xmlChar *base;
     unsigned long cur;
     int nsNr = ctxt->nsNr;
@@ -9244,6 +9396,7 @@
     SHRINK;
     base = ctxt->input->base;
     cur = ctxt->input->cur - ctxt->input->base;
+    inputNr = ctxt->inputNr;
     oldline = ctxt->input->line;
     oldcol = ctxt->input->col;
     nbatts = 0;
@@ -9269,7 +9422,8 @@
      */
     SKIP_BLANKS;
     GROW;
-    if (ctxt->input->base != base) goto base_changed;
+    if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+        goto base_changed;
 
     while (((RAW != '>') &&
 	   ((RAW != '/') || (NXT(1) != '>')) &&
@@ -9280,7 +9434,7 @@
 
 	attname = xmlParseAttribute2(ctxt, prefix, localname,
 	                             &aprefix, &attvalue, &len, &alloc);
-	if (ctxt->input->base != base) {
+	if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
 	    if ((attvalue != NULL) && (alloc != 0))
 	        xmlFree(attvalue);
 	    attvalue = NULL;
@@ -9292,6 +9446,12 @@
 	        const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
 		xmlURIPtr uri;
 
+                if (URL == NULL) {
+		    xmlErrMemory(ctxt, "dictionary allocation failure");
+		    if ((attvalue != NULL) && (alloc != 0))
+			xmlFree(attvalue);
+		    return(NULL);
+		}
                 if (*URL != 0) {
 		    uri = xmlParseURI((const char *) URL);
 		    if (uri == NULL) {
@@ -9334,8 +9494,20 @@
 		else
 		    if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
 skip_default_ns:
-		if (alloc != 0) xmlFree(attvalue);
+		if ((attvalue != NULL) && (alloc != 0)) {
+		    xmlFree(attvalue);
+		    attvalue = NULL;
+		}
+		if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+		    break;
+		if (!IS_BLANK_CH(RAW)) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+				   "attributes construct error\n");
+		    break;
+		}
 		SKIP_BLANKS;
+		if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+		    goto base_changed;
 		continue;
 	    }
             if (aprefix == ctxt->str_xmlns) {
@@ -9407,9 +9579,20 @@
 		else
 		    if (nsPush(ctxt, attname, URL) > 0) nbNs++;
 skip_ns:
-		if (alloc != 0) xmlFree(attvalue);
+		if ((attvalue != NULL) && (alloc != 0)) {
+		    xmlFree(attvalue);
+		    attvalue = NULL;
+		}
+		if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+		    break;
+		if (!IS_BLANK_CH(RAW)) {
+		    xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
+				   "attributes construct error\n");
+		    break;
+		}
 		SKIP_BLANKS;
-		if (ctxt->input->base != base) goto base_changed;
+		if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+		    goto base_changed;
 		continue;
 	    }
 
@@ -9446,7 +9629,8 @@
 	GROW
         if (ctxt->instate == XML_PARSER_EOF)
             break;
-	if (ctxt->input->base != base) goto base_changed;
+	if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+	    goto base_changed;
 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
 	    break;
 	if (!IS_BLANK_CH(RAW)) {
@@ -9462,7 +9646,8 @@
 	    break;
 	}
         GROW;
-	if (ctxt->input->base != base) goto base_changed;
+	if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+	    goto base_changed;
     }
 
     /*
@@ -9629,6 +9814,17 @@
 	    if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
 	        xmlFree((xmlChar *) atts[i]);
     }
+
+    /*
+     * We can't switch from one entity to another in the middle
+     * of a start tag
+     */
+    if (inputNr != ctxt->inputNr) {
+        xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+		    "Start tag doesn't start and stop in the same entity\n");
+	return(NULL);
+    }
+
     ctxt->input->cur = ctxt->input->base + cur;
     ctxt->input->line = oldline;
     ctxt->input->col = oldcol;
@@ -9657,6 +9853,7 @@
 xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
                 const xmlChar *URI, int line, int nsNr, int tlen) {
     const xmlChar *name;
+    size_t curLength;
 
     GROW;
     if ((RAW != '<') || (NXT(1) != '/')) {
@@ -9665,12 +9862,17 @@
     }
     SKIP(2);
 
-    if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
-        if (ctxt->input->cur[tlen] == '>') {
+    curLength = ctxt->input->end - ctxt->input->cur;
+    if ((tlen > 0) && (curLength >= (size_t)tlen) &&
+        (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) {
+        if ((curLength >= (size_t)(tlen + 1)) &&
+	    (ctxt->input->cur[tlen] == '>')) {
 	    ctxt->input->cur += tlen + 1;
+	    ctxt->input->col += tlen + 1;
 	    goto done;
 	}
 	ctxt->input->cur += tlen;
+	ctxt->input->col += tlen;
 	name = (xmlChar*)1;
     } else {
 	if (prefix == NULL)
@@ -9908,7 +10110,7 @@
 	if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
 	    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 	                "detected an error in element content\n");
-	    ctxt->instate = XML_PARSER_EOF;
+	    xmlHaltParser(ctxt);
             break;
 	}
     }
@@ -9943,7 +10145,7 @@
 	xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
 			  xmlParserMaxDepth);
-	ctxt->instate = XML_PARSER_EOF;
+	xmlHaltParser(ctxt);
 	return;
     }
 
@@ -10295,6 +10497,8 @@
 	    encoding = xmlParseEncName(ctxt);
 	    if (RAW != '"') {
 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+		xmlFree((xmlChar *) encoding);
+		return(NULL);
 	    } else
 	        NEXT;
 	} else if (RAW == '\''){
@@ -10302,6 +10506,8 @@
 	    encoding = xmlParseEncName(ctxt);
 	    if (RAW != '\'') {
 		xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+		xmlFree((xmlChar *) encoding);
+		return(NULL);
 	    } else
 	        NEXT;
 	} else {
@@ -10311,8 +10517,10 @@
         /*
          * Non standard parsing, allowing the user to ignore encoding
          */
-        if (ctxt->options & XML_PARSE_IGNORE_ENC)
-            return(encoding);
+        if (ctxt->options & XML_PARSE_IGNORE_ENC) {
+	    xmlFree((xmlChar *) encoding);
+            return(NULL);
+	}
 
 	/*
 	 * UTF-16 encoding stwich has already taken place at this stage,
@@ -10356,7 +10564,11 @@
 
             handler = xmlFindCharEncodingHandler((const char *) encoding);
 	    if (handler != NULL) {
-		xmlSwitchToEncoding(ctxt, handler);
+		if (xmlSwitchToEncoding(ctxt, handler) < 0) {
+		    /* failed to convert */
+		    ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+		    return(NULL);
+		}
 	    } else {
 		xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
 			"Unsupported encoding %s\n", encoding);
@@ -10525,7 +10737,8 @@
 	xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
     }
     xmlParseEncodingDecl(ctxt);
-    if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+    if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+         (ctxt->instate == XML_PARSER_EOF)) {
 	/*
 	 * The XML REC instructs us to stop parsing right here
 	 */
@@ -10649,6 +10862,7 @@
 
     if (CUR == 0) {
 	xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+	return(-1);
     }
 
     /*
@@ -10666,7 +10880,8 @@
 	 * Note that we will switch encoding on the fly.
 	 */
 	xmlParseXMLDecl(ctxt);
-	if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+	if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+	    (ctxt->instate == XML_PARSER_EOF)) {
 	    /*
 	     * The XML REC instructs us to stop parsing right here
 	     */
@@ -10681,6 +10896,10 @@
         ctxt->sax->startDocument(ctxt->userData);
     if (ctxt->instate == XML_PARSER_EOF)
 	return(-1);
+    if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
+        (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
+	ctxt->myDoc->compression = ctxt->input->buf->compressed;
+    }
 
     /*
      * The Misc part of the Prolog
@@ -11031,8 +11250,9 @@
 }
 /**
  * xmlCheckCdataPush:
- * @cur: pointer to the bock of characters
+ * @cur: pointer to the block of characters
  * @len: length of the block in bytes
+ * @complete: 1 if complete CDATA block is passed in, 0 if partial block
  *
  * Check that the block of characters is okay as SCdata content [20]
  *
@@ -11040,7 +11260,7 @@
  *         UTF-8 error occured otherwise
  */
 static int
-xmlCheckCdataPush(const xmlChar *utf, int len) {
+xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
     int ix;
     unsigned char c;
     int codepoint;
@@ -11058,7 +11278,7 @@
 	    else
 	        return(-ix);
 	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
-	    if (ix + 2 > len) return(ix);
+	    if (ix + 2 > len) return(complete ? -ix : ix);
 	    if ((utf[ix+1] & 0xc0 ) != 0x80)
 	        return(-ix);
 	    codepoint = (utf[ix] & 0x1f) << 6;
@@ -11067,7 +11287,7 @@
 	        return(-ix);
 	    ix += 2;
 	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
-	    if (ix + 3 > len) return(ix);
+	    if (ix + 3 > len) return(complete ? -ix : ix);
 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
 	        ((utf[ix+2] & 0xc0) != 0x80))
 		    return(-ix);
@@ -11078,7 +11298,7 @@
 	        return(-ix);
 	    ix += 3;
 	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
-	    if (ix + 4 > len) return(ix);
+	    if (ix + 4 > len) return(complete ? -ix : ix);
 	    if (((utf[ix+1] & 0xc0) != 0x80) ||
 	        ((utf[ix+2] & 0xc0) != 0x80) ||
 		((utf[ix+3] & 0xc0) != 0x80))
@@ -11256,7 +11476,7 @@
 			ctxt->sax->setDocumentLocator(ctxt->userData,
 						      &xmlDefaultSAXLocator);
 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
 			    "PP: entering EOF\n");
@@ -11289,7 +11509,7 @@
 			     * The XML REC instructs us to stop parsing right
 			     * here
 			     */
-			    ctxt->instate = XML_PARSER_EOF;
+			    xmlHaltParser(ctxt);
 			    return(0);
 			}
 			ctxt->standalone = ctxt->input->standalone;
@@ -11345,7 +11565,7 @@
 		cur = ctxt->input->cur[0];
 	        if (cur != '<') {
 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
 			ctxt->sax->endDocument(ctxt->userData);
 		    goto done;
@@ -11377,7 +11597,7 @@
 		    goto done;
 		if (name == NULL) {
 		    spacePop(ctxt);
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 		    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
 			ctxt->sax->endDocument(ctxt->userData);
 		    goto done;
@@ -11544,7 +11764,7 @@
 		if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
 		    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 		                "detected an error in element content\n");
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 		    break;
 		}
 		break;
@@ -11593,7 +11813,7 @@
 		        int tmp;
 
 			tmp = xmlCheckCdataPush(ctxt->input->cur,
-			                        XML_PARSER_BIG_BUFFER_SIZE);
+			                        XML_PARSER_BIG_BUFFER_SIZE, 0);
 			if (tmp < 0) {
 			    tmp = -tmp;
 			    ctxt->input->cur += tmp;
@@ -11616,7 +11836,7 @@
 		} else {
 		    int tmp;
 
-		    tmp = xmlCheckCdataPush(ctxt->input->cur, base);
+		    tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1);
 		    if ((tmp < 0) || (tmp != base)) {
 			tmp = -tmp;
 			ctxt->input->cur += tmp;
@@ -11865,7 +12085,7 @@
 		    goto done;
 		} else {
 		    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-		    ctxt->instate = XML_PARSER_EOF;
+		    xmlHaltParser(ctxt);
 #ifdef DEBUG_PUSH
 		    xmlGenericError(xmlGenericErrorContext,
 			    "PP: entering EOF\n");
@@ -12229,7 +12449,7 @@
 	res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
 	if (res < 0) {
 	    ctxt->errNo = XML_PARSER_EOF;
-	    ctxt->disableSAX = 1;
+	    xmlHaltParser(ctxt);
 	    return (XML_PARSER_EOF);
 	}
         xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
@@ -12283,7 +12503,7 @@
          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
-        ctxt->instate = XML_PARSER_EOF;
+        xmlHaltParser(ctxt);
     }
     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
         return(ctxt->errNo);
@@ -12471,6 +12691,33 @@
 #endif /* LIBXML_PUSH_ENABLED */
 
 /**
+ * xmlHaltParser:
+ * @ctxt:  an XML parser context
+ *
+ * Blocks further parser processing don't override error
+ * for internal use
+ */
+static void
+xmlHaltParser(xmlParserCtxtPtr ctxt) {
+    if (ctxt == NULL)
+        return;
+    ctxt->instate = XML_PARSER_EOF;
+    ctxt->disableSAX = 1;
+    if (ctxt->input != NULL) {
+        /*
+	 * in case there was a specific allocation deallocate before
+	 * overriding base
+	 */
+        if (ctxt->input->free != NULL) {
+	    ctxt->input->free((xmlChar *) ctxt->input->base);
+	    ctxt->input->free = NULL;
+	}
+	ctxt->input->cur = BAD_CAST"";
+	ctxt->input->base = ctxt->input->cur;
+    }
+}
+
+/**
  * xmlStopParser:
  * @ctxt:  an XML parser context
  *
@@ -12480,13 +12727,8 @@
 xmlStopParser(xmlParserCtxtPtr ctxt) {
     if (ctxt == NULL)
         return;
-    ctxt->instate = XML_PARSER_EOF;
+    xmlHaltParser(ctxt);
     ctxt->errNo = XML_ERR_USER_STOP;
-    ctxt->disableSAX = 1;
-    if (ctxt->input != NULL) {
-	ctxt->input->cur = BAD_CAST"";
-	ctxt->input->base = ctxt->input->cur;
-    }
 }
 
 /**
@@ -12591,6 +12833,9 @@
 	return(NULL);
     }
 
+    /* We are loading a DTD */
+    ctxt->options |= XML_PARSE_DTDLOAD;
+
     /*
      * Set-up the SAX context
      */
@@ -12718,6 +12963,9 @@
 	return(NULL);
     }
 
+    /* We are loading a DTD */
+    ctxt->options |= XML_PARSE_DTDLOAD;
+
     /*
      * Set-up the SAX context
      */
@@ -13227,7 +13475,7 @@
     /*
      * Also record the size of the entity parsed
      */
-    if (ctxt->input != NULL) {
+    if (ctxt->input != NULL && oldctxt != NULL) {
 	oldctxt->sizeentities += ctxt->input->consumed;
 	oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
     }
@@ -13239,9 +13487,11 @@
 
     if (sax != NULL)
 	ctxt->sax = oldsax;
-    oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
-    oldctxt->node_seq.length = ctxt->node_seq.length;
-    oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    if (oldctxt != NULL) {
+        oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
+        oldctxt->node_seq.length = ctxt->node_seq.length;
+        oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+    }
     ctxt->node_seq.maximum = 0;
     ctxt->node_seq.length = 0;
     ctxt->node_seq.buffer = NULL;
@@ -13607,7 +13857,7 @@
 	    xmlFree((xmlChar *) ctxt->encoding);
         ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
 
-        hdlr = xmlFindCharEncodingHandler(doc->encoding);
+        hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
         if (hdlr != NULL) {
             xmlSwitchToEncoding(ctxt, hdlr);
 	} else {
@@ -13618,6 +13868,8 @@
     xmlCtxtUseOptionsInternal(ctxt, options, NULL);
     xmlDetectSAX2(ctxt);
     ctxt->myDoc = doc;
+    /* parsing in context, i.e. as within existing content */
+    ctxt->instate = XML_PARSER_CONTENT;
 
     fake = xmlNewComment(NULL);
     if (fake == NULL) {
@@ -13653,7 +13905,6 @@
 	    }
 	    cur = cur->parent;
 	}
-	ctxt->instate = XML_PARSER_CONTENT;
     }
 
     if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
@@ -14763,8 +15014,8 @@
     xmlSchemaCleanupTypes();
     xmlRelaxNGCleanupTypes();
 #endif
-    xmlCleanupGlobals();
     xmlResetLastError();
+    xmlCleanupGlobals();
     xmlCleanupThreads(); /* must be last if called not from the main thread */
     xmlCleanupMemory();
     xmlParserInitialized = 0;
@@ -14780,7 +15031,7 @@
  * DICT_FREE:
  * @str:  a string
  *
- * Free a string if it is not owned by the "dict" dictionnary in the
+ * Free a string if it is not owned by the "dict" dictionary in the
  * current scope
  */
 #define DICT_FREE(str)						\
@@ -15213,6 +15464,7 @@
 
     if (cur == NULL)
         return (NULL);
+    xmlInitParser();
 
     ctxt = xmlCreateDocParserCtxt(cur);
     if (ctxt == NULL)
@@ -15235,6 +15487,7 @@
 {
     xmlParserCtxtPtr ctxt;
 
+    xmlInitParser();
     ctxt = xmlCreateURLParserCtxt(filename, options);
     if (ctxt == NULL)
         return (NULL);
@@ -15258,6 +15511,7 @@
 {
     xmlParserCtxtPtr ctxt;
 
+    xmlInitParser();
     ctxt = xmlCreateMemoryParserCtxt(buffer, size);
     if (ctxt == NULL)
         return (NULL);
@@ -15286,6 +15540,7 @@
 
     if (fd < 0)
         return (NULL);
+    xmlInitParser();
 
     input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
     if (input == NULL)
@@ -15329,6 +15584,7 @@
 
     if (ioread == NULL)
         return (NULL);
+    xmlInitParser();
 
     input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
                                          XML_CHAR_ENCODING_NONE);
@@ -15375,6 +15631,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     xmlCtxtReset(ctxt);
 
@@ -15408,6 +15665,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     xmlCtxtReset(ctxt);
 
@@ -15444,6 +15702,7 @@
         return (NULL);
     if (buffer == NULL)
         return (NULL);
+    xmlInitParser();
 
     xmlCtxtReset(ctxt);
 
@@ -15488,6 +15747,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     xmlCtxtReset(ctxt);
 
@@ -15533,6 +15793,7 @@
         return (NULL);
     if (ctxt == NULL)
         return (NULL);
+    xmlInitParser();
 
     xmlCtxtReset(ctxt);
 
diff --git a/parserInternals.c b/parserInternals.c
index f8a7041..bfc778a 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -55,6 +55,10 @@
 #include <libxml/globals.h>
 #include <libxml/chvalid.h>
 
+#define CUR(ctxt) ctxt->input->cur
+#define END(ctxt) ctxt->input->end
+#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
+
 #include "buf.h"
 #include "enc.h"
 
@@ -165,7 +169,7 @@
  *
  * Handle an internal error
  */
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
 {
     if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
@@ -193,7 +197,7 @@
  *
  * n encoding error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
                   const char *msg, int val)
 {
@@ -294,7 +298,7 @@
  */
 int
 xmlParserInputGrow(xmlParserInputPtr in, int len) {
-    size_t ret;
+    int ret;
     size_t indx;
     const xmlChar *content;
 
@@ -422,103 +426,105 @@
         (ctxt->input == NULL))
         return;
 
-    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-        if ((*ctxt->input->cur == 0) &&
-            (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
-            (ctxt->instate != XML_PARSER_COMMENT)) {
-            /*
-             * If we are at the end of the current entity and
-             * the context allows it, we pop consumed entities
-             * automatically.
-             * the auto closing should be blocked in other cases
-             */
+    if (!(VALID_CTXT(ctxt))) {
+        xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
+	ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+        xmlStopParser(ctxt);
+	return;
+    }
+
+    if ((*ctxt->input->cur == 0) &&
+        (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
+        if ((ctxt->instate != XML_PARSER_COMMENT))
             xmlPopInput(ctxt);
-        } else {
-            const unsigned char *cur;
-            unsigned char c;
+        return;
+    }
 
-            /*
-             *   2.11 End-of-Line Handling
-             *   the literal two-character sequence "#xD#xA" or a standalone
-             *   literal #xD, an XML processor must pass to the application
-             *   the single character #xA.
-             */
-            if (*(ctxt->input->cur) == '\n') {
-                ctxt->input->line++; ctxt->input->col = 1;
-            } else
-                ctxt->input->col++;
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+        const unsigned char *cur;
+        unsigned char c;
 
-            /*
-             * We are supposed to handle UTF8, check it's valid
-             * From rfc2044: encoding of the Unicode values on UTF-8:
-             *
-             * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
-             * 0000 0000-0000 007F   0xxxxxxx
-             * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
-             * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
-             *
-             * Check for the 0x110000 limit too
-             */
-            cur = ctxt->input->cur;
+        /*
+         *   2.11 End-of-Line Handling
+         *   the literal two-character sequence "#xD#xA" or a standalone
+         *   literal #xD, an XML processor must pass to the application
+         *   the single character #xA.
+         */
+        if (*(ctxt->input->cur) == '\n') {
+            ctxt->input->line++; ctxt->input->col = 1;
+        } else
+            ctxt->input->col++;
 
-            c = *cur;
-            if (c & 0x80) {
-	        if (c == 0xC0)
-		    goto encoding_error;
-                if (cur[1] == 0) {
+        /*
+         * We are supposed to handle UTF8, check it's valid
+         * From rfc2044: encoding of the Unicode values on UTF-8:
+         *
+         * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
+         * 0000 0000-0000 007F   0xxxxxxx
+         * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
+         * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
+         *
+         * Check for the 0x110000 limit too
+         */
+        cur = ctxt->input->cur;
+
+        c = *cur;
+        if (c & 0x80) {
+        if (c == 0xC0)
+	    goto encoding_error;
+            if (cur[1] == 0) {
+                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+                cur = ctxt->input->cur;
+            }
+            if ((cur[1] & 0xc0) != 0x80)
+                goto encoding_error;
+            if ((c & 0xe0) == 0xe0) {
+                unsigned int val;
+
+                if (cur[2] == 0) {
                     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                     cur = ctxt->input->cur;
                 }
-                if ((cur[1] & 0xc0) != 0x80)
+                if ((cur[2] & 0xc0) != 0x80)
                     goto encoding_error;
-                if ((c & 0xe0) == 0xe0) {
-                    unsigned int val;
-
-                    if (cur[2] == 0) {
+                if ((c & 0xf0) == 0xf0) {
+                    if (cur[3] == 0) {
                         xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
                         cur = ctxt->input->cur;
                     }
-                    if ((cur[2] & 0xc0) != 0x80)
+                    if (((c & 0xf8) != 0xf0) ||
+                        ((cur[3] & 0xc0) != 0x80))
                         goto encoding_error;
-                    if ((c & 0xf0) == 0xf0) {
-                        if (cur[3] == 0) {
-                            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-                            cur = ctxt->input->cur;
-                        }
-                        if (((c & 0xf8) != 0xf0) ||
-                            ((cur[3] & 0xc0) != 0x80))
-                            goto encoding_error;
-                        /* 4-byte code */
-                        ctxt->input->cur += 4;
-                        val = (cur[0] & 0x7) << 18;
-                        val |= (cur[1] & 0x3f) << 12;
-                        val |= (cur[2] & 0x3f) << 6;
-                        val |= cur[3] & 0x3f;
-                    } else {
-                        /* 3-byte code */
-                        ctxt->input->cur += 3;
-                        val = (cur[0] & 0xf) << 12;
-                        val |= (cur[1] & 0x3f) << 6;
-                        val |= cur[2] & 0x3f;
-                    }
-                    if (((val > 0xd7ff) && (val < 0xe000)) ||
-                        ((val > 0xfffd) && (val < 0x10000)) ||
-                        (val >= 0x110000)) {
-			xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-					  "Char 0x%X out of allowed range\n",
-					  val);
-                    }
-                } else
-                    /* 2-byte code */
-                    ctxt->input->cur += 2;
+                    /* 4-byte code */
+                    ctxt->input->cur += 4;
+                    val = (cur[0] & 0x7) << 18;
+                    val |= (cur[1] & 0x3f) << 12;
+                    val |= (cur[2] & 0x3f) << 6;
+                    val |= cur[3] & 0x3f;
+                } else {
+                    /* 3-byte code */
+                    ctxt->input->cur += 3;
+                    val = (cur[0] & 0xf) << 12;
+                    val |= (cur[1] & 0x3f) << 6;
+                    val |= cur[2] & 0x3f;
+                }
+                if (((val > 0xd7ff) && (val < 0xe000)) ||
+                    ((val > 0xfffd) && (val < 0x10000)) ||
+                    (val >= 0x110000)) {
+		xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x%X out of allowed range\n",
+				  val);
+                }
             } else
-                /* 1-byte code */
-                ctxt->input->cur++;
+                /* 2-byte code */
+                ctxt->input->cur += 2;
+        } else
+            /* 1-byte code */
+            ctxt->input->cur++;
 
-            ctxt->nbChars++;
-            if (*ctxt->input->cur == 0)
-                xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
-        }
+        ctxt->nbChars++;
+        if (*ctxt->input->cur == 0)
+            xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
     } else {
         /*
          * Assume it's a fixed length encoding (1) with
@@ -937,6 +943,7 @@
 {
     xmlCharEncodingHandlerPtr handler;
     int len = -1;
+    int ret;
 
     if (ctxt == NULL) return(-1);
     switch (enc) {
@@ -1097,7 +1104,15 @@
     if (handler == NULL)
 	return(-1);
     ctxt->charset = XML_CHAR_ENCODING_UTF8;
-    return(xmlSwitchToEncodingInt(ctxt, handler, len));
+    ret = xmlSwitchToEncodingInt(ctxt, handler, len);
+    if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
+        /*
+	 * on encoding conversion errors, stop the parser
+	 */
+        xmlStopParser(ctxt);
+	ctxt->errNo = XML_I18N_CONV_FAILED;
+    }
+    return(ret);
 }
 
 /**
@@ -1450,6 +1465,8 @@
     if (entity->URI != NULL)
 	input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
     input->base = entity->content;
+    if (entity->length == 0)
+        entity->length = xmlStrlen(entity->content);
     input->cur = entity->content;
     input->length = entity->length;
     input->end = &entity->content[input->length];
@@ -1691,12 +1708,20 @@
     ctxt->nsWellFormed = 1;
     ctxt->valid = 1;
     ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
+    if (ctxt->loadsubset) {
+        ctxt->options |= XML_PARSE_DTDLOAD;
+    }
     ctxt->validate = xmlDoValidityCheckingDefaultValue;
     ctxt->pedantic = xmlPedanticParserDefaultValue;
+    if (ctxt->pedantic) {
+        ctxt->options |= XML_PARSE_PEDANTIC;
+    }
     ctxt->linenumbers = xmlLineNumbersDefaultValue;
     ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
-    if (ctxt->keepBlanks == 0)
+    if (ctxt->keepBlanks == 0) {
 	ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+	ctxt->options |= XML_PARSE_NOBLANKS;
+    }
 
     ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
     ctxt->vctxt.userData = ctxt;
@@ -1708,8 +1733,12 @@
 	else
 	    ctxt->vctxt.warning = xmlParserValidityWarning;
 	ctxt->vctxt.nodeMax = 0;
+        ctxt->options |= XML_PARSE_DTDVALID;
     }
     ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
+    if (ctxt->replaceEntities) {
+        ctxt->options |= XML_PARSE_NOENT;
+    }
     ctxt->record_info = 0;
     ctxt->nbChars = 0;
     ctxt->checkIndex = 0;
@@ -1990,7 +2019,8 @@
 
     /* Otherwise, we need to add new node to buffer */
     else {
-        if (ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) {
+        if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
+	    (ctxt->node_seq.buffer == NULL)) {
             xmlParserNodeInfo *tmp_buffer;
             unsigned int byte_size;
 
diff --git a/relaxng.c b/relaxng.c
index 370e314..3d3e69c 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -507,7 +507,7 @@
  *
  * Handle a Relax NG Parsing error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -541,7 +541,7 @@
  *
  * Handle a Relax NG Validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error,
            const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -1095,7 +1095,7 @@
 {
     int i;
 
-    if (state == NULL) {
+    if (state == NULL || states == NULL) {
         return (-1);
     }
     if (states->nbState >= states->maxState) {
@@ -2088,6 +2088,7 @@
                          const xmlChar * arg2)
 {
     char msg[1000];
+    xmlChar *result;
 
     if (arg1 == NULL)
         arg1 = BAD_CAST "";
@@ -2215,7 +2216,8 @@
         snprintf(msg, 1000, "Unknown error code %d\n", err);
     }
     msg[1000 - 1] = 0;
-    return (xmlStrdup((xmlChar *) msg));
+    result = xmlCharStrdup(msg);
+    return (xmlEscapeFormatString(&result));
 }
 
 /**
@@ -2595,13 +2597,10 @@
     }
     ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
     if (ret != 0) {
-	if ((comp1 == NULL) && (res1 != NULL))
+	if (res1 != (xmlSchemaValPtr) comp1)
 	    xmlSchemaFreeValue(res1);
         return (-1);
     }
-    if (res1 == NULL) {
-        return (-1);
-    }
     ret = xmlSchemaCompareValues(res1, res2);
     if (res1 != (xmlSchemaValPtr) comp1)
         xmlSchemaFreeValue(res1);
@@ -3822,7 +3821,11 @@
             return (0);
         return (1);
     } else if (def1->type == XML_RELAXNG_EXCEPT) {
-        TODO ret = 0;
+        ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
+	if (ret == 0)
+	    ret = 1;
+	else if (ret == 1)
+	    ret = 0;
     } else {
         TODO ret = 0;
     }
@@ -6603,7 +6606,7 @@
     }
 
     /*
-     * Apply 4.17 mergingd rules to defines and starts
+     * Apply 4.17 merging rules to defines and starts
      */
     xmlRelaxNGCombineStart(ctxt, ret);
     if (ret->defs != NULL) {
@@ -6655,12 +6658,17 @@
     ctxt->define = NULL;
     if (IS_RELAXNG(node, "grammar")) {
         schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+        if (schema->topgrammar == NULL) {
+            xmlRelaxNGFree(schema);
+            return (NULL);
+        }
     } else {
         xmlRelaxNGGrammarPtr tmp, ret;
 
         schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
         if (schema->topgrammar == NULL) {
-            return (schema);
+            xmlRelaxNGFree(schema);
+            return (NULL);
         }
         /*
          * Link the new grammar in the tree
@@ -7317,7 +7325,7 @@
                     }
                 }
                 /*
-                 * Thisd is not an else since "include" is transformed
+                 * This is not an else since "include" is transformed
                  * into a div
                  */
                 if (xmlStrEqual(cur->name, BAD_CAST "div")) {
@@ -7346,13 +7354,13 @@
                     if (ns != NULL)
                         xmlFree(ns);
 		    /*
-		     * Since we are about to delete cur, if it's nsDef is non-NULL we
+		     * Since we are about to delete cur, if its nsDef is non-NULL we
 		     * need to preserve it (it contains the ns definitions for the
 		     * children we just moved).  We'll just stick it on to the end
 		     * of cur->parent's list, since it's never going to be re-serialized
 		     * (bug 143738).
 		     */
-		    if (cur->nsDef != NULL) {
+		    if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
 			xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
 			while (parDef->next != NULL)
 			    parDef = parDef->next;
@@ -7370,7 +7378,8 @@
         else if ((cur->type == XML_TEXT_NODE) ||
                  (cur->type == XML_CDATA_SECTION_NODE)) {
             if (IS_BLANK_NODE(cur)) {
-                if (cur->parent->type == XML_ELEMENT_NODE) {
+                if ((cur->parent != NULL) &&
+		    (cur->parent->type == XML_ELEMENT_NODE)) {
                     if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
                         &&
                         (!xmlStrEqual
@@ -9050,6 +9059,19 @@
                 return (ret);
             list = list->next;
         }
+    } else if (define->type == XML_RELAXNG_CHOICE) {
+        xmlRelaxNGDefinePtr list;
+
+        list = define->nameClass;
+        while (list != NULL) {
+            ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
+            if (ret == 1)
+                return (1);
+            if (ret < 0)
+                return (ret);
+            list = list->next;
+        }
+        return (0);
     } else {
     TODO}
     return (1);
@@ -9409,6 +9431,10 @@
     oldstate = ctxt->state;
     for (i = 0; i < nbgroups; i++) {
         ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
+	if (ctxt->state == NULL) {
+	    ret = -1;
+	    break;
+	}
         group = partitions->groups[i];
         if (lasts[i] != NULL) {
             last = lasts[i]->next;
@@ -9839,7 +9865,7 @@
     ctxt->depth++;
     switch (define->type) {
         case XML_RELAXNG_EMPTY:
-            node = xmlRelaxNGSkipIgnored(ctxt, node);
+            xmlRelaxNGSkipIgnored(ctxt, node);
             ret = 0;
             break;
         case XML_RELAXNG_NOT_ALLOWED:
diff --git a/schematron.c b/schematron.c
index 537b868..6200f2d 100644
--- a/schematron.c
+++ b/schematron.c
@@ -133,7 +133,7 @@
     int flags;			/* specific to this schematron */
 
     void *_private;		/* unused by the library */
-    xmlDictPtr dict;		/* the dictionnary used internally */
+    xmlDictPtr dict;		/* the dictionary used internally */
 
     const xmlChar *title;	/* the title if any */
 
@@ -165,8 +165,10 @@
 
     FILE *outputFile;		/* if using XML_SCHEMATRON_OUT_FILE */
     xmlBufferPtr outputBuffer;	/* if using XML_SCHEMATRON_OUT_BUFFER */
+#ifdef LIBXML_OUTPUT_ENABLED
     xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
     xmlOutputCloseCallback  ioclose;
+#endif
     void *ioctx;
 
     /* error reporting data */
@@ -184,7 +186,7 @@
     const char *buffer;
     int size;
 
-    xmlDictPtr dict;            /* dictionnary for interned string names */
+    xmlDictPtr dict;            /* dictionary for interned string names */
 
     int nberrors;
     int err;
@@ -243,7 +245,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
diff --git a/testlimits.c b/testlimits.c
new file mode 100644
index 0000000..577f593
--- /dev/null
+++ b/testlimits.c
@@ -0,0 +1,1637 @@
+/*
+ * testlimits.c: C program to run libxml2 regression tests checking various
+ *       limits in document size. Will consume a lot of RAM and CPU cycles
+ *
+ * To compile on Unixes:
+ * cc -o testlimits `xml2-config --cflags` testlimits.c `xml2-config --libs` -lpthread
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+#include <stdio.h>
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#ifdef LIBXML_READER_ENABLED
+#include <libxml/xmlreader.h>
+#endif
+
+static int verbose = 0;
+static int tests_quiet = 0;
+
+/************************************************************************
+ *									*
+ *		time handling                                           *
+ *									*
+ ************************************************************************/
+
+/* maximum time for one parsing before declaring a timeout */
+#define MAX_TIME 2 /* seconds */
+
+static clock_t t0;
+int timeout = 0;
+
+static void reset_timout(void) {
+    timeout = 0;
+    t0 = clock();
+}
+
+static int check_time(void) {
+    clock_t tnow = clock();
+    if (((tnow - t0) / CLOCKS_PER_SEC) > MAX_TIME) {
+        timeout = 1;
+        return(0);
+    }
+    return(1);
+}
+
+/************************************************************************
+ *									*
+ *		Huge document generator					*
+ *									*
+ ************************************************************************/
+
+#include <libxml/xmlIO.h>
+
+/*
+ * Huge documents are built using fixed start and end chunks
+ * and filling between the two an unconventional amount of char data
+ */
+typedef struct hugeTest hugeTest;
+typedef hugeTest *hugeTestPtr;
+struct hugeTest {
+    const char *description;
+    const char *name;
+    const char *start;
+    const char *end;
+};
+
+static struct hugeTest hugeTests[] = {
+    { "Huge text node", "huge:textNode", "<foo>", "</foo>" },
+    { "Huge attribute node", "huge:attrNode", "<foo bar='", "'/>" },
+    { "Huge comment node", "huge:commentNode", "<foo><!--", "--></foo>" },
+    { "Huge PI node", "huge:piNode", "<foo><?bar ", "?></foo>" },
+};
+
+static const char *current;
+static int rlen;
+static unsigned int currentTest = 0;
+static int instate = 0;
+
+/**
+ * hugeMatch:
+ * @URI: an URI to test
+ *
+ * Check for an huge: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+static int
+hugeMatch(const char * URI) {
+    if ((URI != NULL) && (!strncmp(URI, "huge:", 5)))
+        return(1);
+    return(0);
+}
+
+/**
+ * hugeOpen:
+ * @URI: an URI to test
+ *
+ * Return a pointer to the huge: query handler, in this example simply
+ * the current pointer...
+ *
+ * Returns an Input context or NULL in case or error
+ */
+static void *
+hugeOpen(const char * URI) {
+    if ((URI == NULL) || (strncmp(URI, "huge:", 5)))
+        return(NULL);
+
+    for (currentTest = 0;currentTest < sizeof(hugeTests)/sizeof(hugeTests[0]);
+         currentTest++)
+         if (!strcmp(hugeTests[currentTest].name, URI))
+             goto found;
+
+    return(NULL);
+
+found:
+    rlen = strlen(hugeTests[currentTest].start);
+    current = hugeTests[currentTest].start;
+    instate = 0;
+    return((void *) current);
+}
+
+/**
+ * hugeClose:
+ * @context: the read context
+ *
+ * Close the huge: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+static int
+hugeClose(void * context) {
+    if (context == NULL) return(-1);
+    fprintf(stderr, "\n");
+    return(0);
+}
+
+#define CHUNK 4096
+
+char filling[CHUNK + 1];
+
+static void fillFilling(void) {
+    int i;
+
+    for (i = 0;i < CHUNK;i++) {
+        filling[i] = 'a';
+    }
+    filling[CHUNK] = 0;
+}
+
+size_t maxlen = 64 * 1024 * 1024;
+size_t curlen = 0;
+size_t dotlen;
+
+/**
+ * hugeRead:
+ * @context: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an huge: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+static int
+hugeRead(void *context, char *buffer, int len)
+{
+    if ((context == NULL) || (buffer == NULL) || (len < 0))
+        return (-1);
+
+    if (instate == 0) {
+        if (len >= rlen) {
+            len = rlen;
+            rlen = 0;
+            memcpy(buffer, current, len);
+            instate = 1;
+            curlen = 0;
+            dotlen = maxlen / 10;
+        } else {
+            memcpy(buffer, current, len);
+            rlen -= len;
+            current += len;
+        }
+    } else if (instate == 2) {
+        if (len >= rlen) {
+            len = rlen;
+            rlen = 0;
+            memcpy(buffer, current, len);
+            instate = 3;
+            curlen = 0;
+        } else {
+            memcpy(buffer, current, len);
+            rlen -= len;
+            current += len;
+        }
+    } else if (instate == 1) {
+        if (len > CHUNK) len = CHUNK;
+        memcpy(buffer, &filling[0], len);
+        curlen += len;
+        if (curlen >= maxlen) {
+            rlen = strlen(hugeTests[currentTest].end);
+            current = hugeTests[currentTest].end;
+            instate = 2;
+	} else {
+            if (curlen > dotlen) {
+                fprintf(stderr, ".");
+                dotlen += maxlen / 10;
+            }
+        }
+    } else
+      len = 0;
+    return (len);
+}
+
+/************************************************************************
+ *									*
+ *		Crazy document generator				*
+ *									*
+ ************************************************************************/
+
+unsigned int crazy_indx = 0;
+
+const char *crazy = "<?xml version='1.0' encoding='UTF-8'?>\
+<?tst ?>\
+<!-- tst -->\
+<!DOCTYPE foo [\
+<?tst ?>\
+<!-- tst -->\
+<!ELEMENT foo (#PCDATA)>\
+<!ELEMENT p (#PCDATA|emph)* >\
+]>\
+<?tst ?>\
+<!-- tst -->\
+<foo bar='foo'>\
+<?tst ?>\
+<!-- tst -->\
+foo\
+<![CDATA[ ]]>\
+</foo>\
+<?tst ?>\
+<!-- tst -->";
+
+/**
+ * crazyMatch:
+ * @URI: an URI to test
+ *
+ * Check for a crazy: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+static int
+crazyMatch(const char * URI) {
+    if ((URI != NULL) && (!strncmp(URI, "crazy:", 6)))
+        return(1);
+    return(0);
+}
+
+/**
+ * crazyOpen:
+ * @URI: an URI to test
+ *
+ * Return a pointer to the crazy: query handler, in this example simply
+ * the current pointer...
+ *
+ * Returns an Input context or NULL in case or error
+ */
+static void *
+crazyOpen(const char * URI) {
+    if ((URI == NULL) || (strncmp(URI, "crazy:", 6)))
+        return(NULL);
+
+    if (crazy_indx > strlen(crazy))
+        return(NULL);
+    reset_timout();
+    rlen = crazy_indx;
+    current = &crazy[0];
+    instate = 0;
+    return((void *) current);
+}
+
+/**
+ * crazyClose:
+ * @context: the read context
+ *
+ * Close the crazy: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+static int
+crazyClose(void * context) {
+    if (context == NULL) return(-1);
+    return(0);
+}
+
+
+/**
+ * crazyRead:
+ * @context: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an crazy: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+static int
+crazyRead(void *context, char *buffer, int len)
+{
+    if ((context == NULL) || (buffer == NULL) || (len < 0))
+        return (-1);
+
+    if ((check_time() <= 0) && (instate == 1)) {
+        fprintf(stderr, "\ntimeout in crazy(%d)\n", crazy_indx);
+        rlen = strlen(crazy) - crazy_indx;
+        current = &crazy[crazy_indx];
+        instate = 2;
+    }
+    if (instate == 0) {
+        if (len >= rlen) {
+            len = rlen;
+            rlen = 0;
+            memcpy(buffer, current, len);
+            instate = 1;
+            curlen = 0;
+        } else {
+            memcpy(buffer, current, len);
+            rlen -= len;
+            current += len;
+        }
+    } else if (instate == 2) {
+        if (len >= rlen) {
+            len = rlen;
+            rlen = 0;
+            memcpy(buffer, current, len);
+            instate = 3;
+            curlen = 0;
+        } else {
+            memcpy(buffer, current, len);
+            rlen -= len;
+            current += len;
+        }
+    } else if (instate == 1) {
+        if (len > CHUNK) len = CHUNK;
+        memcpy(buffer, &filling[0], len);
+        curlen += len;
+        if (curlen >= maxlen) {
+            rlen = strlen(crazy) - crazy_indx;
+            current = &crazy[crazy_indx];
+            instate = 2;
+        }
+    } else
+      len = 0;
+    return (len);
+}
+/************************************************************************
+ *									*
+ *		Libxml2 specific routines				*
+ *									*
+ ************************************************************************/
+
+static int nb_tests = 0;
+static int nb_errors = 0;
+static int nb_leaks = 0;
+static int extraMemoryFromResolver = 0;
+
+/*
+ * We need to trap calls to the resolver to not account memory for the catalog
+ * which is shared to the current running test. We also don't want to have
+ * network downloads modifying tests.
+ */
+static xmlParserInputPtr
+testExternalEntityLoader(const char *URL, const char *ID,
+			 xmlParserCtxtPtr ctxt) {
+    xmlParserInputPtr ret;
+    int memused = xmlMemUsed();
+
+    ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+    extraMemoryFromResolver += xmlMemUsed() - memused;
+
+    return(ret);
+}
+
+/*
+ * Trapping the error messages at the generic level to grab the equivalent of
+ * stderr messages on CLI tools.
+ */
+static char testErrors[32769];
+static int testErrorsSize = 0;
+
+static void XMLCDECL
+channel(void *ctx  ATTRIBUTE_UNUSED, const char *msg, ...) {
+    va_list args;
+    int res;
+
+    if (testErrorsSize >= 32768)
+        return;
+    va_start(args, msg);
+    res = vsnprintf(&testErrors[testErrorsSize],
+                    32768 - testErrorsSize,
+		    msg, args);
+    va_end(args);
+    if (testErrorsSize + res >= 32768) {
+        /* buffer is full */
+	testErrorsSize = 32768;
+	testErrors[testErrorsSize] = 0;
+    } else {
+        testErrorsSize += res;
+    }
+    testErrors[testErrorsSize] = 0;
+}
+
+/**
+ * xmlParserPrintFileContext:
+ * @input:  an xmlParserInputPtr input
+ *
+ * Displays current context within the input content for error tracking
+ */
+
+static void
+xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
+		xmlGenericErrorFunc chanl, void *data ) {
+    const xmlChar *cur, *base;
+    unsigned int n, col;	/* GCC warns if signed, because compared with sizeof() */
+    xmlChar  content[81]; /* space for 80 chars + line terminator */
+    xmlChar *ctnt;
+
+    if (input == NULL) return;
+    cur = input->cur;
+    base = input->base;
+    /* skip backwards over any end-of-lines */
+    while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
+	cur--;
+    }
+    n = 0;
+    /* search backwards for beginning-of-line (to max buff size) */
+    while ((n++ < (sizeof(content)-1)) && (cur > base) &&
+   (*(cur) != '\n') && (*(cur) != '\r'))
+        cur--;
+    if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+    /* calculate the error position in terms of the current position */
+    col = input->cur - cur;
+    /* search forward for end-of-line (to max buff size) */
+    n = 0;
+    ctnt = content;
+    /* copy selected text to our buffer */
+    while ((*cur != 0) && (*(cur) != '\n') &&
+   (*(cur) != '\r') && (n < sizeof(content)-1)) {
+		*ctnt++ = *cur++;
+	n++;
+    }
+    *ctnt = 0;
+    /* print out the selected text */
+    chanl(data ,"%s\n", content);
+    /* create blank line with problem pointer */
+    n = 0;
+    ctnt = content;
+    /* (leave buffer space for pointer + line terminator) */
+    while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
+	if (*(ctnt) != '\t')
+	    *(ctnt) = ' ';
+	ctnt++;
+    }
+    *ctnt++ = '^';
+    *ctnt = 0;
+    chanl(data ,"%s\n", content);
+}
+
+static void
+testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+    char *file = NULL;
+    int line = 0;
+    int code = -1;
+    int domain;
+    void *data = NULL;
+    const char *str;
+    const xmlChar *name = NULL;
+    xmlNodePtr node;
+    xmlErrorLevel level;
+    xmlParserInputPtr input = NULL;
+    xmlParserInputPtr cur = NULL;
+    xmlParserCtxtPtr ctxt = NULL;
+
+    if (err == NULL)
+        return;
+
+    file = err->file;
+    line = err->line;
+    code = err->code;
+    domain = err->domain;
+    level = err->level;
+    node = err->node;
+    if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
+        (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
+	(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
+	ctxt = err->ctxt;
+    }
+    str = err->message;
+
+    if (code == XML_ERR_OK)
+        return;
+
+    if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+        name = node->name;
+
+    /*
+     * Maintain the compatibility with the legacy error handling
+     */
+    if (ctxt != NULL) {
+        input = ctxt->input;
+        if ((input != NULL) && (input->filename == NULL) &&
+            (ctxt->inputNr > 1)) {
+            cur = input;
+            input = ctxt->inputTab[ctxt->inputNr - 2];
+        }
+        if (input != NULL) {
+            if (input->filename)
+                channel(data, "%s:%d: ", input->filename, input->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: ", input->line);
+        }
+    } else {
+        if (file != NULL)
+            channel(data, "%s:%d: ", file, line);
+        else if ((line != 0) && (domain == XML_FROM_PARSER))
+            channel(data, "Entity: line %d: ", line);
+    }
+    if (name != NULL) {
+        channel(data, "element %s: ", name);
+    }
+    if (code == XML_ERR_OK)
+        return;
+    switch (domain) {
+        case XML_FROM_PARSER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_NAMESPACE:
+            channel(data, "namespace ");
+            break;
+        case XML_FROM_DTD:
+        case XML_FROM_VALID:
+            channel(data, "validity ");
+            break;
+        case XML_FROM_HTML:
+            channel(data, "HTML parser ");
+            break;
+        case XML_FROM_MEMORY:
+            channel(data, "memory ");
+            break;
+        case XML_FROM_OUTPUT:
+            channel(data, "output ");
+            break;
+        case XML_FROM_IO:
+            channel(data, "I/O ");
+            break;
+        case XML_FROM_XINCLUDE:
+            channel(data, "XInclude ");
+            break;
+        case XML_FROM_XPATH:
+            channel(data, "XPath ");
+            break;
+        case XML_FROM_XPOINTER:
+            channel(data, "parser ");
+            break;
+        case XML_FROM_REGEXP:
+            channel(data, "regexp ");
+            break;
+        case XML_FROM_MODULE:
+            channel(data, "module ");
+            break;
+        case XML_FROM_SCHEMASV:
+            channel(data, "Schemas validity ");
+            break;
+        case XML_FROM_SCHEMASP:
+            channel(data, "Schemas parser ");
+            break;
+        case XML_FROM_RELAXNGP:
+            channel(data, "Relax-NG parser ");
+            break;
+        case XML_FROM_RELAXNGV:
+            channel(data, "Relax-NG validity ");
+            break;
+        case XML_FROM_CATALOG:
+            channel(data, "Catalog ");
+            break;
+        case XML_FROM_C14N:
+            channel(data, "C14N ");
+            break;
+        case XML_FROM_XSLT:
+            channel(data, "XSLT ");
+            break;
+        default:
+            break;
+    }
+    if (code == XML_ERR_OK)
+        return;
+    switch (level) {
+        case XML_ERR_NONE:
+            channel(data, ": ");
+            break;
+        case XML_ERR_WARNING:
+            channel(data, "warning : ");
+            break;
+        case XML_ERR_ERROR:
+            channel(data, "error : ");
+            break;
+        case XML_ERR_FATAL:
+            channel(data, "error : ");
+            break;
+    }
+    if (code == XML_ERR_OK)
+        return;
+    if (str != NULL) {
+        int len;
+	len = xmlStrlen((const xmlChar *)str);
+	if ((len > 0) && (str[len - 1] != '\n'))
+	    channel(data, "%s\n", str);
+	else
+	    channel(data, "%s", str);
+    } else {
+        channel(data, "%s\n", "out of memory error");
+    }
+    if (code == XML_ERR_OK)
+        return;
+
+    if (ctxt != NULL) {
+        xmlParserPrintFileContextInternal(input, channel, data);
+        if (cur != NULL) {
+            if (cur->filename)
+                channel(data, "%s:%d: \n", cur->filename, cur->line);
+            else if ((line != 0) && (domain == XML_FROM_PARSER))
+                channel(data, "Entity: line %d: \n", cur->line);
+            xmlParserPrintFileContextInternal(cur, channel, data);
+        }
+    }
+    if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
+        (err->int1 < 100) &&
+	(err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
+	xmlChar buf[150];
+	int i;
+
+	channel(data, "%s\n", err->str1);
+	for (i=0;i < err->int1;i++)
+	     buf[i] = ' ';
+	buf[i++] = '^';
+	buf[i] = 0;
+	channel(data, "%s\n", buf);
+    }
+}
+
+static void
+initializeLibxml2(void) {
+    xmlGetWarningsDefaultValue = 0;
+    xmlPedanticParserDefault(0);
+
+    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
+    xmlInitParser();
+    xmlSetExternalEntityLoader(testExternalEntityLoader);
+    xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+    /*
+     * register the new I/O handlers
+     */
+    if (xmlRegisterInputCallbacks(hugeMatch, hugeOpen,
+                                  hugeRead, hugeClose) < 0) {
+        fprintf(stderr, "failed to register Huge handlers\n");
+	exit(1);
+    }
+    if (xmlRegisterInputCallbacks(crazyMatch, crazyOpen,
+                                  crazyRead, crazyClose) < 0) {
+        fprintf(stderr, "failed to register Crazy handlers\n");
+	exit(1);
+    }
+}
+
+/************************************************************************
+ *									*
+ *		SAX empty callbacks                                     *
+ *									*
+ ************************************************************************/
+
+unsigned long callbacks = 0;
+
+/**
+ * isStandaloneCallback:
+ * @ctxt:  An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (0);
+}
+
+/**
+ * hasInternalSubsetCallback:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (0);
+}
+
+/**
+ * hasExternalSubsetCallback:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (0);
+}
+
+/**
+ * internalSubsetCallback:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
+                       const xmlChar * name ATTRIBUTE_UNUSED,
+                       const xmlChar * ExternalID ATTRIBUTE_UNUSED,
+                       const xmlChar * SystemID ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * externalSubsetCallback:
+ * @ctxt:  An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+externalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
+                       const xmlChar * name ATTRIBUTE_UNUSED,
+                       const xmlChar * ExternalID ATTRIBUTE_UNUSED,
+                       const xmlChar * SystemID ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * resolveEntityCallback:
+ * @ctxt:  An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+                      const xmlChar * publicId ATTRIBUTE_UNUSED,
+                      const xmlChar * systemId ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (NULL);
+}
+
+/**
+ * getEntityCallback:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+                  const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (NULL);
+}
+
+/**
+ * getParameterEntityCallback:
+ * @ctxt:  An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+                           const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return (NULL);
+}
+
+
+/**
+ * entityDeclCallback:
+ * @ctxt:  An XML parser context
+ * @name:  the entity name
+ * @type:  the entity type
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @content: the entity value (without processing).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+                   const xmlChar * name ATTRIBUTE_UNUSED,
+                   int type ATTRIBUTE_UNUSED,
+                   const xmlChar * publicId ATTRIBUTE_UNUSED,
+                   const xmlChar * systemId ATTRIBUTE_UNUSED,
+                   xmlChar * content ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * attributeDeclCallback:
+ * @ctxt:  An XML parser context
+ * @name:  the attribute name
+ * @type:  the attribute type
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+                      const xmlChar * elem ATTRIBUTE_UNUSED,
+                      const xmlChar * name ATTRIBUTE_UNUSED,
+                      int type ATTRIBUTE_UNUSED, int def ATTRIBUTE_UNUSED,
+                      const xmlChar * defaultValue ATTRIBUTE_UNUSED,
+                      xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * elementDeclCallback:
+ * @ctxt:  An XML parser context
+ * @name:  the element name
+ * @type:  the element type
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+                    const xmlChar * name ATTRIBUTE_UNUSED,
+                    int type ATTRIBUTE_UNUSED,
+                    xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * notationDeclCallback:
+ * @ctxt:  An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+                     const xmlChar * name ATTRIBUTE_UNUSED,
+                     const xmlChar * publicId ATTRIBUTE_UNUSED,
+                     const xmlChar * systemId ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * unparsedEntityDeclCallback:
+ * @ctxt:  An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+                           const xmlChar * name ATTRIBUTE_UNUSED,
+                           const xmlChar * publicId ATTRIBUTE_UNUSED,
+                           const xmlChar * systemId ATTRIBUTE_UNUSED,
+                           const xmlChar * notationName ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * setDocumentLocatorCallback:
+ * @ctxt:  An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorCallback(void *ctx ATTRIBUTE_UNUSED,
+                           xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * startDocumentCallback:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * endDocumentCallback:
+ * @ctxt:  An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+#if 0
+/**
+ * startElementCallback:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementCallback(void *ctx ATTRIBUTE_UNUSED,
+                     const xmlChar * name ATTRIBUTE_UNUSED,
+                     const xmlChar ** atts ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * endElementCallback:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementCallback(void *ctx ATTRIBUTE_UNUSED,
+                   const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+#endif
+
+/**
+ * charactersCallback:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersCallback(void *ctx ATTRIBUTE_UNUSED,
+                   const xmlChar * ch ATTRIBUTE_UNUSED,
+                   int len ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * referenceCallback:
+ * @ctxt:  An XML parser context
+ * @name:  The entity name
+ *
+ * called when an entity reference is detected.
+ */
+static void
+referenceCallback(void *ctx ATTRIBUTE_UNUSED,
+                  const xmlChar * name ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * ignorableWhitespaceCallback:
+ * @ctxt:  An XML parser context
+ * @ch:  a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceCallback(void *ctx ATTRIBUTE_UNUSED,
+                            const xmlChar * ch ATTRIBUTE_UNUSED,
+                            int len ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * processingInstructionCallback:
+ * @ctxt:  An XML parser context
+ * @target:  the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionCallback(void *ctx ATTRIBUTE_UNUSED,
+                              const xmlChar * target ATTRIBUTE_UNUSED,
+                              const xmlChar * data ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * cdataBlockCallback:
+ * @ctx: the user data (XML parser context)
+ * @value:  The pcdata content
+ * @len:  the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+cdataBlockCallback(void *ctx ATTRIBUTE_UNUSED,
+                   const xmlChar * value ATTRIBUTE_UNUSED,
+                   int len ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * commentCallback:
+ * @ctxt:  An XML parser context
+ * @value:  the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentCallback(void *ctx ATTRIBUTE_UNUSED,
+                const xmlChar * value ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * warningCallback:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a warning messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+warningCallback(void *ctx ATTRIBUTE_UNUSED,
+                const char *msg ATTRIBUTE_UNUSED, ...)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * errorCallback:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorCallback(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
+              ...)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * fatalErrorCallback:
+ * @ctxt:  An XML parser context
+ * @msg:  the message to display/transmit
+ * @...:  extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorCallback(void *ctx ATTRIBUTE_UNUSED,
+                   const char *msg ATTRIBUTE_UNUSED, ...)
+{
+    return;
+}
+
+
+/*
+ * SAX2 specific callbacks
+ */
+
+/**
+ * startElementNsCallback:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
+                       const xmlChar * localname ATTRIBUTE_UNUSED,
+                       const xmlChar * prefix ATTRIBUTE_UNUSED,
+                       const xmlChar * URI ATTRIBUTE_UNUSED,
+                       int nb_namespaces ATTRIBUTE_UNUSED,
+                       const xmlChar ** namespaces ATTRIBUTE_UNUSED,
+                       int nb_attributes ATTRIBUTE_UNUSED,
+                       int nb_defaulted ATTRIBUTE_UNUSED,
+                       const xmlChar ** attributes ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+/**
+ * endElementCallback:
+ * @ctxt:  An XML parser context
+ * @name:  The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
+                     const xmlChar * localname ATTRIBUTE_UNUSED,
+                     const xmlChar * prefix ATTRIBUTE_UNUSED,
+                     const xmlChar * URI ATTRIBUTE_UNUSED)
+{
+    callbacks++;
+    return;
+}
+
+static xmlSAXHandler callbackSAX2HandlerStruct = {
+    internalSubsetCallback,
+    isStandaloneCallback,
+    hasInternalSubsetCallback,
+    hasExternalSubsetCallback,
+    resolveEntityCallback,
+    getEntityCallback,
+    entityDeclCallback,
+    notationDeclCallback,
+    attributeDeclCallback,
+    elementDeclCallback,
+    unparsedEntityDeclCallback,
+    setDocumentLocatorCallback,
+    startDocumentCallback,
+    endDocumentCallback,
+    NULL,
+    NULL,
+    referenceCallback,
+    charactersCallback,
+    ignorableWhitespaceCallback,
+    processingInstructionCallback,
+    commentCallback,
+    warningCallback,
+    errorCallback,
+    fatalErrorCallback,
+    getParameterEntityCallback,
+    cdataBlockCallback,
+    externalSubsetCallback,
+    XML_SAX2_MAGIC,
+    NULL,
+    startElementNsCallback,
+    endElementNsCallback,
+    NULL
+};
+
+static xmlSAXHandlerPtr callbackSAX2Handler = &callbackSAX2HandlerStruct;
+
+/************************************************************************
+ *									*
+ *		The tests front-ends                                     *
+ *									*
+ ************************************************************************/
+
+/**
+ * readerTest:
+ * @filename: the file to parse
+ * @max_size: size of the limit to test
+ * @options: parsing options
+ * @fail: should a failure be reported
+ *
+ * Parse a memory generated file using SAX
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+saxTest(const char *filename, size_t limit, int options, int fail) {
+    int res = 0;
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr doc;
+    xmlSAXHandlerPtr old_sax;
+
+    nb_tests++;
+
+    maxlen = limit;
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL) {
+        fprintf(stderr, "Failed to create parser context\n");
+	return(1);
+    }
+    old_sax = ctxt->sax;
+    ctxt->sax = callbackSAX2Handler;
+    ctxt->userData = NULL;
+    doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+
+    if (doc != NULL) {
+        fprintf(stderr, "SAX parsing generated a document !\n");
+        xmlFreeDoc(doc);
+        res = 0;
+    } else if (ctxt->wellFormed == 0) {
+        if (fail)
+            res = 0;
+        else {
+            fprintf(stderr, "Failed to parse '%s' %lu\n", filename, limit);
+            res = 1;
+        }
+    } else {
+        if (fail) {
+            fprintf(stderr, "Failed to get failure for '%s' %lu\n",
+                    filename, limit);
+            res = 1;
+        } else
+            res = 0;
+    }
+    ctxt->sax = old_sax;
+    xmlFreeParserCtxt(ctxt);
+
+    return(res);
+}
+#ifdef LIBXML_READER_ENABLED
+/**
+ * readerTest:
+ * @filename: the file to parse
+ * @max_size: size of the limit to test
+ * @options: parsing options
+ * @fail: should a failure be reported
+ *
+ * Parse a memory generated file using the xmlReader
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+readerTest(const char *filename, size_t limit, int options, int fail) {
+    xmlTextReaderPtr reader;
+    int res = 0;
+    int ret;
+
+    nb_tests++;
+
+    maxlen = limit;
+    reader = xmlReaderForFile(filename , NULL, options);
+    if (reader == NULL) {
+        fprintf(stderr, "Failed to open '%s' test\n", filename);
+	return(1);
+    }
+    ret = xmlTextReaderRead(reader);
+    while (ret == 1) {
+        ret = xmlTextReaderRead(reader);
+    }
+    if (ret != 0) {
+        if (fail)
+            res = 0;
+        else {
+            if (strncmp(filename, "crazy:", 6) == 0)
+                fprintf(stderr, "Failed to parse '%s' %u\n",
+                        filename, crazy_indx);
+            else
+                fprintf(stderr, "Failed to parse '%s' %lu\n",
+                        filename, limit);
+            res = 1;
+        }
+    } else {
+        if (fail) {
+            if (strncmp(filename, "crazy:", 6) == 0)
+                fprintf(stderr, "Failed to get failure for '%s' %u\n",
+                        filename, crazy_indx);
+            else
+                fprintf(stderr, "Failed to get failure for '%s' %lu\n",
+                        filename, limit);
+            res = 1;
+        } else
+            res = 0;
+    }
+    if (timeout)
+        res = 1;
+    xmlFreeTextReader(reader);
+
+    return(res);
+}
+#endif
+
+/************************************************************************
+ *									*
+ *			Tests descriptions				*
+ *									*
+ ************************************************************************/
+
+typedef int (*functest) (const char *filename, size_t limit, int options,
+                         int fail);
+
+typedef struct limitDesc limitDesc;
+typedef limitDesc *limitDescPtr;
+struct limitDesc {
+    const char *name; /* the huge generator name */
+    size_t limit;     /* the limit to test */
+    int options;      /* extra parser options */
+    int fail;         /* whether the test should fail */
+};
+
+static limitDesc limitDescriptions[] = {
+    /* max length of a text node in content */
+    {"huge:textNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+    {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+    {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+    /* max length of a text node in content */
+    {"huge:attrNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+    {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+    {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+    /* max length of a comment node */
+    {"huge:commentNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+    {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+    {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+    /* max length of a PI node */
+    {"huge:piNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+    {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+    {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+};
+
+typedef struct testDesc testDesc;
+typedef testDesc *testDescPtr;
+struct testDesc {
+    const char *desc; /* descripton of the test */
+    functest    func; /* function implementing the test */
+};
+
+static
+testDesc testDescriptions[] = {
+    { "Parsing of huge files with the sax parser", saxTest},
+/*    { "Parsing of huge files with the tree parser", treeTest}, */
+#ifdef LIBXML_READER_ENABLED
+    { "Parsing of huge files with the reader", readerTest},
+#endif
+    {NULL, NULL}
+};
+
+typedef struct testException testException;
+typedef testException *testExceptionPtr;
+struct testException {
+    unsigned int test;  /* the parser test number */
+    unsigned int limit; /* the limit test number */
+    int fail;           /* new fail value or -1*/
+    size_t size;        /* new limit value or 0 */
+};
+
+static
+testException testExceptions[] = {
+    /* the SAX parser doesn't hit a limit of XML_MAX_TEXT_LENGTH text nodes */
+    { 0, 1, 0, 0},
+};
+
+static int
+launchTests(testDescPtr tst, unsigned int test) {
+    int res = 0, err = 0;
+    unsigned int i, j;
+    size_t limit;
+    int fail;
+
+    if (tst == NULL) return(-1);
+
+    for (i = 0;i < sizeof(limitDescriptions)/sizeof(limitDescriptions[0]);i++) {
+        limit = limitDescriptions[i].limit;
+        fail = limitDescriptions[i].fail;
+        /*
+         * Handle exceptions if any
+         */
+        for (j = 0;j < sizeof(testExceptions)/sizeof(testExceptions[0]);j++) {
+            if ((testExceptions[j].test == test) &&
+                (testExceptions[j].limit == i)) {
+                if (testExceptions[j].fail != -1)
+                    fail = testExceptions[j].fail;
+                if (testExceptions[j].size != 0)
+                    limit = testExceptions[j].size;
+                break;
+            }
+        }
+        res = tst->func(limitDescriptions[i].name, limit,
+                        limitDescriptions[i].options, fail);
+        if (res != 0) {
+            nb_errors++;
+            err++;
+        }
+    }
+    return(err);
+}
+
+
+static int
+runtest(unsigned int i) {
+    int ret = 0, res;
+    int old_errors, old_tests, old_leaks;
+
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+    if ((tests_quiet == 0) && (testDescriptions[i].desc != NULL))
+	printf("## %s\n", testDescriptions[i].desc);
+    res = launchTests(&testDescriptions[i], i);
+    if (res != 0)
+	ret++;
+    if (verbose) {
+	if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	    printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+	else
+	    printf("Ran %d tests, %d errors, %d leaks\n",
+		   nb_tests - old_tests,
+		   nb_errors - old_errors,
+		   nb_leaks - old_leaks);
+    }
+    return(ret);
+}
+
+static int
+launchCrazySAX(unsigned int test, int fail) {
+    int res = 0, err = 0;
+
+    crazy_indx = test;
+
+    res = saxTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
+    if (res != 0) {
+        nb_errors++;
+        err++;
+    }
+    if (tests_quiet == 0)
+        fprintf(stderr, "%c", crazy[test]);
+
+    return(err);
+}
+
+#ifdef LIBXML_READER_ENABLED
+static int
+launchCrazy(unsigned int test, int fail) {
+    int res = 0, err = 0;
+
+    crazy_indx = test;
+
+    res = readerTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
+    if (res != 0) {
+        nb_errors++;
+        err++;
+    }
+    if (tests_quiet == 0)
+        fprintf(stderr, "%c", crazy[test]);
+
+    return(err);
+}
+#endif
+
+static int get_crazy_fail(int test) {
+    /*
+     * adding 1000000 of character 'a' leads to parser failure mostly
+     * everywhere except in those special spots. Need to be updated
+     * each time crazy is updated
+     */
+    int fail = 1;
+    if ((test == 44) || /* PI in Misc */
+        ((test >= 50) && (test <= 55)) || /* Comment in Misc */
+        (test == 79) || /* PI in DTD */
+        ((test >= 85) && (test <= 90)) || /* Comment in DTD */
+        (test == 154) || /* PI in Misc */
+        ((test >= 160) && (test <= 165)) || /* Comment in Misc */
+        ((test >= 178) && (test <= 181)) || /* attribute value */
+        (test == 183) || /* Text */
+        (test == 189) || /* PI in Content */
+        (test == 191) || /* Text */
+        ((test >= 195) && (test <= 200)) || /* Comment in Content */
+        ((test >= 203) && (test <= 206)) || /* Text */
+        (test == 215) || (test == 216) || /* in CDATA */
+        (test == 219) || /* Text */
+        (test == 231) || /* PI in Misc */
+        ((test >= 237) && (test <= 242))) /* Comment in Misc */
+        fail = 0;
+    return(fail);
+}
+
+static int
+runcrazy(void) {
+    int ret = 0, res = 0;
+    int old_errors, old_tests, old_leaks;
+    unsigned int i;
+
+    old_errors = nb_errors;
+    old_tests = nb_tests;
+    old_leaks = nb_leaks;
+
+#ifdef LIBXML_READER_ENABLED
+    if (tests_quiet == 0) {
+	printf("## Crazy tests on reader\n");
+    }
+    for (i = 0;i < strlen(crazy);i++) {
+        res += launchCrazy(i, get_crazy_fail(i));
+        if (res != 0)
+            ret++;
+    }
+#endif
+
+    if (tests_quiet == 0) {
+	printf("\n## Crazy tests on SAX\n");
+    }
+    for (i = 0;i < strlen(crazy);i++) {
+        res += launchCrazySAX(i, get_crazy_fail(i));
+        if (res != 0)
+            ret++;
+    }
+    if (tests_quiet == 0)
+        fprintf(stderr, "\n");
+    if (verbose) {
+	if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+	    printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+	else
+	    printf("Ran %d tests, %d errors, %d leaks\n",
+		   nb_tests - old_tests,
+		   nb_errors - old_errors,
+		   nb_leaks - old_leaks);
+    }
+    return(ret);
+}
+
+
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+    int i, a, ret = 0;
+    int subset = 0;
+
+    fillFilling();
+    initializeLibxml2();
+
+    for (a = 1; a < argc;a++) {
+        if (!strcmp(argv[a], "-v"))
+	    verbose = 1;
+        else if (!strcmp(argv[a], "-quiet"))
+	    tests_quiet = 1;
+        else if (!strcmp(argv[a], "-crazy"))
+	    subset = 1;
+    }
+    if (subset == 0) {
+	for (i = 0; testDescriptions[i].func != NULL; i++) {
+	    ret += runtest(i);
+	}
+    }
+    ret += runcrazy();
+    if ((nb_errors == 0) && (nb_leaks == 0)) {
+        ret = 0;
+	printf("Total %d tests, no errors\n",
+	       nb_tests);
+    } else {
+        ret = 1;
+	printf("Total %d tests, %d errors, %d leaks\n",
+	       nb_tests, nb_errors, nb_leaks);
+    }
+    xmlCleanupParser();
+    xmlMemoryDump();
+
+    return(ret);
+}
diff --git a/threads.c b/threads.c
index f2f2703..b9d6cae 100644
--- a/threads.c
+++ b/threads.c
@@ -47,7 +47,7 @@
 #ifdef HAVE_PTHREAD_H
 
 static int libxml_is_threaded = -1;
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(__GLIBC__)
 #ifdef linux
 #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
 extern int pthread_once (pthread_once_t *__once_control,
@@ -89,7 +89,7 @@
 	   __attribute((weak));
 #endif
 #endif /* linux */
-#endif /* __GNUC__ */
+#endif /* defined(__GNUC__) && defined(__GLIBC__) */
 #endif /* HAVE_PTHREAD_H */
 
 /*
@@ -378,7 +378,7 @@
     pthread_mutex_unlock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
     EnterCriticalSection(&tok->cs);
-    ++tok->count;
+    tok->count++;
 #elif defined HAVE_BEOS_THREADS
     if (tok->lock->tid == find_thread(NULL)) {
         tok->count++;
@@ -414,8 +414,10 @@
     }
     pthread_mutex_unlock(&tok->lock);
 #elif defined HAVE_WIN32_THREADS
-    if (!--tok->count)
+    if (tok->count > 0) {
+	tok->count--;
         LeaveCriticalSection(&tok->cs);
+    }
 #elif defined HAVE_BEOS_THREADS
     if (tok->lock->tid == find_thread(NULL)) {
         tok->count--;
diff --git a/timsort.h b/timsort.h
index 99697a0..795f272 100644
--- a/timsort.h
+++ b/timsort.h
@@ -61,12 +61,12 @@
 
   if (x == 0) return(64);
   n = 0;
-  if (x <= 0x00000000FFFFFFFFL) {n = n + 32; x = x << 32;}
-  if (x <= 0x0000FFFFFFFFFFFFL) {n = n + 16; x = x << 16;}
-  if (x <= 0x00FFFFFFFFFFFFFFL) {n = n + 8; x = x << 8;}
-  if (x <= 0x0FFFFFFFFFFFFFFFL) {n = n + 4; x = x << 4;}
-  if (x <= 0x3FFFFFFFFFFFFFFFL) {n = n + 2; x = x << 2;}
-  if (x <= 0x7FFFFFFFFFFFFFFFL) {n = n + 1;}
+  if (x <= MK_UINT64(0x00000000FFFFFFFF)) {n = n + 32; x = x << 32;}
+  if (x <= MK_UINT64(0x0000FFFFFFFFFFFF)) {n = n + 16; x = x << 16;}
+  if (x <= MK_UINT64(0x00FFFFFFFFFFFFFF)) {n = n + 8; x = x << 8;}
+  if (x <= MK_UINT64(0x0FFFFFFFFFFFFFFF)) {n = n + 4; x = x << 4;}
+  if (x <= MK_UINT64(0x3FFFFFFFFFFFFFFF)) {n = n + 2; x = x << 2;}
+  if (x <= MK_UINT64(0x7FFFFFFFFFFFFFFF)) {n = n + 1;}
   return n;
 }
 /* }}} */
@@ -392,62 +392,66 @@
 
 static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size)
 {
-  while (1)
-  {
-    int64_t A, B, C;
+  while (1) {
+    int64_t A, B, C, D;
+    int ABC, BCD, BD, CD;
+
     /* if the stack only has one thing on it, we are done with the collapse */
-    if (stack_curr <= 1) break;
+    if (stack_curr <= 1) {
+      break;
+    }
+
     /* if this is the last merge, just do it */
-    if ((stack_curr == 2) &&
-        (stack[0].length + stack[1].length == (int64_t) size))
-    {
+    if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
     }
     /* check if the invariant is off for a stack of 2 elements */
-    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length))
-    {
+    else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[0].length += stack[1].length;
       stack_curr--;
       break;
-    }
-    else if (stack_curr == 2)
+    } else if (stack_curr == 2) {
       break;
-
-    A = stack[stack_curr - 3].length;
-    B = stack[stack_curr - 2].length;
-    C = stack[stack_curr - 1].length;
-
-    /* check first invariant */
-    if (A <= B + C)
-    {
-      if (A < C)
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
-        stack[stack_curr - 3].length += stack[stack_curr - 2].length;
-        stack[stack_curr - 2] = stack[stack_curr - 1];
-        stack_curr--;
-      }
-      else
-      {
-        TIM_SORT_MERGE(dst, stack, stack_curr, store);
-        stack[stack_curr - 2].length += stack[stack_curr - 1].length;
-        stack_curr--;
-      }
     }
-    /* check second invariant */
-    else if (B <= C)
-    {
+
+    B = stack[stack_curr - 3].length;
+    C = stack[stack_curr - 2].length;
+    D = stack[stack_curr - 1].length;
+
+    if (stack_curr >= 4) {
+      A = stack[stack_curr - 4].length;
+      ABC = (A <= B + C);
+    } else {
+      ABC = 0;
+    }
+
+    BCD = (B <= C + D) || ABC;
+    CD = (C <= D);
+    BD = (B < D);
+
+    /* Both invariants are good */
+    if (!BCD && !CD) {
+      break;
+    }
+
+    /* left merge */
+    if (BCD && !CD) {
+      TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
+      stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+      stack[stack_curr - 2] = stack[stack_curr - 1];
+      stack_curr--;
+    } else {
+      /* right merge */
       TIM_SORT_MERGE(dst, stack, stack_curr, store);
       stack[stack_curr - 2].length += stack[stack_curr - 1].length;
       stack_curr--;
     }
-    else
-      break;
   }
+
   return stack_curr;
 }
 
diff --git a/tree.c b/tree.c
index 7e5af26..9d330b8 100644
--- a/tree.c
+++ b/tree.c
@@ -55,7 +55,7 @@
 static xmlNsPtr
 xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
 
-static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
+static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
 
 /************************************************************************
  *									*
@@ -160,7 +160,7 @@
  * Returns A pointer to the entity structure or NULL if not found.
  */
 static xmlEntityPtr
-xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+xmlGetEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
     xmlEntitiesTablePtr table;
 
     if((dtd != NULL) && (dtd->entities != NULL)) {
@@ -181,7 +181,7 @@
  * Returns A pointer to the entity structure or NULL if not found.
  */
 static xmlEntityPtr
-xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+xmlGetParameterEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
     xmlEntitiesTablePtr table;
 
     if ((dtd != NULL) && (dtd->pentities != NULL)) {
@@ -352,7 +352,7 @@
 
 #define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
 
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 /**
  * xmlValidateNCName:
  * @value: the value to check
@@ -717,8 +717,11 @@
  * Creation of a new Namespace. This function will refuse to create
  * a namespace with a similar prefix than an existing one present on this
  * node.
+ * Note that for a default namespace, @prefix should be NULL.
+ *
  * We use href==NULL in the case of an element creation where the namespace
  * was not defined.
+ *
  * Returns a new namespace pointer or NULL
  */
 xmlNsPtr
@@ -803,7 +806,9 @@
 #endif
 	return;
     }
-    node->ns = ns;
+    if ((node->type == XML_ELEMENT_NODE) ||
+        (node->type == XML_ATTRIBUTE_NODE))
+	node->ns = ns;
 }
 
 /**
@@ -911,7 +916,7 @@
  */
 
 xmlDtdPtr
-xmlGetIntSubset(xmlDocPtr doc) {
+xmlGetIntSubset(const xmlDoc *doc) {
     xmlNodePtr cur;
 
     if (doc == NULL)
@@ -1039,7 +1044,7 @@
  * DICT_FREE:
  * @str:  a string
  *
- * Free a string if it is not owned by the "dict" dictionnary in the
+ * Free a string if it is not owned by the "dict" dictionary in the
  * current scope
  */
 #define DICT_FREE(str)						\
@@ -1052,7 +1057,7 @@
  * DICT_COPY:
  * @str:  a string
  *
- * Copy a string using a "dict" dictionnary in the current scope,
+ * Copy a string using a "dict" dictionary in the current scope,
  * if availabe.
  */
 #define DICT_COPY(str, cpy) \
@@ -1069,7 +1074,7 @@
  * DICT_CONST_COPY:
  * @str:  a string
  *
- * Copy a string using a "dict" dictionnary in the current scope,
+ * Copy a string using a "dict" dictionary in the current scope,
  * if availabe.
  */
 #define DICT_CONST_COPY(str, cpy) \
@@ -1261,7 +1266,7 @@
  * Returns a pointer to the first child
  */
 xmlNodePtr
-xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
+xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
     xmlNodePtr ret = NULL, last = NULL;
     xmlNodePtr node;
     xmlChar *val;
@@ -1446,9 +1451,9 @@
 	node->content = xmlBufDetach(buf);
 
 	if (last == NULL) {
-	    last = ret = node;
+	    ret = node;
 	} else {
-	    last = xmlAddNextSibling(last, node);
+	    xmlAddNextSibling(last, node);
 	}
     } else if (ret == NULL) {
         ret = xmlNewDocText(doc, BAD_CAST "");
@@ -1469,7 +1474,7 @@
  * Returns a pointer to the first child
  */
 xmlNodePtr
-xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
+xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
     xmlNodePtr ret = NULL, last = NULL;
     xmlNodePtr node;
     xmlChar *val;
@@ -1588,6 +1593,7 @@
 			else if ((ent != NULL) && (ent->children == NULL)) {
 			    xmlNodePtr temp;
 
+			    ent->children = (xmlNodePtr) -1;
 			    ent->children = xmlStringGetNodeList(doc,
 				    (const xmlChar*)node->content);
 			    ent->owner = 1;
@@ -1634,9 +1640,9 @@
 	node->content = xmlBufDetach(buf);
 
 	if (last == NULL) {
-	    last = ret = node;
+	    ret = node;
 	} else {
-	    last = xmlAddNextSibling(last, node);
+	    xmlAddNextSibling(last, node);
 	}
     }
 
@@ -1657,9 +1663,9 @@
  * Returns a pointer to the string copy, the caller must free it with xmlFree().
  */
 xmlChar *
-xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
 {
-    xmlNodePtr node = list;
+    const xmlNode *node = list;
     xmlChar *ret = NULL;
     xmlEntityPtr ent;
     int attr;
@@ -1747,9 +1753,9 @@
  * Returns a pointer to the string copy, the caller must free it with xmlFree().
  */
 xmlChar *
-xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
 {
-    xmlNodePtr node = list;
+    const xmlNode *node = list;
     xmlChar *ret = NULL;
     xmlEntityPtr ent;
 
@@ -2265,7 +2271,7 @@
     cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode));
     if (cur == NULL) {
 	xmlTreeErrMemory("building node");
-	/* we can't check here that name comes from the doc dictionnary */
+	/* we can't check here that name comes from the doc dictionary */
 	return(NULL);
     }
     memset(cur, 0, sizeof(xmlNode));
@@ -2345,7 +2351,7 @@
 	    UPDATE_LAST_CHILD_AND_PARENT(cur)
 	}
     } else {
-        /* if name don't come from the doc dictionnary free it here */
+        /* if name don't come from the doc dictionary free it here */
         if ((name != NULL) && (doc != NULL) &&
 	    (!(xmlDictOwns(doc->dict, name))))
 	    xmlFree(name);
@@ -2578,7 +2584,7 @@
  * Returns a pointer to the new node object.
  */
 xmlNodePtr
-xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
+xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
     xmlNodePtr cur;
     xmlEntityPtr ent;
 
@@ -2596,7 +2602,7 @@
     memset(cur, 0, sizeof(xmlNode));
     cur->type = XML_ENTITY_REF_NODE;
 
-    cur->doc = doc;
+    cur->doc = (xmlDoc *)doc;
     if (name[0] == '&') {
         int len;
         name++;
@@ -2634,11 +2640,11 @@
  * Returns a pointer to the new node object.
  */
 xmlNodePtr
-xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
+xmlNewDocText(const xmlDoc *doc, const xmlChar *content) {
     xmlNodePtr cur;
 
     cur = xmlNewText(content);
-    if (cur != NULL) cur->doc = doc;
+    if (cur != NULL) cur->doc = (xmlDoc *)doc;
     return(cur);
 }
 
@@ -2794,8 +2800,27 @@
 	if(tree->type == XML_ELEMENT_NODE) {
 	    prop = tree->properties;
 	    while (prop != NULL) {
+                if (prop->atype == XML_ATTRIBUTE_ID) {
+                    xmlRemoveID(tree->doc, prop);
+                }
+
 		prop->doc = doc;
 		xmlSetListDoc(prop->children, doc);
+
+                /*
+                 * TODO: ID attributes should be also added to the new
+                 * document, but this breaks things like xmlReplaceNode.
+                 * The underlying problem is that xmlRemoveID is only called
+                 * if a node is destroyed, not if it's unlinked.
+                 */
+#if 0
+                if (xmlIsID(doc, tree, prop)) {
+                    xmlChar *idVal = xmlNodeListGetString(doc, prop->children,
+                                                          1);
+                    xmlAddID(NULL, doc, idVal, prop);
+                }
+#endif
+
 		prop = prop->next;
 	    }
 	}
@@ -3034,7 +3059,7 @@
 }
 
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
-    defined(LIBXML_SCHEMAS_ENABLED)
+    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
 /**
  * xmlAddPrevSibling:
  * @cur:  the child node
@@ -3412,7 +3437,7 @@
  * Returns the last child or NULL if none.
  */
 xmlNodePtr
-xmlGetLastChild(xmlNodePtr parent) {
+xmlGetLastChild(const xmlNode *parent) {
     if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
 #ifdef DEBUG_TREE
         xmlGenericError(xmlGenericErrorContext,
@@ -3451,6 +3476,7 @@
         case XML_ELEMENT_NODE:
         case XML_ENTITY_NODE:
         case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
         case XML_HTML_DOCUMENT_NODE:
             cur = parent->children;
             break;
@@ -3486,6 +3512,7 @@
         case XML_ELEMENT_NODE:
         case XML_ENTITY_NODE:
         case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
         case XML_HTML_DOCUMENT_NODE:
             cur = parent->children;
             break;
@@ -3521,6 +3548,7 @@
         case XML_ELEMENT_NODE:
         case XML_ENTITY_NODE:
         case XML_DOCUMENT_NODE:
+        case XML_DOCUMENT_FRAG_NODE:
         case XML_HTML_DOCUMENT_NODE:
             cur = parent->last;
             break;
@@ -3674,7 +3702,7 @@
 	     * When a node is a text node or a comment, it uses a global static
 	     * variable for the name of the node.
 	     * Otherwise the node name might come from the document's
-	     * dictionnary
+	     * dictionary
 	     */
 	    if ((cur->name != NULL) &&
 		(cur->type != XML_TEXT_NODE) &&
@@ -3743,7 +3771,7 @@
     /*
      * When a node is a text node or a comment, it uses a global static
      * variable for the name of the node.
-     * Otherwise the node name might come from the document's dictionnary
+     * Otherwise the node name might come from the document's dictionary
      */
     if ((cur->name != NULL) &&
         (cur->type != XML_TEXT_NODE) &&
@@ -4128,7 +4156,7 @@
  */
 
 static xmlNodePtr
-xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
+xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
                   int extended) {
     xmlNodePtr ret;
 
@@ -4294,6 +4322,7 @@
 	    }
 	    if (doc->intSubset == NULL) {
 		q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
+		if (q == NULL) return(NULL);
 		q->doc = doc;
 		q->parent = parent;
 		doc->intSubset = (xmlDtdPtr) q;
@@ -4305,6 +4334,7 @@
 	} else
 #endif /* LIBXML_TREE_ENABLED */
 	    q = xmlStaticCopyNode(node, doc, parent, 1);
+	if (q == NULL) return(NULL);
 	if (ret == NULL) {
 	    q->prev = NULL;
 	    ret = p = q;
@@ -4331,7 +4361,7 @@
  * Returns: a new #xmlNodePtr, or NULL in case of error.
  */
 xmlNodePtr
-xmlCopyNode(const xmlNodePtr node, int extended) {
+xmlCopyNode(xmlNodePtr node, int extended) {
     xmlNodePtr ret;
 
     ret = xmlStaticCopyNode(node, NULL, NULL, extended);
@@ -4351,7 +4381,7 @@
  * Returns: a new #xmlNodePtr, or NULL in case of error.
  */
 xmlNodePtr
-xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
+xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int extended) {
     xmlNodePtr ret;
 
     ret = xmlStaticCopyNode(node, doc, NULL, extended);
@@ -4367,7 +4397,7 @@
  *
  * Returns: a new #xmlNodePtr, or NULL in case of error.
  */
-xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, const xmlNodePtr node) {
+xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, xmlNodePtr node) {
     xmlNodePtr ret = xmlStaticCopyNodeList(node, doc, NULL);
     return(ret);
 }
@@ -4381,7 +4411,7 @@
  *
  * Returns: a new #xmlNodePtr, or NULL in case of error.
  */
-xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
+xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
     xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
     return(ret);
 }
@@ -4507,6 +4537,10 @@
 #ifdef LIBXML_TREE_ENABLED
     if (doc->intSubset != NULL) {
         ret->intSubset = xmlCopyDtd(doc->intSubset);
+	if (ret->intSubset == NULL) {
+	    xmlFreeDoc(ret);
+	    return(NULL);
+	}
 	xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
 	ret->intSubset->parent = ret;
     }
@@ -4547,7 +4581,7 @@
  * Returns the line number if successful, -1 otherwise
  */
 static long
-xmlGetLineNoInternal(xmlNodePtr node, int depth)
+xmlGetLineNoInternal(const xmlNode *node, int depth)
 {
     long result = -1;
 
@@ -4597,7 +4631,7 @@
  * Returns the line number if successful, -1 otherwise
  */
 long
-xmlGetLineNo(xmlNodePtr node)
+xmlGetLineNo(const xmlNode *node)
 {
     return(xmlGetLineNoInternal(node, 0));
 }
@@ -4613,9 +4647,9 @@
  *     the returned string
  */
 xmlChar *
-xmlGetNodePath(xmlNodePtr node)
+xmlGetNodePath(const xmlNode *node)
 {
-    xmlNodePtr cur, tmp, next;
+    const xmlNode *cur, *tmp, *next;
     xmlChar *buffer = NULL, *temp;
     size_t buf_len;
     xmlChar *buf;
@@ -4859,7 +4893,7 @@
  * Returns the #xmlNodePtr for the root or NULL
  */
 xmlNodePtr
-xmlDocGetRootElement(xmlDocPtr doc) {
+xmlDocGetRootElement(const xmlDoc *doc) {
     xmlNodePtr ret;
 
     if (doc == NULL) return(NULL);
@@ -4973,7 +5007,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlNodeGetLang(xmlNodePtr cur) {
+xmlNodeGetLang(const xmlNode *cur) {
     xmlChar *lang;
 
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
@@ -5054,7 +5088,7 @@
  * Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
  */
 int
-xmlNodeGetSpacePreserve(xmlNodePtr cur) {
+xmlNodeGetSpacePreserve(const xmlNode *cur) {
     xmlChar *space;
 
     if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
@@ -5089,6 +5123,7 @@
 xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
     xmlDocPtr doc;
     xmlDictPtr dict;
+    const xmlChar *freeme = NULL;
 
     if (cur == NULL) return;
     if (name == NULL) return;
@@ -5126,12 +5161,16 @@
         dict = NULL;
     if (dict != NULL) {
         if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
-	    xmlFree((xmlChar *) cur->name);
+	    freeme = cur->name;
 	cur->name = xmlDictLookup(dict, name, -1);
     } else {
-	if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
+	if (cur->name != NULL)
+	    freeme = cur->name;
 	cur->name = xmlStrdup(name);
     }
+
+    if (freeme)
+        xmlFree((xmlChar *) freeme);
 }
 #endif
 
@@ -5219,7 +5258,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
+xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
     xmlChar *oldbase = NULL;
     xmlChar *base, *newbase;
 
@@ -5304,7 +5343,7 @@
  * Returns 0 in case of success and -1 in case of error.
  */
 int
-xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
+xmlNodeBufGetContent(xmlBufferPtr buffer, const xmlNode *cur)
 {
     xmlBufPtr buf;
     int ret;
@@ -5327,12 +5366,12 @@
  * directly by this node if it's a TEXT node or the aggregate string
  * of the values carried by this node child's (TEXT and ENTITY_REF).
  * Entity references are substituted.
- * Fills up the buffer @buffer with this value
+ * Fills up the buffer @buf with this value
  *
  * Returns 0 in case of success and -1 in case of error.
  */
 int
-xmlBufGetNodeContent(xmlBufPtr buf, xmlNodePtr cur)
+xmlBufGetNodeContent(xmlBufPtr buf, const xmlNode *cur)
 {
     if ((cur == NULL) || (buf == NULL)) return(-1);
     switch (cur->type) {
@@ -5342,7 +5381,7 @@
             break;
         case XML_DOCUMENT_FRAG_NODE:
         case XML_ELEMENT_NODE:{
-                xmlNodePtr tmp = cur;
+                const xmlNode *tmp = cur;
 
                 while (tmp != NULL) {
                     switch (tmp->type) {
@@ -5473,7 +5512,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlNodeGetContent(xmlNodePtr cur)
+xmlNodeGetContent(const xmlNode *cur)
 {
     if (cur == NULL)
         return (NULL);
@@ -5853,7 +5892,7 @@
  *         namespace if defined
  */
 xmlNsPtr *
-xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
+xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
 {
     xmlNsPtr cur;
     xmlNsPtr *ret = NULL;
@@ -5960,7 +5999,7 @@
 xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
 
     xmlNsPtr cur;
-    xmlNodePtr orig = node;
+    const xmlNode *orig = node;
 
     if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) return(NULL);
     if ((nameSpace != NULL) &&
@@ -6429,7 +6468,7 @@
 #endif /* LIBXML_TREE_ENABLED */
 
 static xmlAttrPtr
-xmlGetPropNodeInternal(xmlNodePtr node, const xmlChar *name,
+xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
 		       const xmlChar *nsName, int useDTD)
 {
     xmlAttrPtr prop;
@@ -6543,7 +6582,7 @@
 }
 
 static xmlChar*
-xmlGetPropNodeValueInternal(xmlAttrPtr prop)
+xmlGetPropNodeValueInternal(const xmlAttr *prop)
 {
     if (prop == NULL)
 	return(NULL);
@@ -6589,7 +6628,7 @@
  *         neither was found.
  */
 xmlAttrPtr
-xmlHasProp(xmlNodePtr node, const xmlChar *name) {
+xmlHasProp(const xmlNode *node, const xmlChar *name) {
     xmlAttrPtr prop;
     xmlDocPtr doc;
 
@@ -6644,7 +6683,7 @@
  *     if neither was found.
  */
 xmlAttrPtr
-xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
 
     return(xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD));
 }
@@ -6666,7 +6705,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlGetProp(xmlNodePtr node, const xmlChar *name) {
+xmlGetProp(const xmlNode *node, const xmlChar *name) {
     xmlAttrPtr prop;
 
     prop = xmlHasProp(node, name);
@@ -6691,7 +6730,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name) {
+xmlGetNoNsProp(const xmlNode *node, const xmlChar *name) {
     xmlAttrPtr prop;
 
     prop = xmlGetPropNodeInternal(node, name, NULL, xmlCheckDTD);
@@ -6716,7 +6755,7 @@
  *     It's up to the caller to free the memory with xmlFree().
  */
 xmlChar *
-xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
     xmlAttrPtr prop;
 
     prop = xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD);
@@ -6881,7 +6920,7 @@
  * Returns 1 yes, 0 no
  */
 int
-xmlNodeIsText(xmlNodePtr node) {
+xmlNodeIsText(const xmlNode *node) {
     if (node == NULL) return(0);
 
     if (node->type == XML_TEXT_NODE) return(1);
@@ -6898,7 +6937,7 @@
  * Returns 1 yes, 0 no
  */
 int
-xmlIsBlankNode(xmlNodePtr node) {
+xmlIsBlankNode(const xmlNode *node) {
     const xmlChar *cur;
     if (node == NULL) return(0);
 
@@ -7301,7 +7340,7 @@
  */
 
 const xmlChar *
-xmlBufferContent(const xmlBufferPtr buf)
+xmlBufferContent(const xmlBuffer *buf)
 {
     if(!buf)
         return NULL;
@@ -7319,7 +7358,7 @@
  */
 
 int
-xmlBufferLength(const xmlBufferPtr buf)
+xmlBufferLength(const xmlBuffer *buf)
 {
     if(!buf)
         return 0;
@@ -7703,7 +7742,7 @@
  * Returns 0 (uncompressed) to 9 (max compression)
  */
 int
-xmlGetDocCompressMode (xmlDocPtr doc) {
+xmlGetDocCompressMode (const xmlDoc *doc) {
     if (doc == NULL) return(-1);
     return(doc->compression);
 }
@@ -7894,8 +7933,7 @@
 	map->first->prev = ret;
 	ret->next = map->first;
 	map->first = ret;
-    } else
-	return(NULL);
+    }
 
     ret->oldNs = oldNs;
     ret->newNs = newNs;
@@ -7955,7 +7993,7 @@
 *
 * Allocates and initializes a new DOM-wrapper context.
 *
-* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal errror.
+* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal error.
 */
 xmlDOMWrapCtxtPtr
 xmlDOMWrapNewCtxt(void)
@@ -9780,7 +9818,8 @@
 	    if (clone->parent != NULL)
 		clone->parent->last = clone;
 	    clone = clone->parent;
-	    parentClone = clone->parent;
+	    if (clone != NULL)
+		parentClone = clone->parent;
 	    /*
 	    * Process parent --> next;
 	    */
@@ -9962,7 +10001,7 @@
 * References of out-of scope ns-decls are remapped to point to @destDoc:
 * 1) If @destParent is given, then nsDef entries on element-nodes are used
 * 2) If *no* @destParent is given, then @destDoc->oldNs entries are used
-*    This is the case when you have an unliked node and just want to move it
+*    This is the case when you have an unlinked node and just want to move it
 *    to the context of
 *
 * If @destParent is given, it ensures that the tree is namespace
diff --git a/trio.c b/trio.c
index d885db9..c8b9c84 100644
--- a/trio.c
+++ b/trio.c
@@ -99,7 +99,7 @@
 #endif
 #include <stddef.h>
 
-#ifdef HAVE_ERRNO_H
+#if defined( HAVE_ERRNO_H ) || defined( __VMS )
 #include <errno.h>
 #endif
 
@@ -126,13 +126,23 @@
 # define TRIO_ERROR_RETURN(x,y) (-1)
 #endif
 
+#ifndef VA_LIST_IS_ARRAY
+#define TRIO_VA_LIST_PTR	va_list *
+#define TRIO_VA_LIST_ADDR(l)	(&(l))
+#define TRIO_VA_LIST_DEREF(l)	(*(l))
+#else
+#define TRIO_VA_LIST_PTR	va_list
+#define TRIO_VA_LIST_ADDR(l)	(l)
+#define TRIO_VA_LIST_DEREF(l)	(l)
+#endif
+
 typedef unsigned long trio_flags_t;
 
 
 /*************************************************************************
  * Platform specific definitions
  */
-#if defined(TRIO_PLATFORM_UNIX)
+#if defined(TRIO_PLATFORM_UNIX) || defined(TRIO_PLATFORM_OS400)
 # include <unistd.h>
 # include <signal.h>
 # include <locale.h>
@@ -208,7 +218,7 @@
 #endif
 
 /* Maximal and fixed integer types */
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
+#if defined(TRIO_COMPILER_SUPPORTS_C99) && !defined( __VMS )
 # include <stdint.h>
 typedef intmax_t trio_intmax_t;
 typedef uintmax_t trio_uintmax_t;
@@ -216,8 +226,12 @@
 typedef int16_t trio_int16_t;
 typedef int32_t trio_int32_t;
 typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
+#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) || defined( __VMS )
 # include <inttypes.h>
+#ifdef __VMS
+typedef long long int          intmax_t;
+typedef unsigned long long int uintmax_t;
+#endif
 typedef intmax_t trio_intmax_t;
 typedef uintmax_t trio_uintmax_t;
 typedef int8_t trio_int8_t;
@@ -308,7 +322,9 @@
 #define NAN_UPPER "NAN"
 
 #if !defined(HAVE_ISASCII) && !defined(isascii)
-#  define isascii(x) ((unsigned int)(x) < 128)
+#ifndef __VMS
+# define isascii(x) ((unsigned int)(x) < 128)
+#endif
 #endif
 
 /* Various constants */
@@ -1167,7 +1183,7 @@
 	   int type,
 	   TRIO_CONST char *format,
 	   trio_parameter_t *parameters,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   /* Count the number of times a parameter is referenced */
@@ -1945,14 +1961,14 @@
 	  if (flags & FLAGS_WIDECHAR)
 	    {
 	      parameters[i].data.wstring = (argarray == NULL)
-		? va_arg(*arglist, trio_wchar_t *)
+		? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_wchar_t *)
 		: (trio_wchar_t *)(argarray[num]);
 	    }
 	  else
 #endif
 	    {
 	      parameters[i].data.string = (argarray == NULL)
-		? va_arg(*arglist, char *)
+		? va_arg(TRIO_VA_LIST_DEREF(arglist), char *)
 		: (char *)(argarray[num]);
 	    }
 	  break;
@@ -1964,7 +1980,7 @@
 	case FORMAT_COUNT:
 	case FORMAT_UNKNOWN:
 	  parameters[i].data.pointer = (argarray == NULL)
-	    ? va_arg(*arglist, trio_pointer_t )
+	    ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
 	    : argarray[num];
 	  break;
 
@@ -1974,7 +1990,7 @@
 	    {
               if (argarray == NULL)
                 parameters[i].data.pointer =
-                  (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
+                  (trio_pointer_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t);
               else
                 {
                   if (parameters[i].type == FORMAT_CHAR)
@@ -2032,36 +2048,36 @@
 #if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
 	      if (parameters[i].flags & FLAGS_SIZE_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, size_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), size_t)
 		  : (trio_uintmax_t)(*((size_t *)argarray[num]));
 	      else
 #endif
 #if defined(QUALIFIER_PTRDIFF_T)
 	      if (parameters[i].flags & FLAGS_PTRDIFF_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), ptrdiff_t)
 		  : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
 	      else
 #endif
 #if defined(QUALIFIER_INTMAX_T)
 	      if (parameters[i].flags & FLAGS_INTMAX_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_intmax_t)
 		  : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
 	      else
 #endif
 	      if (parameters[i].flags & FLAGS_QUAD)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_ulonglong_t)
 		  : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
 	      else if (parameters[i].flags & FLAGS_LONG)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, long)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), long)
 		  : (trio_uintmax_t)(*((long *)argarray[num]));
 	      else
 		{
 		  if (argarray == NULL)
-		    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
+		    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int);
 		  else
 		    {
 		      if (parameters[i].type == FORMAT_CHAR)
@@ -2082,11 +2098,11 @@
 	   */
 	  if (parameters[i].flags & FLAGS_USER_DEFINED)
 	    parameters[i].data.pointer = (argarray == NULL)
-	      ? va_arg(*arglist, trio_pointer_t )
+	      ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
 	      : argarray[num];
 	  else
 	    parameters[i].data.number.as_unsigned = (argarray == NULL)
-	      ? (trio_uintmax_t)va_arg(*arglist, int)
+	      ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int)
 	      : (trio_uintmax_t)(*((int *)argarray[num]));
 	  break;
 
@@ -2095,17 +2111,17 @@
 	    {
 	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
 		parameters[i].data.longdoublePointer = (argarray == NULL)
-		  ? va_arg(*arglist, trio_long_double_t *)
+		  ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t *)
 		  : (trio_long_double_t *)argarray[num];
 	      else
                 {
 		  if (parameters[i].flags & FLAGS_LONG)
 		    parameters[i].data.doublePointer = (argarray == NULL)
-		      ? va_arg(*arglist, double *)
+		      ? va_arg(TRIO_VA_LIST_DEREF(arglist), double *)
 		      : (double *)argarray[num];
 		  else
 		    parameters[i].data.doublePointer = (argarray == NULL)
-		      ? (double *)va_arg(*arglist, float *)
+		      ? (double *)va_arg(TRIO_VA_LIST_DEREF(arglist), float *)
 		      : (double *)((float *)argarray[num]);
                 }
 	    }
@@ -2113,13 +2129,13 @@
 	    {
 	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
 		parameters[i].data.longdoubleNumber = (argarray == NULL)
-		  ? va_arg(*arglist, trio_long_double_t)
+		  ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t)
 		  : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
 	      else
 		{
 		  if (argarray == NULL)
 		    parameters[i].data.longdoubleNumber =
-		      (trio_long_double_t)va_arg(*arglist, double);
+		      (trio_long_double_t)va_arg(TRIO_VA_LIST_DEREF(arglist), double);
 		  else
 		    {
 		      if (parameters[i].flags & FLAGS_SHORT)
@@ -3384,7 +3400,7 @@
 TRIO_ARGS4((reference, format, arglist, argarray),
 	   trio_reference_t *reference,
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -3412,7 +3428,7 @@
 	   size_t destinationSize,
 	   void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -3638,7 +3654,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3658,7 +3674,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+  return TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3705,7 +3721,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+  status = TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3728,7 +3744,7 @@
   assert(VALID(file));
   assert(VALID(format));
 
-  return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+  return TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3777,7 +3793,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3799,7 +3815,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3843,7 +3859,7 @@
   TRIO_VA_START(args, format);
   data.stream.out = stream;
   data.closure = closure;
-  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3863,7 +3879,7 @@
 
   data.stream.out = stream;
   data.closure = closure;
-  return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+  return TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -3910,7 +3926,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL; /* Terminate with NIL character */
   TRIO_VA_END(args);
   return status;
@@ -3936,7 +3952,7 @@
   assert(VALID(buffer));
   assert(VALID(format));
 
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL;
   return status;
 }
@@ -3995,7 +4011,7 @@
 
   TRIO_VA_START(args, format);
   status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   if (max > 0)
     *buffer = NIL;
   TRIO_VA_END(args);
@@ -4025,7 +4041,7 @@
   assert(VALID(format));
 
   status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   if (max > 0)
     *buffer = NIL;
   return status;
@@ -4086,7 +4102,7 @@
   buffer = &buffer[buf_len];
 
   status = TrioFormat(&buffer, max - 1 - buf_len,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   *buffer = NIL;
   return status;
@@ -4109,7 +4125,7 @@
   buf_len = trio_length(buffer);
   buffer = &buffer[buf_len];
   status = TrioFormat(&buffer, max - 1 - buf_len,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL;
   return status;
 }
@@ -4136,7 +4152,7 @@
     {
       TRIO_VA_START(args, format);
       (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-		       format, &args, NULL);
+		       format, TRIO_VA_LIST_ADDR(args), NULL);
       TRIO_VA_END(args);
 
       trio_string_terminate(info);
@@ -4162,7 +4178,7 @@
   if (info)
     {
       (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-		       format, &args, NULL);
+		       format, TRIO_VA_LIST_ADDR(args), NULL);
       trio_string_terminate(info);
       result = trio_string_extract(info);
       trio_string_destroy(info);
@@ -4194,7 +4210,7 @@
     {
       TRIO_VA_START(args, format);
       status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-			  format, &args, NULL);
+			  format, TRIO_VA_LIST_ADDR(args), NULL);
       TRIO_VA_END(args);
       if (status >= 0)
 	{
@@ -4228,7 +4244,7 @@
   else
     {
       status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-			  format, &args, NULL);
+			  format, TRIO_VA_LIST_ADDR(args), NULL);
       if (status >= 0)
 	{
 	  trio_string_terminate(info);
@@ -4930,7 +4946,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(arglist, format);
-  status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+  status = TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
   TRIO_VA_END(arglist);
   return status;
 }
@@ -4947,7 +4963,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+  return TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
 }
 
 /*************************************************************************
@@ -6374,7 +6390,7 @@
 	   size_t sourceSize,
 	   void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -6418,11 +6434,14 @@
 	   trio_class_t *self,
 	   int *intPointer)
 {
-  FILE *file = (FILE *)self->location;
+  FILE *file;
 
   assert(VALID(self));
+  assert(VALID(self->location));
   assert(VALID(file));
 
+  file = (FILE *)self->location;
+
   self->current = fgetc(file);
   if (self->current == EOF)
     {
@@ -6451,11 +6470,14 @@
 	   trio_class_t *self,
 	   int *intPointer)
 {
-  int fd = *((int *)self->location);
+  int fd;
   int size;
   unsigned char input;
 
   assert(VALID(self));
+  assert(VALID(self->location));
+
+  fd = *((int *)self->location);
 
   size = read(fd, &input, sizeof(char));
   if (size == -1)
@@ -6586,7 +6608,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)stdin, 0,
 		    TrioInStreamFile,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6601,7 +6623,7 @@
 
   return TrioScan((trio_pointer_t)stdin, 0,
 		  TrioInStreamFile,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6636,7 +6658,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)file, 0,
 		    TrioInStreamFile,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6653,7 +6675,7 @@
 
   return TrioScan((trio_pointer_t)file, 0,
 		  TrioInStreamFile,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6689,7 +6711,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)&fd, 0,
 		    TrioInStreamFileDescriptor,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6705,7 +6727,7 @@
 
   return TrioScan((trio_pointer_t)&fd, 0,
 		  TrioInStreamFileDescriptor,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6743,7 +6765,7 @@
   TRIO_VA_START(args, format);
   data.stream.in = stream;
   data.closure = closure;
-  status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+  status = TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6763,7 +6785,7 @@
 
   data.stream.in = stream;
   data.closure = closure;
-  return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+  return TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6803,7 +6825,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)&buffer, 0,
 		    TrioInStreamString,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6820,7 +6842,7 @@
 
   return TrioScan((trio_pointer_t)&buffer, 0,
 		  TrioInStreamString,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
diff --git a/trio.h b/trio.h
index 108a709..99d2127 100644
--- a/trio.h
+++ b/trio.h
@@ -155,45 +155,59 @@
 #ifdef TRIO_REPLACE_STDIO
 /* Replace the <stdio.h> functions */
 #ifndef HAVE_PRINTF
+# undef printf
 # define printf trio_printf
 #endif
 #ifndef HAVE_VPRINTF
+# undef vprintf
 # define vprintf trio_vprintf
 #endif
 #ifndef HAVE_FPRINTF
+# undef fprintf
 # define fprintf trio_fprintf
 #endif
 #ifndef HAVE_VFPRINTF
+# undef vfprintf
 # define vfprintf trio_vfprintf
 #endif
 #ifndef HAVE_SPRINTF
+# undef sprintf
 # define sprintf trio_sprintf
 #endif
 #ifndef HAVE_VSPRINTF
+# undef vsprintf
 # define vsprintf trio_vsprintf
 #endif
 #ifndef HAVE_SNPRINTF
+# undef snprintf
 # define snprintf trio_snprintf
 #endif
 #ifndef HAVE_VSNPRINTF
+# undef vsnprintf
 # define vsnprintf trio_vsnprintf
 #endif
 #ifndef HAVE_SCANF
+# undef scanf
 # define scanf trio_scanf
 #endif
 #ifndef HAVE_VSCANF
+# undef vscanf
 # define vscanf trio_vscanf
 #endif
 #ifndef HAVE_FSCANF
+# undef fscanf
 # define fscanf trio_fscanf
 #endif
 #ifndef HAVE_VFSCANF
+# undef vfscanf
 # define vfscanf trio_vfscanf
 #endif
 #ifndef HAVE_SSCANF
+# undef sscanf
 # define sscanf trio_sscanf
 #endif
 #ifndef HAVE_VSSCANF
+# undef vsscanf
 # define vsscanf trio_vsscanf
 #endif
 /* These aren't stdio functions, but we make them look similar */
diff --git a/triodef.h b/triodef.h
index fa89416..46772ee 100644
--- a/triodef.h
+++ b/triodef.h
@@ -48,6 +48,8 @@
  * based on the DECC compiler later on.
  */
 # define TRIO_PLATFORM_VMS
+#elif defined(__OS400__)
+# define TRIO_PLATFORM_OS400
 #elif defined(unix) || defined(__unix) || defined(__unix__)
 # define TRIO_PLATFORM_UNIX
 #elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
@@ -98,6 +100,10 @@
 #   define TRIO_COMPILER_SUPPORTS_C94
 #  endif
 # endif
+#elif defined(TRIO_COMPILER_XLC) && defined(__EXTENDED__)
+# define TRIO_COMPILER_SUPPORTS_C89
+# define TRIO_COMPILER_SUPPORTS_C90
+# define TRIO_COMPILER_SUPPORTS_C94
 #endif
 
 #if defined(_XOPEN_SOURCE)
diff --git a/triostr.c b/triostr.c
index e507645..123bbeb 100644
--- a/triostr.c
+++ b/triostr.c
@@ -52,7 +52,9 @@
 # define BOOLEAN_T int
 #endif
 
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
+#ifdef __VMS
+# define USE_STRTOD
+#elif defined(TRIO_COMPILER_SUPPORTS_C99)
 # define USE_STRTOD
 # define USE_STRTOF
 #elif defined(TRIO_COMPILER_MSVC)
@@ -78,6 +80,10 @@
 # else
 #  define strcasecmp(x,y) strcmpi(x,y)
 # endif
+#elif defined(TRIO_PLATFORM_OS400)
+# define USE_STRCASECMP
+# define USE_STRNCASECMP
+# include <strings.h>
 #endif
 
 #if !(defined(TRIO_PLATFORM_SUNOS))
diff --git a/uri.c b/uri.c
index 4ab0ce2..d7f32fc 100644
--- a/uri.c
+++ b/uri.c
@@ -314,7 +314,7 @@
  * @uri:  pointer to an URI structure
  * @str:  the string to analyze
  *
- * Parse a port  part and fills in the appropriate fields
+ * Parse a port part and fills in the appropriate fields
  * of the @uri structure
  *
  * port          = *DIGIT
@@ -325,15 +325,16 @@
 xmlParse3986Port(xmlURIPtr uri, const char **str)
 {
     const char *cur = *str;
+    unsigned port = 0; /* unsigned for defined overflow behavior */
 
     if (ISA_DIGIT(cur)) {
-	if (uri != NULL)
-	    uri->port = 0;
 	while (ISA_DIGIT(cur)) {
-	    if (uri != NULL)
-		uri->port = uri->port * 10 + (*cur - '0');
+	    port = port * 10 + (*cur - '0');
+
 	    cur++;
 	}
+	if (uri != NULL)
+	    uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */
 	*str = cur;
 	return(0);
     }
@@ -759,6 +760,8 @@
         cur += 2;
 	ret = xmlParse3986Authority(uri, &cur);
 	if (ret != 0) return(ret);
+	if (uri->server == NULL)
+	    uri->port = -1;
 	ret = xmlParse3986PathAbEmpty(uri, &cur);
 	if (ret != 0) return(ret);
 	*str = cur;
@@ -1106,7 +1109,7 @@
 	    }
 	}
     } else {
-	if (uri->server != NULL) {
+	if ((uri->server != NULL) || (uri->port == -1)) {
 	    if (len + 3 >= max) {
                 temp = xmlSaveUriRealloc(ret, &max);
                 if (temp == NULL) goto mem_error;
@@ -1143,22 +1146,24 @@
 		}
 		ret[len++] = '@';
 	    }
-	    p = uri->server;
-	    while (*p != 0) {
-		if (len >= max) {
-                    temp = xmlSaveUriRealloc(ret, &max);
-                    if (temp == NULL) goto mem_error;
-                    ret = temp;
+	    if (uri->server != NULL) {
+		p = uri->server;
+		while (*p != 0) {
+		    if (len >= max) {
+			temp = xmlSaveUriRealloc(ret, &max);
+			if (temp == NULL) goto mem_error;
+			ret = temp;
+		    }
+		    ret[len++] = *p++;
 		}
-		ret[len++] = *p++;
-	    }
-	    if (uri->port > 0) {
-		if (len + 10 >= max) {
-                    temp = xmlSaveUriRealloc(ret, &max);
-                    if (temp == NULL) goto mem_error;
-                    ret = temp;
+		if (uri->port > 0) {
+		    if (len + 10 >= max) {
+			temp = xmlSaveUriRealloc(ret, &max);
+			if (temp == NULL) goto mem_error;
+			ret = temp;
+		    }
+		    len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
 		}
-		len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
 	    }
 	} else if (uri->authority != NULL) {
 	    if (len + 3 >= max) {
@@ -1194,8 +1199,6 @@
                 if (temp == NULL) goto mem_error;
                 ret = temp;
 	    }
-	    ret[len++] = '/';
-	    ret[len++] = '/';
 	}
 	if (uri->path != NULL) {
 	    p = uri->path;
@@ -1529,11 +1532,10 @@
           break;
         }
         /* Valgrind complained, strcpy(cur, segp + 3); */
-        /* string will overlap, do not use strcpy */
-        tmp = cur;
-        segp += 3;
-        while ((*tmp++ = *segp++) != 0)
-          ;
+	/* string will overlap, do not use strcpy */
+	tmp = cur;
+	segp += 3;
+	while ((*tmp++ = *segp++) != 0);
 
         /* If there are no previous segments, then keep going from here.  */
         segp = cur;
diff --git a/valid.c b/valid.c
index 6e53a76..19f84b8 100644
--- a/valid.c
+++ b/valid.c
@@ -93,7 +93,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
             const char *msg, const char *extra)
 {
@@ -137,7 +137,7 @@
  *
  * Handle a validation error, provide contextual informations
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNode(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
@@ -180,7 +180,7 @@
  *
  * Handle a validation error, provide contextual informations
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
@@ -221,7 +221,7 @@
  *
  * Handle a validation error, provide contextual information
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidWarning(xmlValidCtxtPtr ctxt,
                 xmlNodePtr node, xmlParserErrors error,
                 const char *msg, const xmlChar * str1,
@@ -1798,6 +1798,7 @@
 
     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;
@@ -2531,7 +2532,7 @@
  * DICT_FREE:
  * @str:  a string
  *
- * Free a string if it is not owned by the "dict" dictionnary in the
+ * Free a string if it is not owned by the "dict" dictionary in the
  * current scope
  */
 #define DICT_FREE(str)						\
@@ -2633,10 +2634,9 @@
 	/*
 	 * 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);
@@ -2740,23 +2740,24 @@
 
     if (doc == NULL) return(-1);
     if (attr == NULL) return(-1);
+
     table = (xmlIDTablePtr) doc->ids;
     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);
 }
 
@@ -3059,21 +3060,21 @@
 
     if (doc == NULL) return(-1);
     if (attr == NULL) return(-1);
+
     table = (xmlRefTablePtr) doc->refs;
     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
@@ -5236,7 +5237,7 @@
     xmlElementContentPtr cont;
     const xmlChar *name;
 
-    if ((elemDecl == NULL) || (parent == NULL))
+    if ((elemDecl == NULL) || (parent == NULL) || (ctxt == NULL))
 	return(-1);
     cont = elemDecl->content;
     name = elemDecl->name;
@@ -6948,7 +6949,7 @@
                          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;
 
@@ -6998,6 +6999,9 @@
      * 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;
diff --git a/xinclude.c b/xinclude.c
index ace005b..e3bb43e 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -17,6 +17,7 @@
 #include <libxml/tree.h>
 #include <libxml/parser.h>
 #include <libxml/uri.h>
+#include <libxml/xpath.h>
 #include <libxml/xpointer.h>
 #include <libxml/parserInternals.h>
 #include <libxml/xmlerror.h>
@@ -124,7 +125,7 @@
  *
  * Handle an XInclude error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
                const char *msg, const xmlChar *extra)
 {
@@ -146,7 +147,7 @@
  *
  * Emit an XInclude warning.
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error,
                const char *msg, const xmlChar *extra)
 {
@@ -1207,6 +1208,7 @@
 	    }
 	    break;
 	}
+#ifdef LIBXML_XPTR_ENABLED
 	case XPATH_LOCATIONSET: {
 	    xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
 	    if (set == NULL)
@@ -1226,7 +1228,6 @@
 	    }
 	    break;
 	}
-#ifdef LIBXML_XPTR_ENABLED
 	case XPATH_RANGE:
 	    return(xmlXIncludeCopyRange(ctxt, target, source, obj));
 #endif
@@ -1687,7 +1688,7 @@
     /*
      * Do the xml:base fixup if needed
      */
-    if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/')) &&
+    if ((doc != NULL) && (URL != NULL) &&
         (!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) &&
 	(!(doc->parseFlags & XML_PARSE_NOBASEFIX))) {
 	xmlNodePtr node;
diff --git a/xlink.c b/xlink.c
index 3566e06..c0e4ff3 100644
--- a/xlink.c
+++ b/xlink.c
@@ -150,7 +150,7 @@
     if (type != NULL) {
 	if (xmlStrEqual(type, BAD_CAST "simple")) {
             ret = XLINK_TYPE_SIMPLE;
-	} if (xmlStrEqual(type, BAD_CAST "extended")) {
+	} else if (xmlStrEqual(type, BAD_CAST "extended")) {
 	    role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
 	    if (role != NULL) {
 		xmlNsPtr xlink;
diff --git a/xmlIO.c b/xmlIO.c
index 847cb7e..1a79c09 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -800,6 +800,13 @@
     return 1;
 }
 
+/**
+ * xmlNop:
+ *
+ * No Operation function, does nothing, no input
+ *
+ * Returns zero
+ */
 int
 xmlNop(void) {
     return(0);
@@ -887,7 +894,7 @@
  */
 static void *
 xmlFileOpen_real (const char *filename) {
-    const char *path = NULL;
+    const char *path = filename;
     FILE *fd;
 
     if (filename == NULL)
@@ -917,11 +924,8 @@
 #else
 	path = &filename[5];
 #endif
-    } else
-	path = filename;
+    }
 
-    if (path == NULL)
-	return(NULL);
     if (!xmlCheckFilename(path))
         return(NULL);
 
@@ -1159,7 +1163,12 @@
     gzFile fd;
 
     if (!strcmp(filename, "-")) {
-        fd = gzdopen(dup(0), "rb");
+        int duped_fd = dup(fileno(stdin));
+        fd = gzdopen(duped_fd, "rb");
+        if (fd == Z_NULL && duped_fd >= 0) {
+            close(duped_fd);  /* gzdOpen() does not close on failure */
+        }
+
 	return((void *) fd);
     }
 
@@ -1233,7 +1242,12 @@
 
     snprintf(mode, sizeof(mode), "wb%d", compression);
     if (!strcmp(filename, "-")) {
-        fd = gzdopen(dup(1), mode);
+        int duped_fd = dup(fileno(stdout));
+        fd = gzdopen(duped_fd, "rb");
+        if (fd == Z_NULL && duped_fd >= 0) {
+            close(duped_fd);  /* gzdOpen() does not close on failure */
+        }
+
 	return((void *) fd);
     }
 
@@ -1320,7 +1334,7 @@
 }
 #endif /* HAVE_ZLIB_H */
 
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
 /************************************************************************
  *									*
  *		I/O for compressed file accesses			*
@@ -1355,7 +1369,7 @@
     xzFile fd;
 
     if (!strcmp(filename, "-")) {
-        fd = __libxml2_xzdopen(dup(0), "rb");
+        fd = __libxml2_xzdopen(dup(fileno(stdin)), "rb");
 	return((void *) fd);
     }
 
@@ -1437,7 +1451,7 @@
     if (ret < 0) xmlIOErr(0, "xzclose()");
     return(ret);
 }
-#endif /* HAVE_LZMA_H */
+#endif /* LIBXML_LZMA_ENABLED */
 
 #ifdef LIBXML_HTTP_ENABLED
 /************************************************************************
@@ -1590,7 +1604,7 @@
 	xmlFreeZMemBuff( buff );
 	buff = NULL;
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlCreateZMemBuff:  %s %d\n",
+		    "xmlCreateZMemBuff:  %s %d\n",
 		    "Error initializing compression context.  ZLIB error:",
 		    z_err );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1658,7 +1672,7 @@
     else {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlZMemBuffExtend:  %s %lu bytes.\n",
+		    "xmlZMemBuffExtend:  %s %lu bytes.\n",
 		    "Allocation failure extending output buffer to",
 		    new_size );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1704,7 +1718,7 @@
 	if ( z_err != Z_OK ) {
 	    xmlChar msg[500];
 	    xmlStrPrintf(msg, 500,
-			(const xmlChar *) "xmlZMemBuffAppend:  %s %d %s - %d",
+			"xmlZMemBuffAppend:  %s %d %s - %d",
 			"Compression error while appending",
 			len, "bytes to buffer.  ZLIB error", z_err );
 	    xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1777,7 +1791,7 @@
     else {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		    (const xmlChar *) "xmlZMemBuffGetContent:  %s - %d\n",
+		    "xmlZMemBuffGetContent:  %s - %d\n",
 		    "Error flushing zlib buffers.  Error code", z_err );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
     }
@@ -1982,7 +1996,7 @@
 	if ( len < 0 ) {
 	    xmlChar msg[500];
 	    xmlStrPrintf(msg, 500,
-			(const xmlChar *) "xmlIOHTTPWrite:  %s\n%s '%s'.\n",
+			"xmlIOHTTPWrite:  %s\n%s '%s'.\n",
 			"Error appending to internal buffer.",
 			"Error sending document to URI",
 			ctxt->uri );
@@ -2054,7 +2068,7 @@
     if ( http_content == NULL ) {
 	xmlChar msg[500];
 	xmlStrPrintf(msg, 500,
-		     (const xmlChar *) "xmlIOHTTPCloseWrite:  %s '%s' %s '%s'.\n",
+		     "xmlIOHTTPCloseWrite:  %s '%s' %s '%s'.\n",
 		     "Error retrieving content.\nUnable to",
 		     http_mthd, "data to URI", ctxt->uri );
 	xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -2126,7 +2140,7 @@
 	    else {
                 xmlChar msg[500];
                 xmlStrPrintf(msg, 500,
-    (const xmlChar *) "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
+                      "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n",
 			    http_mthd, content_lgth,
 			    "bytes to URI", ctxt->uri,
 			    "failed.  HTTP return code:", http_rtn );
@@ -2314,10 +2328,10 @@
     xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
 	                      xmlGzfileRead, xmlGzfileClose);
 #endif /* HAVE_ZLIB_H */
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
     xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
 	                      xmlXzfileRead, xmlXzfileClose);
-#endif /* HAVE_ZLIB_H */
+#endif /* LIBXML_LZMA_ENABLED */
 
 #ifdef LIBXML_HTTP_ENABLED
     xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
@@ -2669,6 +2683,12 @@
 #endif
 	}
 #endif
+#ifdef LIBXML_LZMA_ENABLED
+	if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) &&
+		(strcmp(URI, "-") != 0)) {
+            ret->compressed = __libxml2_xzcompressed(context);
+	}
+#endif
     }
     else
       xmlInputCallbackTable[i].closecallback (context);
@@ -3325,6 +3345,17 @@
     if (res < 0) {
 	return(-1);
     }
+
+    /*
+     * try to establish compressed status of input if not done already
+     */
+    if (in->compressed == -1) {
+#ifdef LIBXML_LZMA_ENABLED
+	if (in->readcallback == xmlXzfileRead)
+            in->compressed = __libxml2_xzcompressed(in->context);
+#endif
+    }
+
     len = res;
     if (in->encoder != NULL) {
         unsigned int use;
diff --git a/xmlcatalog.c b/xmlcatalog.c
index 43f455a..006f0cc 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -80,6 +80,7 @@
 
     if (prompt != NULL)
 	fprintf(stdout, "%s", prompt);
+    fflush(stdout);
     if (!fgets(line_read, 500, stdin))
         return(NULL);
     line_read[500] = 0;
@@ -181,12 +182,13 @@
 	/*
 	 * start interpreting the command
 	 */
-        if (!strcmp(command, "exit"))
+	if (!strcmp(command, "exit") ||
+	    !strcmp(command, "quit") ||
+	    !strcmp(command, "bye")) {
+	    free(cmdline);
 	    break;
-        if (!strcmp(command, "quit"))
-	    break;
-        if (!strcmp(command, "bye"))
-	    break;
+	}
+
 	if (!strcmp(command, "public")) {
 	    if (nbargs != 1) {
 		printf("public requires 1 arguments\n");
diff --git a/xmllint.c b/xmllint.c
index 26d8db1..67f7adb 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -449,7 +449,7 @@
  *           message about the timing performed; format is a printf
  *           type argument
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
 endTimer(const char *fmt, ...)
 {
     long msec;
@@ -485,7 +485,7 @@
 {
     begin = clock();
 }
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
 endTimer(const char *fmt, ...)
 {
     long msec;
@@ -514,7 +514,7 @@
      * Do nothing
      */
 }
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
 endTimer(char *format, ...)
 {
     /*
@@ -634,7 +634,7 @@
  * Display and format an error messages, gives file, line, position and
  * extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlHTMLError(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -671,7 +671,7 @@
  * Display and format a warning messages, gives file, line, position and
  * extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlHTMLWarning(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -709,7 +709,7 @@
  * Display and format an validity error messages, gives file,
  * line, position and extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlHTMLValidityError(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -746,7 +746,7 @@
  * Display and format a validity warning messages, gives file, line,
  * position and extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -809,6 +809,7 @@
 
     if (prompt != NULL)
 	fprintf(stdout, "%s", prompt);
+    fflush(stdout);
     if (!fgets(line_read, 500, stdin))
         return(NULL);
     line_read[500] = 0;
@@ -1410,7 +1411,7 @@
  * Display and format a warning messages, gives file, line, position and
  * extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
 {
     va_list args;
@@ -1433,7 +1434,7 @@
  * Display and format a error messages, gives file, line, position and
  * extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
 {
     va_list args;
@@ -1456,7 +1457,7 @@
  * Display and format a fatalError messages, gives file, line, position and
  * extra parameters.
  */
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
 {
     va_list args;
@@ -1837,8 +1838,12 @@
 	if ((fd = open(filename, O_RDONLY)) < 0)
 	    return;
 	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
-	if (base == (void *) MAP_FAILED)
+	if (base == (void *) MAP_FAILED) {
+	    close(fd);
+	    fprintf(stderr, "mmap failure for file %s\n", filename);
+	    progresult = XMLLINT_ERR_RDFILE;
 	    return;
+	}
 
 	reader = xmlReaderForMemory(base, info.st_size, filename,
 	                            NULL, options);
@@ -1997,6 +2002,12 @@
     xmlNsPtr ns;
 
     root = xmlDocGetRootElement(doc);
+    if (root == NULL ) {
+        xmlGenericError(xmlGenericErrorContext,
+                "Document does not have a root element");
+        progresult = XMLLINT_ERR_UNCLASS;
+        return;
+    }
     for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
         namespaces[i++] = ns->href;
         namespaces[i++] = ns->prefix;
@@ -2190,6 +2201,8 @@
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 	f = fopen(filename, "rb");
+#elif defined(__OS400__)
+	f = fopen(filename, "rb");
 #else
 	f = fopen(filename, "r");
 #endif
@@ -2202,6 +2215,7 @@
             if (res > 0) {
                 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
                             chars, res, filename, XML_CHAR_ENCODING_NONE);
+                xmlCtxtUseOptions(ctxt, options);
                 while ((res = fread(chars, 1, pushsize, f)) > 0) {
                     htmlParseChunk(ctxt, chars, res, 0);
                 }
@@ -2223,8 +2237,12 @@
 	if ((fd = open(filename, O_RDONLY)) < 0)
 	    return;
 	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
-	if (base == (void *) MAP_FAILED)
+	if (base == (void *) MAP_FAILED) {
+	    close(fd);
+	    fprintf(stderr, "mmap failure for file %s\n", filename);
+	    progresult = XMLLINT_ERR_RDFILE;
 	    return;
+	}
 
 	doc = htmlReadMemory((char *) base, info.st_size, filename,
 	                     NULL, options);
@@ -2251,6 +2269,8 @@
 	    } else {
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 		f = fopen(filename, "rb");
+#elif defined(__OS400__)
+		f = fopen(filename, "rb");
 #else
 		f = fopen(filename, "r");
 #endif
@@ -2292,6 +2312,8 @@
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
 		f = fopen(filename, "rb");
+#elif defined(__OS400__)
+		f = fopen(filename, "rb");
 #else
 		f = fopen(filename, "r");
 #endif
@@ -2338,8 +2360,12 @@
 	    if ((fd = open(filename, O_RDONLY)) < 0)
 		return;
 	    base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
-	    if (base == (void *) MAP_FAILED)
+	    if (base == (void *) MAP_FAILED) {
+	        close(fd);
+	        fprintf(stderr, "mmap failure for file %s\n", filename);
+		progresult = XMLLINT_ERR_RDFILE;
 	        return;
+	    }
 
 	    if (rectxt == NULL)
 		doc = xmlReadMemory((char *) base, info.st_size,
@@ -2561,7 +2587,7 @@
 		    fprintf(stderr, "Failed to canonicalize\n");
 		    progresult = XMLLINT_ERR_OUT;
 		}
-	    } else if (canonical) {
+	    } else if (canonical_11) {
 	        xmlChar *result = NULL;
 		int size;
 
@@ -2948,6 +2974,7 @@
     if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
     if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
     if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
+    if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
     if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
     if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
     if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
@@ -2990,7 +3017,7 @@
     printf("\t--noenc : ignore any encoding specified inside the document\n");
     printf("\t--noout : don't output the result tree\n");
     printf("\t--path 'paths': provide a set of paths for resources\n");
-    printf("\t--load-trace : print trace of all external entites loaded\n");
+    printf("\t--load-trace : print trace of all external entities loaded\n");
     printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
     printf("\t--nocompact : do not generate compact text nodes\n");
     printf("\t--htmlout : output results as HTML\n");
@@ -3027,7 +3054,7 @@
     printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
     printf("\t--nocdata : replace cdata section with text nodes\n");
 #ifdef LIBXML_OUTPUT_ENABLED
-    printf("\t--format : reformat/reindent the input\n");
+    printf("\t--format : reformat/reindent the output\n");
     printf("\t--encode encoding : output in the given encoding\n");
     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
     printf("\t--pretty STYLE : pretty-print in a particular style\n");
@@ -3087,6 +3114,10 @@
 static void registerNode(xmlNodePtr node)
 {
     node->_private = malloc(sizeof(long));
+    if (node->_private == NULL) {
+        fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
+	exit(XMLLINT_ERR_MEM);
+    }
     *(long*)node->_private = (long) 0x81726354;
     nbregister++;
 }
@@ -3372,11 +3403,13 @@
 	         (!strcmp(argv[i], "--pretty"))) {
 	     i++;
 #ifdef LIBXML_OUTPUT_ENABLED
-	     format = atoi(argv[i]);
-	     if (format == 1) {
-	         noblanks++;
-	         xmlKeepBlanksDefault(0);
-	     }
+       if (argv[i] != NULL) {
+	         format = atoi(argv[i]);
+	         if (format == 1) {
+	             noblanks++;
+	             xmlKeepBlanksDefault(0);
+	         }
+       }
 #endif /* LIBXML_OUTPUT_ENABLED */
 	}
 #ifdef LIBXML_READER_ENABLED
diff --git a/xmlmemory.c b/xmlmemory.c
index 25d9318..f08c8c3 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -109,6 +109,7 @@
 #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
 		      / ALIGN_SIZE ) * ALIGN_SIZE)
 
+#define MAX_SIZE_T ((size_t)-1)
 
 #define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
 #define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
@@ -217,7 +218,7 @@
 
 /**
  * xmlMallocAtomicLoc:
- * @size:  an int specifying the size in byte to allocate.
+ * @size:  an unsigned int specifying the size in byte to allocate.
  * @file:  the file name or NULL
  * @line:  the line number
  *
@@ -240,11 +241,18 @@
 
     TEST_POINT
 
+    if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+	xmlGenericError(xmlGenericErrorContext,
+		"xmlMallocAtomicLoc : Unsigned overflow prevented\n");
+	xmlMemoryDump();
+	return(NULL);
+    }
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
 	xmlGenericError(xmlGenericErrorContext,
-		"xmlMallocLoc : Out of free space\n");
+		"xmlMallocAtomicLoc : Out of free space\n");
 	xmlMemoryDump();
 	return(NULL);
     }
@@ -313,7 +321,7 @@
 void *
 xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
 {
-    MEMHDR *p;
+    MEMHDR *p, *tmp;
     unsigned long number;
 #ifdef DEBUG_MEMORY
     size_t oldsize;
@@ -344,10 +352,12 @@
 #endif
     xmlMutexUnlock(xmlMemMutex);
 
-    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
-    if (!p) {
+    tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
+    if (!tmp) {
+	 free(p);
 	 goto error;
     }
+    p = tmp;
     if (xmlMemTraceBlockAt == ptr) {
 	xmlGenericError(xmlGenericErrorContext,
 			"%p : Realloced(%lu -> %lu) Ok\n",
@@ -512,10 +522,7 @@
 
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
-    if (s != NULL)
-      strcpy(s,str);
-    else
-      goto error;
+    strcpy(s,str);
 
     TEST_POINT
 
@@ -555,7 +562,12 @@
 
 int
 xmlMemUsed(void) {
-     return(debugMemSize);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemSize;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 /**
@@ -568,7 +580,12 @@
 
 int
 xmlMemBlocks(void) {
-     return(debugMemBlocks);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemBlocks;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 #ifdef MEM_LIST
@@ -583,13 +600,15 @@
 static void
 xmlMemContentShow(FILE *fp, MEMHDR *p)
 {
-    int i,j,k,len = p->mh_size;
-    const char *buf = (const char *) HDR_2_CLIENT(p);
+    int i,j,k,len;
+    const char *buf;
 
     if (p == NULL) {
 	fprintf(fp, " NULL");
 	return;
     }
+    len = p->mh_size;
+    buf = (const char *) HDR_2_CLIENT(p);
 
     for (i = 0;i < len;i++) {
         if (buf[i] == 0) break;
diff --git a/xmlmodule.c b/xmlmodule.c
index 7fe5bc2..50ed666 100644
--- a/xmlmodule.c
+++ b/xmlmodule.c
@@ -115,7 +115,7 @@
 {
     int rc = -1;
 
-    if ((NULL == module) || (symbol == NULL)) {
+    if ((NULL == module) || (symbol == NULL) || (name == NULL)) {
         __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
                         XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
                         NULL, NULL, 0, 0, "null parameter\n");
diff --git a/xmlreader.c b/xmlreader.c
index 00083d0..f285790 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -51,9 +51,8 @@
 /*
  * The following VA_COPY was coded following an example in
  * the Samba project.  It may not be sufficient for some
- * esoteric implementations of va_list (i.e. it may need
- * something involving a memcpy) but (hopefully) will be
- * sufficient for libxml2.
+ * esoteric implementations of va_list but (hopefully) will
+ * be sufficient for libxml2.
  */
 #ifndef VA_COPY
   #ifdef HAVE_VA_COPY
@@ -62,7 +61,12 @@
     #ifdef HAVE___VA_COPY
       #define VA_COPY(dest,src) __va_copy(dest, src)
     #else
-      #define VA_COPY(dest,src) (dest) = (src)
+      #ifndef VA_LIST_IS_ARRAY
+        #define VA_COPY(dest,src) (dest) = (src)
+      #else
+        #include <string.h>
+        #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
+      #endif
     #endif
   #endif
 #endif
@@ -138,7 +142,7 @@
     xmlNodePtr			faketext;/* fake xmlNs chld */
     int				preserve;/* preserve the resulting document */
     xmlBufPtr		        buffer; /* used to return const xmlChar * */
-    xmlDictPtr			dict;	/* the context dictionnary */
+    xmlDictPtr			dict;	/* the context dictionary */
 
     /* entity stack when traversing entities content */
     xmlNodePtr         ent;          /* Current Entity Ref Node */
@@ -206,7 +210,7 @@
  * DICT_FREE:
  * @str:  a string
  *
- * Free a string if it is not owned by the "dict" dictionnary in the
+ * Free a string if it is not owned by the "dict" dictionary in the
  * current scope
  */
 #define DICT_FREE(str)						\
@@ -282,7 +286,10 @@
 xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
     xmlDictPtr dict;
 
-    dict = reader->ctxt->dict;
+    if ((reader != NULL) && (reader->ctxt != NULL))
+	dict = reader->ctxt->dict;
+    else
+        dict = NULL;
     if (cur == NULL) return;
 
     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
@@ -319,7 +326,7 @@
 static void
 xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
     xmlAttrPtr next;
-    if (cur == NULL) return;
+
     while (cur != NULL) {
         next = cur->next;
         xmlTextReaderFreeProp(reader, cur);
@@ -340,7 +347,10 @@
     xmlNodePtr next;
     xmlDictPtr dict;
 
-    dict = reader->ctxt->dict;
+    if ((reader != NULL) && (reader->ctxt != NULL))
+	dict = reader->ctxt->dict;
+    else
+        dict = NULL;
     if (cur == NULL) return;
     if (cur->type == XML_NAMESPACE_DECL) {
 	xmlFreeNsList((xmlNsPtr) cur);
@@ -417,7 +427,10 @@
 xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
     xmlDictPtr dict;
 
-    dict = reader->ctxt->dict;
+    if ((reader != NULL) && (reader->ctxt != NULL))
+	dict = reader->ctxt->dict;
+    else
+        dict = NULL;
     if (cur->type == XML_DTD_NODE) {
 	xmlFreeDtd((xmlDtdPtr) cur);
 	return;
@@ -1427,7 +1440,7 @@
 	goto node_found;
     }
 #ifdef LIBXML_REGEXP_ENABLED
-    if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
+    if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node->type == XML_ELEMENT_NODE))
 	xmlTextReaderValidatePop(reader);
 #endif /* LIBXML_REGEXP_ENABLED */
     if ((reader->preserves > 0) &&
@@ -1560,7 +1573,7 @@
         goto get_next_node;
     }
 #ifdef LIBXML_REGEXP_ENABLED
-    if ((reader->validate) && (reader->node != NULL)) {
+    if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node != NULL)) {
 	xmlNodePtr node = reader->node;
 
 	if ((node->type == XML_ELEMENT_NODE) &&
@@ -1790,6 +1803,7 @@
 	if (xmlTextReaderDoExpand(reader) != -1) {
 	    return xmlTextReaderCollectSiblings(node->children);
 	}
+	break;
     case XML_ATTRIBUTE_NODE:
 	TODO
 	break;
@@ -2077,6 +2091,9 @@
 		"xmlNewTextReader : malloc failed\n");
 	return(NULL);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(ret->buffer,
+			      XML_BUFFER_ALLOC_BOUNDED);
     ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (ret->sax == NULL) {
 	xmlBufFree(ret->buffer);
@@ -2141,7 +2158,7 @@
     ret->ctxt->dictNames = 1;
     ret->allocs = XML_TEXTREADER_CTXT;
     /*
-     * use the parser dictionnary to allocate all elements and attributes names
+     * use the parser dictionary to allocate all elements and attributes names
      */
     ret->ctxt->docdict = 1;
     ret->dict = ret->ctxt->dict;
@@ -3602,6 +3619,7 @@
 	    return(((xmlNsPtr) node)->href);
         case XML_ATTRIBUTE_NODE:{
 	    xmlAttrPtr attr = (xmlAttrPtr) node;
+	    const xmlChar *ret;
 
 	    if ((attr->children != NULL) &&
 	        (attr->children->type == XML_TEXT_NODE) &&
@@ -3615,10 +3633,21 @@
                                         "xmlTextReaderSetup : malloc failed\n");
                         return (NULL);
                     }
+		    xmlBufSetAllocationScheme(reader->buffer,
+		                              XML_BUFFER_ALLOC_BOUNDED);
                 } else
                     xmlBufEmpty(reader->buffer);
 	        xmlBufGetNodeContent(reader->buffer, node);
-		return(xmlBufContent(reader->buffer));
+		ret = xmlBufContent(reader->buffer);
+		if (ret == NULL) {
+		    /* error on the buffer best to reallocate */
+		    xmlBufFree(reader->buffer);
+		    reader->buffer = xmlBufCreateSize(100);
+		    xmlBufSetAllocationScheme(reader->buffer,
+		                              XML_BUFFER_ALLOC_BOUNDED);
+		    ret = BAD_CAST "";
+		}
+		return(ret);
 	    }
 	    break;
 	}
@@ -4021,13 +4050,19 @@
 }
 
 #ifdef LIBXML_SCHEMAS_ENABLED
-static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
+static char *xmlTextReaderBuildMessage(const char *msg, va_list ap) LIBXML_ATTR_FORMAT(1,0);
 
 static void XMLCDECL
-xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
+xmlTextReaderValidityError(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 static void XMLCDECL
-xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
+xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+static void XMLCDECL
+xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+static void XMLCDECL
+xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
 
 static void XMLCDECL
 xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
@@ -4821,7 +4856,7 @@
     }
 }
 
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlTextReaderError(void *ctxt, const char *msg, ...)
 {
     va_list ap;
@@ -4834,7 +4869,7 @@
 
 }
 
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
 xmlTextReaderWarning(void *ctxt, const char *msg, ...)
 {
     va_list ap;
@@ -5117,6 +5152,9 @@
                         "xmlTextReaderSetup : malloc failed\n");
         return (-1);
     }
+    /* no operation on a reader should require a huge buffer */
+    xmlBufSetAllocationScheme(reader->buffer,
+			      XML_BUFFER_ALLOC_BOUNDED);
     if (reader->sax == NULL)
 	reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
     if (reader->sax == NULL) {
@@ -5217,7 +5255,7 @@
     reader->ctxt->linenumbers = 1;
     reader->ctxt->dictNames = 1;
     /*
-     * use the parser dictionnary to allocate all elements and attributes names
+     * use the parser dictionary to allocate all elements and attributes names
      */
     reader->ctxt->docdict = 1;
     reader->ctxt->parseMode = XML_PARSE_READER;
diff --git a/xmlregexp.c b/xmlregexp.c
index 1f9911c..ca3b4f4 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1544,6 +1544,7 @@
 xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from,
 	                 xmlRegStatePtr to, xmlRegAtomPtr atom) {
     xmlRegStatePtr end;
+    int nullable = 0;
 
     if (atom == NULL) {
 	ERROR("genrate transition: atom == NULL");
@@ -1730,6 +1731,13 @@
     if (xmlRegAtomPush(ctxt, atom) < 0) {
 	return(-1);
     }
+    if ((atom->quant == XML_REGEXP_QUANT_RANGE) &&
+        (atom->min == 0) && (atom->max > 0)) {
+	nullable = 1;
+	atom->min = 1;
+        if (atom->max == 1)
+	    atom->quant = XML_REGEXP_QUANT_OPT;
+    }
     xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1);
     ctxt->state = end;
     switch (atom->quant) {
@@ -1747,11 +1755,8 @@
 	    xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1);
 	    break;
 	case XML_REGEXP_QUANT_RANGE:
-#if DV_test
-	    if (atom->min == 0) {
+	    if (nullable)
 		xmlFAGenerateEpsilonTransition(ctxt, from, to);
-	    }
-#endif
 	    break;
 	default:
 	    break;
@@ -3162,8 +3167,10 @@
 	    exec->status = -6;
 	    return;
 	}
-	memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
+	if (exec->counts) {
+	    memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
 	       exec->comp->nbCounters * sizeof(int));
+	}
     }
 
 #ifdef DEBUG_REGEXP_EXEC
@@ -4091,7 +4098,7 @@
 	     */
 	    exec->determinist = 0;
 	    xmlFARegExecRollBack(exec);
-	    if (exec->status == 0) {
+	    if ((exec->inputStack != NULL ) && (exec->status == 0)) {
 		value = exec->inputStack[exec->index].value;
 		data = exec->inputStack[exec->index].data;
 #ifdef DEBUG_PUSH
@@ -4306,7 +4313,7 @@
 		    (*nbval)++;
 		}
 	    } else {
-                if ((exec->comp->states[trans->to] != NULL) &&
+                if ((exec->comp != NULL) && (exec->comp->states[trans->to] != NULL) &&
 		    (exec->comp->states[trans->to]->type !=
 		     XML_REGEXP_SINK_STATE)) {
 		    if (atom->neg)
@@ -5050,11 +5057,12 @@
 	ERROR("Expecting the end of a char range");
 	return;
     }
-    NEXTL(len);
+
     /* TODO check that the values are acceptable character ranges for XML */
     if (end < start) {
 	ERROR("End of range is before start of range");
     } else {
+        NEXTL(len);
         xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
 		           XML_REGEXP_CHARVAL, start, end, NULL);
     }
@@ -5707,8 +5715,6 @@
     if (atom == NULL)
         return(NULL);
     atom->data = data;
-    if (atom == NULL)
-	return(NULL);
     atom->valuep = xmlStrdup(token);
 
     if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
@@ -6345,7 +6351,7 @@
 /**
  * xmlExpNewCtxt:
  * @maxNodes:  the maximum number of nodes
- * @dict:  optional dictionnary to use internally
+ * @dict:  optional dictionary to use internally
  *
  * Creates a new context for manipulating expressions
  *
@@ -7204,7 +7210,7 @@
         return(NULL);
     }
     /*
-     * check the string is in the dictionnary, if yes use an interned
+     * check the string is in the dictionary, if yes use an interned
      * copy, otherwise we know it's not an acceptable input
      */
     input = xmlDictExists(ctxt->dict, str, len);
diff --git a/xmlsave.c b/xmlsave.c
index 774404b..4a8e3f3 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -2097,8 +2097,8 @@
             xmlBufAdd(buf, BAD_CAST "&amp;", 5);
             cur++;
             base = cur;
-        } else if ((*cur >= 0x80) && ((doc == NULL) ||
-                                      (doc->encoding == NULL))) {
+        } else if ((*cur >= 0x80) && (cur[1] != 0) &&
+	           ((doc == NULL) || (doc->encoding == NULL))) {
             /*
              * We assume we have UTF-8 content.
              */
@@ -2121,14 +2121,14 @@
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
                 l = 2;
-            } else if (*cur < 0xF0) {
+            } else if ((*cur < 0xF0) && (cur [2] != 0)) {
                 val = (cur[0]) & 0x0F;
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
                 val <<= 6;
                 val |= (cur[2]) & 0x3F;
                 l = 3;
-            } else if (*cur < 0xF8) {
+            } else if ((*cur < 0xF8) && (cur [2] != 0) && (cur[3] != 0)) {
                 val = (cur[0]) & 0x07;
                 val <<= 6;
                 val |= (cur[1]) & 0x3F;
diff --git a/xmlschemas.c b/xmlschemas.c
index 121533f..7afe2eb 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -617,7 +617,7 @@
     xmlAutomataStatePtr end;
     xmlAutomataStatePtr state;
 
-    xmlDictPtr dict;		/* dictionnary for interned string names */
+    xmlDictPtr dict;		/* dictionary for interned string names */
     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
     int options;
     xmlSchemaValidCtxtPtr vctxt;
@@ -1085,7 +1085,7 @@
 static void
 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
-		     const char *message);
+		     const char *message) LIBXML_ATTR_FORMAT(3,0);
 static int
 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 			     xmlSchemaTypePtr type,
@@ -1471,7 +1471,7 @@
  * @retValue: the returned value
  * @ws: the whitespace type of the value
  *
- * Get a the cononical representation of the value.
+ * Get a the canonical representation of the value.
  * The caller has to free the returned retValue.
  *
  * Returns 0 if the value could be built and -1 in case of
@@ -1769,7 +1769,7 @@
     }
     FREE_AND_NULL(str)
 
-    return (*buf);
+    return (xmlEscapeFormatString(buf));
 }
 
 /**
@@ -1889,7 +1889,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
               const char *msg, const xmlChar * str1, const xmlChar * str2)
 {
@@ -1922,7 +1922,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
                xmlNodePtr child, int error,
                const char *msg, const xmlChar * str1, const xmlChar * str2)
@@ -1951,7 +1951,7 @@
  *
  * Handle a parser error
  */
-static void
+static void LIBXML_ATTR_FORMAT(7,0)
 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 		const xmlChar * strData1, const xmlChar * strData2,
 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
@@ -2002,7 +2002,7 @@
                      extra);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 			    const char *msg, const xmlChar *str)
 {
@@ -2013,18 +2013,21 @@
 #define WXS_ERROR_TYPE_ERROR 1
 #define WXS_ERROR_TYPE_WARNING 2
 /**
- * xmlSchemaErr3:
+ * xmlSchemaErr4Line:
  * @ctxt: the validation context
- * @node: the context node
+ * @errorLevel: the error level
  * @error: the error code
+ * @node: the context node
+ * @line: the line number
  * @msg: the error message
  * @str1: extra data
  * @str2: extra data
  * @str3: extra data
+ * @str4: extra data
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(6,0)
 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 		  xmlErrorLevel errorLevel,
 		  int error, xmlNodePtr node, int line, const char *msg,
@@ -2039,6 +2042,7 @@
 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
 	    const char *file = NULL;
+	    int col = 0;
 	    if (errorLevel != XML_ERR_WARNING) {
 		vctxt->nberrors++;
 		vctxt->err = error;
@@ -2067,6 +2071,7 @@
 		    (vctxt->parserCtxt->input != NULL)) {
 		    file = vctxt->parserCtxt->input->filename;
 		    line = vctxt->parserCtxt->input->line;
+		    col = vctxt->parserCtxt->input->col;
 		}
 	    } else {
 		/*
@@ -2101,7 +2106,7 @@
 		node, XML_FROM_SCHEMASV,
 		error, errorLevel, file, line,
 		(const char *) str1, (const char *) str2,
-		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
+		(const char *) str3, 0, col, msg, str1, str2, str3, str4);
 
 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
@@ -2137,7 +2142,7 @@
  *
  * Handle a validation error
  */
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
 	      int error, xmlNodePtr node, const char *msg,
 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
@@ -2146,7 +2151,7 @@
 	msg, str1, str2, str3, NULL);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
 	      int error, xmlNodePtr node, const char *msg,
 	      const xmlChar *str1, const xmlChar *str2,
@@ -2156,7 +2161,7 @@
 	msg, str1, str2, str3, str4);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(4,0)
 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 	     int error, xmlNodePtr node, const char *msg,
 	     const xmlChar *str1, const xmlChar *str2)
@@ -2179,7 +2184,7 @@
 	/*
 	* Don't try to format other nodes than element and
 	* attribute nodes.
-	* Play save and return an empty string.
+	* Play safe and return an empty string.
 	*/
 	*msg = xmlStrdup(BAD_CAST "");
 	return(*msg);
@@ -2244,6 +2249,13 @@
 	TODO
 	return (NULL);
     }
+
+    /*
+     * xmlSchemaFormatItemForReport() also returns an escaped format
+     * string, so do this before calling it below (in the future).
+     */
+    xmlEscapeFormatString(msg);
+
     /*
     * VAL TODO: The output of the given schema component is currently
     * disabled.
@@ -2260,7 +2272,7 @@
     return (*msg);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
 		     const char *message,
@@ -2271,24 +2283,21 @@
 
     if (actxt == NULL)
         return;
-    msg = xmlStrdup(BAD_CAST "Internal error: ");
-    msg = xmlStrcat(msg, BAD_CAST funcName);
-    msg = xmlStrcat(msg, BAD_CAST ", ");
+    msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
     msg = xmlStrcat(msg, BAD_CAST message);
     msg = xmlStrcat(msg, BAD_CAST ".\n");
 
     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
-	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
-	    (const char *) msg, str1, str2);
-
+	xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
+	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
-	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
-	    (const char *) msg, str1, str2);
+	xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
+	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
 
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 		     const char *funcName,
 		     const char *message)
@@ -2297,7 +2306,7 @@
 }
 
 #if 0
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 		     const char *funcName,
 		     const char *message,
@@ -2309,7 +2318,7 @@
 }
 #endif
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2334,7 +2343,7 @@
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2349,7 +2358,7 @@
 
 
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 		   xmlParserErrors error,
 		   xmlNodePtr node,
@@ -2374,7 +2383,7 @@
 
 
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 		   xmlParserErrors error,
 		   xmlSchemaPSVIIDCNodePtr idcNode,
@@ -2474,11 +2483,13 @@
 	msg = xmlStrcat(msg, BAD_CAST " '");
 	if (type->builtInType != 0) {
 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
-	    msg = xmlStrcat(msg, type->name);
-	} else
-	    msg = xmlStrcat(msg,
-		xmlSchemaFormatQName(&str,
-		    type->targetNamespace, type->name));
+	    str = xmlStrdup(type->name);
+	} else {
+	    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
+	    if (!str)
+		str = xmlStrdup(qName);
+	}
+	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 	msg = xmlStrcat(msg, BAD_CAST "'");
 	FREE_AND_NULL(str);
     }
@@ -2523,7 +2534,7 @@
     FREE_AND_NULL(msg)
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 		        xmlParserErrors error,
 		        xmlNodePtr node,
@@ -2615,7 +2626,7 @@
 		str = xmlStrcat(str, BAD_CAST ", ");
 	}
 	str = xmlStrcat(str, BAD_CAST " ).\n");
-	msg = xmlStrcat(msg, BAD_CAST str);
+	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 	FREE_AND_NULL(str)
     } else
       msg = xmlStrcat(msg, BAD_CAST "\n");
@@ -2623,7 +2634,7 @@
     xmlFree(msg);
 }
 
-static void
+static void LIBXML_ATTR_FORMAT(8,0)
 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 		  xmlParserErrors error,
 		  xmlNodePtr node,
@@ -2914,7 +2925,7 @@
  *
  * Reports an error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlSchemaBasicItemPtr item,
@@ -2950,7 +2961,7 @@
  *
  * Reports an error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlSchemaBasicItemPtr item,
@@ -2975,7 +2986,7 @@
  *
  * Reports an attribute use error during parsing.
  */
-static void
+static void LIBXML_ATTR_FORMAT(6,0)
 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 		    xmlParserErrors error,
 		    xmlNodePtr node,
@@ -3097,7 +3108,7 @@
  * Reports a simple type validation error.
  * TODO: Should this report the value of an element as well?
  */
-static void
+static void LIBXML_ATTR_FORMAT(8,0)
 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
 			xmlParserErrors error,
 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
@@ -3139,11 +3150,13 @@
 		msg = xmlStrcat(msg, BAD_CAST " '");
 		if (type->builtInType != 0) {
 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
-		    msg = xmlStrcat(msg, type->name);
-		} else
-		    msg = xmlStrcat(msg,
-			xmlSchemaFormatQName(&str,
-			    type->targetNamespace, type->name));
+		    str = xmlStrdup(type->name);
+		} else {
+		    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
+		    if (!str)
+			str = xmlStrdup(qName);
+		}
+		msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
 		msg = xmlStrcat(msg, BAD_CAST "'.");
 		FREE_AND_NULL(str);
 	    }
@@ -3155,8 +3168,10 @@
 		"valid.");
 	}
 	if (expected) {
+	    xmlChar *expectedEscaped = xmlCharStrdup(expected);
 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
-	    msg = xmlStrcat(msg, BAD_CAST expected);
+	    msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
+	    FREE_AND_NULL(expectedEscaped);
 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 	} else
 	    msg = xmlStrcat(msg, BAD_CAST "\n");
@@ -6139,7 +6154,7 @@
     value = xmlNodeGetContent(node);
     /*
     * 3.2.2.1 Lexical representation
-    * An instance of a datatype that is defined as �boolean�
+    * An instance of a datatype that is defined as `boolean`
     * can have the following legal literals {true, false, 1, 0}.
     */
     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
@@ -6187,7 +6202,7 @@
         return (def);
     /*
     * 3.2.2.1 Lexical representation
-    * An instance of a datatype that is defined as �boolean�
+    * An instance of a datatype that is defined as `boolean`
     * can have the following legal literals {true, false, 1, 0}.
     */
     if (xmlStrEqual(val, BAD_CAST "true"))
@@ -7717,8 +7732,8 @@
 	/*
 	* SPEC src-redefine:
 	* (7.1) "If it has an <attributeGroup> among its contents
-	* the �actual value� of whose ref [attribute] is the same
-	* as the �actual value� of its own name attribute plus
+	* the `actual value` of whose ref [attribute] is the same
+	* as the `actual value` of its own name attribute plus
 	* target namespace, then it must have exactly one such group."
 	*/
 	if (pctxt->redefCounter != 0) {
@@ -8867,7 +8882,7 @@
     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
     /*
     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
-    * then the �simple ur-type definition�."
+    * then the `simple ur-type definition`."
     */
     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
     /*
@@ -9035,7 +9050,7 @@
     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
     /*
     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
-    * then the �simple ur-type definition�."
+    * then the `simple ur-type definition`."
     */
     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
     /*
@@ -9180,9 +9195,9 @@
     }
     /*
     * TargetNamespace:
-    * SPEC "The �actual value� of the targetNamespace [attribute]
+    * SPEC "The `actual value` of the targetNamespace [attribute]
     * of the <schema> ancestor element information item if present,
-    * otherwise �absent�.
+    * otherwise `absent`.
     */
     if (topLevel == 0) {
 #ifdef ENABLE_NAMED_LOCALS
@@ -9317,8 +9332,8 @@
     /*
     * REDEFINE: SPEC src-redefine (5)
     * "Within the [children], each <simpleType> must have a
-    * <restriction> among its [children] ... the �actual value� of whose
-    * base [attribute] must be the same as the �actual value� of its own
+    * <restriction> among its [children] ... the `actual value` of whose
+    * base [attribute] must be the same as the `actual value` of its own
     * name attribute plus target namespace;"
     */
     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
@@ -10402,7 +10417,7 @@
 	/*
 	* Given that the schemaLocation [attribute] is only a hint, it is open
 	* to applications to ignore all but the first <import> for a given
-	* namespace, regardless of the �actual value� of schemaLocation, but
+	* namespace, regardless of the `actual value` of schemaLocation, but
 	* such a strategy risks missing useful information when new
 	* schemaLocations are offered.
 	*
@@ -10755,7 +10770,7 @@
 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 	    NULL, node,
 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
-	    NULL, namespaceName, NULL, NULL, NULL);
+	    NULL, schemaLocation, NULL, NULL, NULL);
 	return (pctxt->err);
     }
     /*
@@ -10786,8 +10801,8 @@
     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
     if (namespaceName != NULL) {
 	/*
-	* 1.1 If the namespace [attribute] is present, then its �actual value�
-	* must not match the �actual value� of the enclosing <schema>'s
+	* 1.1 If the namespace [attribute] is present, then its `actual value`
+	* must not match the `actual value` of the enclosing <schema>'s
 	* targetNamespace [attribute].
 	*/
 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
@@ -10988,7 +11003,7 @@
 	    * for inclusions, since the that was the feedback from the
 	    * schema people. I.e. the following spec piece will *not* be
 	    * satisfied:
-	    * SPEC src-include: "It is not an error for the �actual value� of the
+	    * SPEC src-include: "It is not an error for the `actual value` of the
 	    * schemaLocation [attribute] to fail to resolve it all, in which
 	    * case no corresponding inclusion is performed.
 	    * So do we need a warning report here?"
@@ -11005,7 +11020,7 @@
 	    *
 	    * SPEC src-redefine (1)
 	    * "If there are any element information items among the [children]
-	    * other than <annotation> then the �actual value� of the
+	    * other than <annotation> then the `actual value` of the
 	    * schemaLocation [attribute] must successfully resolve."
 	    * TODO: Ask the WG if a the location has always to resolve
 	    * here as well!
@@ -11025,9 +11040,9 @@
 	if (bucket->origTargetNamespace != NULL) {
 	    /*
 	    * SPEC src-include (2.1)
-	    * "SII has a targetNamespace [attribute], and its �actual
-	    * value� is identical to the �actual value� of the targetNamespace
-	    * [attribute] of SII� (which must have such an [attribute])."
+	    * "SII has a targetNamespace [attribute], and its `actual
+	    * value` is identical to the `actual value` of the targetNamespace
+	    * [attribute] of SII' (which must have such an [attribute])."
 	    */
 	    if (pctxt->targetNamespace == NULL) {
 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
@@ -11375,8 +11390,8 @@
 			/*
 			* SPEC src-redefine:
 			* (6.1) "If it has a <group> among its contents at
-			* some level the �actual value� of whose ref
-			* [attribute] is the same as the �actual value� of
+			* some level the `actual value` of whose ref
+			* [attribute] is the same as the `actual value` of
 			* its own name attribute plus target namespace, then
 			* all of the following must be true:"
 			* (6.1.1) "It must have exactly one such group."
@@ -11401,9 +11416,9 @@
 			    xmlChar *str = NULL;
 			    /*
 			    * SPEC src-redefine:
-			    * (6.1.2) "The �actual value� of both that
+			    * (6.1.2) "The `actual value` of both that
 			    * group's minOccurs and maxOccurs [attribute]
-			    * must be 1 (or �absent�).
+			    * must be 1 (or `absent`).
 			    */
 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
@@ -11517,8 +11532,8 @@
     *
     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
     * among its [children]), the simple type definition which is
-    * the {content type} of the type definition �resolved� to by
-    * the �actual value� of the base [attribute]"
+    * the {content type} of the type definition `resolved` to by
+    * the `actual value` of the base [attribute]"
     */
     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
 	&(type->baseNs), &(type->base)) == 0)
@@ -11541,8 +11556,8 @@
 		/*
 		* REDEFINE: SPEC src-redefine (5)
 		* "Within the [children], each <simpleType> must have a
-		* <restriction> among its [children] ... the �actual value� of
-		* whose base [attribute] must be the same as the �actual value�
+		* <restriction> among its [children] ... the `actual value` of
+		* whose base [attribute] must be the same as the `actual value`
 		* of its own name attribute plus target namespace;"
 		*/
 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
@@ -12303,7 +12318,7 @@
 	* SPEC
 	* "...the third alternative (neither <simpleContent> nor
 	* <complexContent>) is chosen. This case is understood as shorthand
-	* for complex content restricting the �ur-type definition�, and the
+	* for complex content restricting the `ur-type definition`, and the
 	* details of the mappings should be modified as necessary.
 	*/
 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
@@ -13211,8 +13226,8 @@
     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
 	xmlSchemaTypePtr type;
 
-	/* (type definition) ... otherwise the type definition �resolved�
-	* to by the �actual value� of the type [attribute] ...
+	/* (type definition) ... otherwise the type definition `resolved`
+	* to by the `actual value` of the type [attribute] ...
 	*/
 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
 	    elemDecl->namedTypeNs);
@@ -13250,7 +13265,7 @@
 	    /*
 	    * The type definitions is set to:
 	    * SPEC "...the {type definition} of the element
-	    * declaration �resolved� to by the �actual value�
+	    * declaration `resolved` to by the `actual value`
 	    * of the substitutionGroup [attribute], if present"
 	    */
 	    if (elemDecl->subtypes == NULL)
@@ -13288,8 +13303,8 @@
 
     /*
     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
-    * define the explicit members as the type definitions �resolved�
-    * to by the items in the �actual value� of the memberTypes [attribute],
+    * define the explicit members as the type definitions `resolved`
+    * to by the items in the `actual value` of the memberTypes [attribute],
     * if any, followed by the type definitions corresponding to the
     * <simpleType>s among the [children] of <union>, if any."
     */
@@ -13584,7 +13599,7 @@
 	return (0);
     }
     /*
-    * 3 If both O1 and O2 are sets of (namespace names or �absent�),
+    * 3 If both O1 and O2 are sets of (namespace names or `absent`),
     * then the union of those sets must be the value.
     */
     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
@@ -13618,7 +13633,7 @@
     }
     /*
     * 4 If the two are negations of different values (namespace names
-    * or �absent�), then a pair of not and �absent� must be the value.
+    * or `absent`), then a pair of not and `absent` must be the value.
     */
     if ((completeWild->negNsSet != NULL) &&
 	(curWild->negNsSet != NULL) &&
@@ -13660,7 +13675,7 @@
 	if (nsFound && absentFound) {
 	    /*
 	    * 5.1 If the set S includes both the negated namespace
-	    * name and �absent�, then any must be the value.
+	    * name and `absent`, then any must be the value.
 	    */
 	    completeWild->any = 1;
 	    if (completeWild->nsSet != NULL) {
@@ -13674,7 +13689,7 @@
 	} else if (nsFound && (!absentFound)) {
 	    /*
 	    * 5.2 If the set S includes the negated namespace name
-	    * but not �absent�, then a pair of not and �absent� must
+	    * but not `absent`, then a pair of not and `absent` must
 	    * be the value.
 	    */
 	    if (completeWild->nsSet != NULL) {
@@ -13689,7 +13704,7 @@
 	    completeWild->negNsSet->value = NULL;
 	} else if ((!nsFound) && absentFound) {
 	    /*
-	    * 5.3 If the set S includes �absent� but not the negated
+	    * 5.3 If the set S includes `absent` but not the negated
 	    * namespace name, then the union is not expressible.
 	    */
 	    xmlSchemaPErr(ctxt, completeWild->node,
@@ -13700,7 +13715,7 @@
 	} else if ((!nsFound) && (!absentFound)) {
 	    /*
 	    * 5.4 If the set S does not include either the negated namespace
-	    * name or �absent�, then whichever of O1 or O2 is a pair of not
+	    * name or `absent`, then whichever of O1 or O2 is a pair of not
 	    * and a namespace name must be the value.
 	    */
 	    if (completeWild->negNsSet == NULL) {
@@ -13734,7 +13749,7 @@
 	while (cur != NULL) {
 	    if (cur->value == NULL) {
 		/*
-		* 6.1 If the set S includes �absent�, then any must be the
+		* 6.1 If the set S includes `absent`, then any must be the
 		* value.
 		*/
 		completeWild->any = 1;
@@ -13752,8 +13767,8 @@
 	}
 	if (completeWild->negNsSet == NULL) {
 	    /*
-	    * 6.2 If the set S does not include �absent�, then a pair of not
-	    * and �absent� must be the value.
+	    * 6.2 If the set S does not include `absent`, then a pair of not
+	    * and `absent` must be the value.
 	    */
 	    if (completeWild->nsSet != NULL) {
 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
@@ -13836,9 +13851,9 @@
     }
     /*
     * 3 If either O1 or O2 is a pair of not and a value (a namespace
-    * name or �absent�) and the other is a set of (namespace names or
-    * �absent�), then that set, minus the negated value if it was in
-    * the set, minus �absent� if it was in the set, must be the value.
+    * name or `absent`) and the other is a set of (namespace names or
+    * `absent`), then that set, minus the negated value if it was in
+    * the set, minus `absent` if it was in the set, must be the value.
     */
     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
@@ -13887,7 +13902,7 @@
 	return(0);
     }
     /*
-    * 4 If both O1 and O2 are sets of (namespace names or �absent�),
+    * 4 If both O1 and O2 are sets of (namespace names or `absent`),
     * then the intersection of those sets must be the value.
     */
     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
@@ -13937,7 +13952,7 @@
     }
     /*
     * 6 If the one is a negation of a namespace name and the other
-    * is a negation of �absent�, then the one which is the negation
+    * is a negation of `absent`, then the one which is the negation
     * of a namespace name must be the value.
     */
     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
@@ -13969,7 +13984,7 @@
     if (super->any)
 	return (0);
     /*
-    * 2.1 sub must be a pair of not and a namespace name or �absent�.
+    * 2.1 sub must be a pair of not and a namespace name or `absent`.
     * 2.2 super must be a pair of not and the same value.
     */
     if ((sub->negNsSet != NULL) &&
@@ -13977,7 +13992,7 @@
 	(sub->negNsSet->value == super->negNsSet->value))
 	return (0);
     /*
-    * 3.1 sub must be a set whose members are either namespace names or �absent�.
+    * 3.1 sub must be a set whose members are either namespace names or `absent`.
     */
     if (sub->nsSet != NULL) {
 	/*
@@ -14008,7 +14023,7 @@
 	    xmlSchemaWildcardNsPtr cur;
 	    /*
 	    * 3.2.2 super must be a pair of not and a namespace name or
-	    * �absent� and that value must not be in sub's set.
+	    * `absent` and that value must not be in sub's set.
 	    */
 	    cur = sub->nsSet;
 	    while (cur != NULL) {
@@ -14170,7 +14185,7 @@
 			* SPEC (2.1.2) "R's {attribute declaration}'s
 			* {type definition} must be validly derived from
 			* B's {type definition} given the empty set as
-			* defined in Type Derivation OK (Simple) (�3.14.6)."
+			* defined in Type Derivation OK (Simple) ($3.14.6)."
 			*/
 			xmlSchemaPAttrUseErr4(pctxt,
 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
@@ -14202,8 +14217,8 @@
 			/*
 			* 2.1.3 ... one of the following must be true
 			*
-			* 2.1.3.1 B's �effective value constraint� is
-			* �absent� or default.
+			* 2.1.3.1 B's `effective value constraint` is
+			* `absent` or default.
 			*/
 			if ((bEffValue != NULL) &&
 			    (effFixed == 1)) {
@@ -14212,7 +14227,7 @@
 			    xmlSchemaGetEffectiveValueConstraint(bcur,
 				&effFixed, &rEffValue, NULL);
 			    /*
-			    * 2.1.3.2 R's �effective value constraint� is
+			    * 2.1.3.2 R's `effective value constraint` is
 			    * fixed with the same string as B's.
 			    * MAYBE TODO: Compare the computed values.
 			    *       Hmm, it says "same string" so
@@ -14246,9 +14261,9 @@
 		/*
 		* (2.2) "otherwise the {base type definition} must have an
 		* {attribute wildcard} and the {target namespace} of the
-		* R's {attribute declaration} must be �valid� with respect
+		* R's {attribute declaration} must be `valid` with respect
 		* to that wildcard, as defined in Wildcard allows Namespace
-		* Name (�3.10.4)."
+		* Name ($3.10.4)."
 		*/
 		if ((baseWild == NULL) ||
 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
@@ -14346,7 +14361,7 @@
 	    * (4.2) "The complex type definition's {attribute wildcard}'s
 	    * {namespace constraint} must be a subset of the {base type
 	    * definition}'s {attribute wildcard}'s {namespace constraint},
-	    * as defined by Wildcard Subset (�3.10.6)."
+	    * as defined by Wildcard Subset ($3.10.6)."
 	    */
 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
@@ -14360,8 +14375,8 @@
 	    FREE_AND_NULL(str);
 	    return(pctxt->err);
 	}
-	/* 4.3 Unless the {base type definition} is the �ur-type
-	* definition�, the complex type definition's {attribute
+	/* 4.3 Unless the {base type definition} is the `ur-type
+	* definition`, the complex type definition's {attribute
 	* wildcard}'s {process contents} must be identical to or
 	* stronger than the {base type definition}'s {attribute
 	* wildcard}'s {process contents}, where strict is stronger
@@ -14547,7 +14562,7 @@
     if (WXS_IS_EXTENSION(type)) {
 	if (baseType->attributeWildcard != NULL) {
 	    /*
-	    * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
+	    * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
 	    * the appropriate case among the following:"
 	    */
 	    if (type->attributeWildcard != NULL) {
@@ -14555,26 +14570,26 @@
 		* Union the complete wildcard with the base wildcard.
 		* SPEC {attribute wildcard}
 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
-		* and {annotation} are those of the �complete wildcard�,
+		* and {annotation} are those of the `complete wildcard`,
 		* and whose {namespace constraint} is the intensional union
-		* of the {namespace constraint} of the �complete wildcard�
-		* and of the �base wildcard�, as defined in Attribute
-		* Wildcard Union (�3.10.6)."
+		* of the {namespace constraint} of the `complete wildcard`
+		* and of the `base wildcard`, as defined in Attribute
+		* Wildcard Union ($3.10.6)."
 		*/
 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
 		    baseType->attributeWildcard) == -1)
 		    goto exit_failure;
 	    } else {
 		/*
-		* (3.2.2.1.1) "If the �complete wildcard� is �absent�,
-		* then the �base wildcard�."
+		* (3.2.2.1.1) "If the `complete wildcard` is `absent`,
+		* then the `base wildcard`."
 		*/
 		type->attributeWildcard = baseType->attributeWildcard;
 	    }
 	} else {
 	    /*
-	    * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
-	    * �complete wildcard"
+	    * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
+	    * `complete wildcard`"
 	    * NOOP
 	    */
 	}
@@ -14582,7 +14597,7 @@
 	/*
 	* SPEC {attribute wildcard}
 	* (3.1) "If the <restriction> alternative is chosen, then the
-	* �complete wildcard�;"
+	* `complete wildcard`;"
 	* NOOP
 	*/
     }
@@ -14831,12 +14846,12 @@
     /* 2.2 */
     if (type->baseType == baseType) {
 	/*
-	* 2.2.1 D's �base type definition� is B.
+	* 2.2.1 D's `base type definition` is B.
 	*/
 	return (0);
     }
     /*
-    * 2.2.2 D's �base type definition� is not the �ur-type definition�
+    * 2.2.2 D's `base type definition` is not the `ur-type definition`
     * and is validly derived from B given the subset, as defined by this
     * constraint.
     */
@@ -14846,8 +14861,8 @@
 	return (0);
     }
     /*
-    * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
-    * definition�.
+    * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
+    * definition`.
     */
     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
@@ -15159,14 +15174,14 @@
     * NOTE: This is somehow redundant, since we actually built a simple type
     * to have all the needed information; this acts as an self test.
     */
-    /* Base type: If the datatype has been �derived� by �restriction�
-    * then the Simple Type Definition component from which it is �derived�,
-    * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
+    /* Base type: If the datatype has been `derived` by `restriction`
+    * then the Simple Type Definition component from which it is `derived`,
+    * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
     */
     if (baseType == NULL) {
 	/*
 	* TODO: Think about: "modulo the impact of Missing
-	* Sub-components (�5.3)."
+	* Sub-components ($5.3)."
 	*/
 	xmlSchemaPCustomErr(ctxt,
 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
@@ -15226,10 +15241,10 @@
     }
 
     /*
-    * 2 All simple type definitions must be derived ultimately from the �simple
-    * ur-type definition (so� circular definitions are disallowed). That is, it
-    * must be possible to reach a built-in primitive datatype or the �simple
-    * ur-type definition� by repeatedly following the {base type definition}.
+    * 2 All simple type definitions must be derived ultimately from the `simple
+    * ur-type definition` (so circular definitions are disallowed). That is, it
+    * must be possible to reach a built-in primitive datatype or the `simple
+    * ur-type definition` by repeatedly following the {base type definition}.
     *
     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
     */
@@ -15413,10 +15428,10 @@
 	    }
 	    /*
 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
-	    * A �list� datatype can be �derived� from an �atomic� datatype
-	    * whose �lexical space� allows space (such as string or anyURI)or
-	    * a �union� datatype any of whose {member type definitions}'s
-	    * �lexical space� allows space.
+	    * A `list` datatype can be `derived` from an `atomic` datatype
+	    * whose `lexical space` allows space (such as string or anyURI)or
+	    * a `union` datatype any of whose {member type definitions}'s
+	    * `lexical space` allows space.
 	    */
 	} else {
 	    /*
@@ -15453,7 +15468,7 @@
 	    /*
 	    * 2.3.2.3 The {item type definition} must be validly derived
 	    * from the {base type definition}'s {item type definition} given
-	    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
+	    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
 	    */
 	    {
 		xmlSchemaTypePtr baseItemType;
@@ -15500,7 +15515,7 @@
 			case XML_SCHEMA_FACET_WHITESPACE:
 			    /*
 			    * TODO: 2.5.1.2 List datatypes
-			    * The value of �whiteSpace� is fixed to the value collapse.
+			    * The value of `whiteSpace` is fixed to the value collapse.
 			    */
 			case XML_SCHEMA_FACET_PATTERN:
 			case XML_SCHEMA_FACET_ENUMERATION:
@@ -15553,8 +15568,8 @@
 	    member = member->next;
 	}
 	/*
-	* 3.3.1 If the {base type definition} is the �simple ur-type
-	* definition�
+	* 3.3.1 If the {base type definition} is the `simple ur-type
+	* definition`
 	*/
 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
 	    /*
@@ -15616,7 +15631,7 @@
 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
 	    * derived from the corresponding type definitions in the {base
 	    * type definition}'s {member type definitions} given the empty set,
-	    * as defined in Type Derivation OK (Simple) (�3.14.6).
+	    * as defined in Type Derivation OK (Simple) ($3.14.6).
 	    */
 	    {
 		xmlSchemaTypeLinkPtr baseMember;
@@ -15723,7 +15738,7 @@
     /*
     * src-simple-type.1 The corresponding simple type definition, if any,
     * must satisfy the conditions set out in Constraints on Simple Type
-    * Definition Schema Components (�3.14.6).
+    * Definition Schema Components ($3.14.6).
     */
     if (WXS_IS_RESTRICTION(type)) {
 	/*
@@ -15821,8 +15836,8 @@
 	* SPEC (2.1) "its {content type} must be a simple type definition
 	* or mixed."
 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
-	* type}'s particle must be �emptiable� as defined by
-	* Particle Emptiable (�3.9.6)."
+	* type}'s particle must be `emptiable` as defined by
+	* Particle Emptiable ($3.9.6)."
 	*/
 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
@@ -15838,14 +15853,14 @@
     }
     /*
     * 1 If the type definition is a simple type definition, then the string
-    * must be �valid� with respect to that definition as defined by String
-    * Valid (�3.14.4).
+    * must be `valid` with respect to that definition as defined by String
+    * Valid ($3.14.4).
     *
     * AND
     *
     * 2.2.1 If the {content type} is a simple type definition, then the
-    * string must be �valid� with respect to that simple type definition
-    * as defined by String Valid (�3.14.4).
+    * string must be `valid` with respect to that simple type definition
+    * as defined by String Valid ($3.14.4).
     */
     if (WXS_IS_SIMPLE(type))
 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
@@ -15886,8 +15901,8 @@
     *
     * SPEC (1) "The values of the properties of a complex type definition must
     * be as described in the property tableau in The Complex Type Definition
-    * Schema Component (�3.4.1), modulo the impact of Missing
-    * Sub-components (�5.3)."
+    * Schema Component ($3.4.1), modulo the impact of Missing
+    * Sub-components ($5.3)."
     */
     if ((type->baseType != NULL) &&
 	(WXS_IS_SIMPLE(type->baseType)) &&
@@ -15904,9 +15919,9 @@
 	return (XML_SCHEMAP_SRC_CT_1);
     }
     /*
-    * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
-    * definition�. That is, it must be possible to reach the �ur-type
-    * definition by repeatedly following the {base type definition}."
+    * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
+    * definition`. That is, it must be possible to reach the `ur-type
+    * definition` by repeatedly following the {base type definition}."
     *
     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
     */
@@ -16058,8 +16073,8 @@
     if (type->baseType == baseType)
 	return (0);
     /*
-    * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
-    * definition�."
+    * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
+    * definition`."
     */
     if (WXS_IS_ANYTYPE(type->baseType))
 	return (1);
@@ -16076,7 +16091,7 @@
 	/*
 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
 	* must be validly derived from B given the subset as defined in Type
-	* Derivation OK (Simple) (�3.14.6).
+	* Derivation OK (Simple) ($3.14.6).
 	*/
 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
 	    baseType, set));
@@ -16216,7 +16231,7 @@
 	* definition must also have one, and the base type definition's
 	* {attribute  wildcard}'s {namespace constraint} must be a subset
 	* of the complex  type definition's {attribute wildcard}'s {namespace
-	* constraint}, as defined by Wildcard Subset (�3.10.6)."
+	* constraint}, as defined by Wildcard Subset ($3.10.6)."
 	*/
 
 	/*
@@ -16313,9 +16328,9 @@
 		}
 		/*
 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
-		* complex type definition must be a �valid extension�
+		* complex type definition must be a `valid extension`
 		* of the {base type definition}'s particle, as defined
-		* in Particle Valid (Extension) (�3.9.6)."
+		* in Particle Valid (Extension) ($3.9.6)."
 		*
 		* NOTE that we won't check "Particle Valid (Extension)",
 		* since it is ensured by the derivation process in
@@ -16432,7 +16447,7 @@
     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
 	/*
 	* SPEC (5.1) "The {base type definition} must be the
-	* �ur-type definition�."
+	* `ur-type definition`."
 	* PASS
 	*/
     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
@@ -16451,7 +16466,7 @@
 	    * SPEC (5.2.2.1) "The {content type} of the {base type
 	    * definition} must be a simple type definition from which
 	    * the {content type} is validly derived given the empty
-	    * set as defined in Type Derivation OK (Simple) (�3.14.6)."
+	    * set as defined in Type Derivation OK (Simple) ($3.14.6)."
 	    *
 	    * ATTENTION TODO: This seems not needed if the type implicitely
 	    * derived from the base type.
@@ -16482,8 +16497,8 @@
 		(xmlSchemaParticlePtr) base->subtypes))) {
 	    /*
 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
-	    * and have a particle which is �emptiable� as defined in
-	    * Particle Emptiable (�3.9.6)."
+	    * and have a particle which is `emptiable` as defined in
+	    * Particle Emptiable ($3.9.6)."
 	    * PASS
 	    */
 	} else {
@@ -16512,7 +16527,7 @@
 	    /*
 	    * SPEC (5.3.2.2) "The {content type} of the {base type
 	    * definition} must be elementOnly or mixed and have a particle
-	    * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
+	    * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
 	    * PASS
 	    */
 	} else {
@@ -16545,9 +16560,9 @@
 	}
 	/*
 	* SPEC (5.4.2) "The particle of the complex type definition itself
-	* must be a �valid restriction� of the particle of the {content
+	* must be a `valid restriction` of the particle of the {content
 	* type} of the {base type definition} as defined in Particle Valid
-	* (Restriction) (�3.9.6).
+	* (Restriction) ($3.9.6).
 	*
 	* URGENT TODO: (5.4.2)
 	*/
@@ -16616,7 +16631,7 @@
     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
 	/*
 	* 1 If the <complexContent> alternative is chosen, the type definition
-	* �resolved� to by the �actual value� of the base [attribute]
+	* `resolved` to by the `actual value` of the base [attribute]
 	* must be a complex type definition;
 	*/
 	if (! WXS_IS_COMPLEX(base)) {
@@ -16636,7 +16651,7 @@
 	* SPEC
 	* 2 If the <simpleContent> alternative is chosen, all of the
 	* following must be true:
-	* 2.1 The type definition �resolved� to by the �actual value� of the
+	* 2.1 The type definition `resolved` to by the `actual value` of the
 	* base [attribute] must be one of the following:
 	*/
 	if (WXS_IS_SIMPLE(base)) {
@@ -16742,14 +16757,14 @@
     /*
     * SPEC (3) "The corresponding complex type definition component must
     * satisfy the conditions set out in Constraints on Complex Type
-    * Definition Schema Components (�3.4.6);"
+    * Definition Schema Components ($3.4.6);"
     * NOTE (3) will be done in xmlSchemaTypeFixup().
     */
     /*
     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
     * above for {attribute wildcard} is satisfied, the intensional
     * intersection must be expressible, as defined in Attribute Wildcard
-    * Intersection (�3.10.6).
+    * Intersection ($3.10.6).
     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
     */
     return (ret);
@@ -16820,7 +16835,7 @@
 	return (1);
     /*
     * SPEC (2) "R's occurrence range is a valid restriction of B's
-    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
     */
     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 	    b->minOccurs, b->maxOccurs) != 0)
@@ -16912,19 +16927,19 @@
 {
     /* TODO:Error codes (rcase-NSCompat). */
     /*
-    * SPEC "For an element declaration particle to be a �valid restriction�
+    * SPEC "For an element declaration particle to be a `valid restriction`
     * of a wildcard particle all of the following must be true:"
     *
-    * SPEC (1) "The element declaration's {target namespace} is �valid�
+    * SPEC (1) "The element declaration's {target namespace} is `valid`
     * with respect to the wildcard's {namespace constraint} as defined by
-    * Wildcard allows Namespace Name (�3.10.4)."
+    * Wildcard allows Namespace Name ($3.10.4)."
     */
     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
 	return (1);
     /*
     * SPEC (2) "R's occurrence range is a valid restriction of B's
-    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
     */
     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 	    b->minOccurs, b->maxOccurs) != 0)
@@ -16984,21 +16999,21 @@
     /* TODO: Error codes (rcase-NSSubset). */
     /*
     * SPEC (1) "R's occurrence range is a valid restriction of B's
-    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
     */
     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 	    b->minOccurs, b->maxOccurs))
 	return (1);
     /*
     * SPEC (2) "R's {namespace constraint} must be an intensional subset
-    * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
+    * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
     */
     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
 	(xmlSchemaWildcardPtr) b->children))
 	return (1);
     /*
-    * SPEC (3) "Unless B is the content model wildcard of the �ur-type
-    * definition�, R's {process contents} must be identical to or stronger
+    * SPEC (3) "Unless B is the content model wildcard of the `ur-type
+    * definition`, R's {process contents} must be identical to or stronger
     * than B's {process contents}, where strict is stronger than lax is
     * stronger than skip."
     */
@@ -17076,12 +17091,12 @@
     if ((r->children == NULL) || (r->children->children == NULL))
 	return (-1);
     /*
-    * SPEC "For a group particle to be a �valid restriction� of a
+    * SPEC "For a group particle to be a `valid restriction` of a
     * wildcard particle..."
     *
-    * SPEC (1) "Every member of the {particles} of the group is a �valid
-    * restriction� of the wildcard as defined by
-    * Particle Valid (Restriction) (�3.9.6)."
+    * SPEC (1) "Every member of the {particles} of the group is a `valid
+    * restriction` of the wildcard as defined by
+    * Particle Valid (Restriction) ($3.9.6)."
     */
     part = (xmlSchemaParticlePtr) r->children->children;
     do {
@@ -17092,7 +17107,7 @@
     /*
     * SPEC (2) "The effective total range of the group [...] is a
     * valid restriction of B's occurrence range as defined by
-    * Occurrence Range OK (�3.9.6)."
+    * Occurrence Range OK ($3.9.6)."
     */
     if (xmlSchemaCheckParticleRangeOK(
 	    xmlSchemaGetParticleTotalRangeMin(r),
@@ -17132,11 +17147,11 @@
 	(r->children->type != b->children->type))
 	return (-1);
     /*
-    * SPEC "For an all or sequence group particle to be a �valid
-    * restriction� of another group particle with the same {compositor}..."
+    * SPEC "For an all or sequence group particle to be a `valid
+    * restriction` of another group particle with the same {compositor}..."
     *
     * SPEC (1) "R's occurrence range is a valid restriction of B's
-    * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+    * occurrence range as defined by Occurrence Range OK ($3.9.6)."
     */
     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
 	    b->minOccurs, b->maxOccurs))
@@ -17760,7 +17775,7 @@
     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
     /*
     * The actual value is then formed by replacing any union type
-    * definition in the �explicit members� with the members of their
+    * definition in the `explicit members` with the members of their
     * {member type definitions}, in order.
     *
     * TODO: There's a bug entry at
@@ -17894,8 +17909,8 @@
 	}
     }
     /*
-    * For all �atomic� datatypes other than string (and types �derived�
-    * by �restriction� from it) the value of whiteSpace is fixed to
+    * For all `atomic` datatypes other than string (and types `derived`
+    * by `restriction` from it) the value of whiteSpace is fixed to
     * collapse
     */
     {
@@ -18084,7 +18099,7 @@
     * SPEC src-simple-type 1
     * "The corresponding simple type definition, if any, must satisfy
     * the conditions set out in Constraints on Simple Type Definition
-    * Schema Components (�3.14.6)."
+    * Schema Components ($3.14.6)."
     */
     /*
     * Schema Component Constraint: Simple Type Definition Properties Correct
@@ -18344,7 +18359,7 @@
 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
 		/*
-		* SPEC (2.1.4) "If the �effective mixed� is true, then
+		* SPEC (2.1.4) "If the `effective mixed` is true, then
 		* a particle whose properties are as follows:..."
 		*
 		* Empty sequence model group with
@@ -18406,7 +18421,7 @@
 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
 		/*
 		* SPEC (3.2.1)
-		* "If the �effective content� is empty, then the
+		* "If the `effective content` is empty, then the
 		*  {content type} of the [...] base ..."
 		*/
 		type->contentType = baseType->contentType;
@@ -18513,7 +18528,7 @@
 		    particle->children =
 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
 		    /*
-		    * SPEC "followed by the �effective content�."
+		    * SPEC "followed by the `effective content`."
 		    */
 		    particle->next = effectiveContent;
 		    /*
@@ -18657,12 +18672,12 @@
 
 		/* 4.3.5.5 Constraints on enumeration Schema Components
 		* Schema Component Constraint: enumeration valid restriction
-		* It is an �error� if any member of {value} is not in the
-		* �value space� of {base type definition}.
+		* It is an `error` if any member of {value} is not in the
+		* `value space` of {base type definition}.
 		*
 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
-		* The value �must� be in the
-		* �value space� of the �base type�.
+		* The value `must` be in the
+		* `value space` of the `base type`.
 		*/
 		/*
 		* This function is intended to deliver a compiled value
@@ -19097,9 +19112,9 @@
     * 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
+    * (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
+    * it must not be the case that a `QName` is encountered at any depth
     * which resolves to the component corresponding to this <attributeGroup>.
     */
     if (attrGr->attrUses == NULL)
@@ -19356,8 +19371,8 @@
     * SPEC ag-props-correct
     * (1) "The values of the properties of an attribute group definition
     * must be as described in the property tableau in The Attribute
-    * Group Definition Schema Component (�3.6.1), modulo the impact of
-    * Missing Sub-components (�5.3);"
+    * Group Definition Schema Component ($3.6.1), modulo the impact of
+    * Missing Sub-components ($5.3);"
     */
 
     if ((attrGr->attrUses != NULL) &&
@@ -19491,8 +19506,8 @@
     * SPEC a-props-correct (1)
     * "The values of the properties of an attribute declaration must
     * be as described in the property tableau in The Attribute
-    * Declaration Schema Component (�3.2.1), modulo the impact of
-    * Missing Sub-components (�5.3)."
+    * Declaration Schema Component ($3.2.1), modulo the impact of
+    * Missing Sub-components ($5.3)."
     */
 
     if (WXS_ATTR_TYPEDEF(attr) == NULL)
@@ -19520,9 +19535,9 @@
 	/*
 	* SPEC a-props-correct (2)
 	* "if there is a {value constraint}, the canonical lexical
-	* representation of its value must be �valid� with respect
-	* to the {type definition} as defined in String Valid (�3.14.4)."
-	* TODO: Don't care about the *cononical* stuff here, this requirement
+	* representation of its value must be `valid` with respect
+	* to the {type definition} as defined in String Valid ($3.14.4)."
+	* TODO: Don't care about the *canonical* stuff here, this requirement
 	* will be removed in WXS 1.1 anyway.
 	*/
 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
@@ -19589,15 +19604,15 @@
     /*
     * SPEC (1) "The values of the properties of an element declaration
     * must be as described in the property tableau in The Element
-    * Declaration Schema Component (�3.3.1), modulo the impact of Missing
-    * Sub-components (�5.3)."
+    * Declaration Schema Component ($3.3.1), modulo the impact of Missing
+    * Sub-components ($5.3)."
     */
     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
 
 	xmlSchemaCheckElementDeclComponent(head, pctxt);
 	/*
-	* SPEC (3) "If there is a non-�absent� {substitution group
+	* SPEC (3) "If there is a non-`absent` {substitution group
 	* affiliation}, then {scope} must be global."
 	*/
 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
@@ -19641,9 +19656,9 @@
 	* of the element declaration must be validly derived from the {type
 	* definition} of the {substitution group affiliation}, given the value
 	* of the {substitution group exclusions} of the {substitution group
-	* affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
+	* affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
 	* (if the {type definition} is complex) or as defined in
-	* Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
+	* Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
 	* simple)."
 	*
 	* NOTE: {substitution group exclusions} means the values of the
@@ -19707,9 +19722,9 @@
 
 	/*
 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
-	* representation of its value must be �valid� with respect to the
+	* representation of its value must be `valid` with respect to the
 	* {type definition} as defined in Element Default Valid (Immediate)
-	* (�3.3.6)."
+	* ($3.3.6)."
 	*/
 	if (typeDef == NULL) {
 	    xmlSchemaPErr(pctxt, elemDecl->node,
@@ -19777,7 +19792,7 @@
 	/*
 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
 	* {disallowed substitutions} as the blocking constraint, as defined in
-	* Substitution Group OK (Transitive) (�3.3.6)."
+	* Substitution Group OK (Transitive) ($3.3.6)."
 	*/
 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
 	    head = WXS_SUBST_HEAD(head)) {
@@ -19910,7 +19925,7 @@
 		    * SPEC Element Declarations Consistent:
 		    * "If the {particles} contains, either directly,
 		    * indirectly (that is, within the {particles} of a
-		    * contained model group, recursively) or �implicitly�
+		    * contained model group, recursively) or `implicitly`
 		    * two or more element declaration particles with
 		    * the same {name} and {target namespace}, then
 		    * all their type definitions must be the same
@@ -20108,12 +20123,12 @@
 	ptx = xmlSchemaGetPrimitiveType(tx);
 	pty = xmlSchemaGetPrimitiveType(ty);
 	/*
-	* (1) if a datatype T' is �derived� by �restriction� from an
-	* atomic datatype T then the �value space� of T' is a subset of
-	* the �value space� of T. */
+	* (1) if a datatype T' is `derived` by `restriction` from an
+	* atomic datatype T then the `value space` of T' is a subset of
+	* the `value space` of T. */
 	/*
-	* (2) if datatypes T' and T'' are �derived� by �restriction�
-	* from a common atomic ancestor T then the �value space�s of T'
+	* (2) if datatypes T' and T'' are `derived` by `restriction`
+	* from a common atomic ancestor T then the `value space`s of T'
 	* and T'' may overlap.
 	*/
 	if (ptx != pty)
@@ -20214,8 +20229,8 @@
     * SPEC au-props-correct (1)
     * "The values of the properties of an attribute use must be as
     * described in the property tableau in The Attribute Use Schema
-    * Component (�3.5.1), modulo the impact of Missing
-    * Sub-components (�5.3)."
+    * Component ($3.5.1), modulo the impact of Missing
+    * Sub-components ($5.3)."
     */
 
     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
@@ -20316,8 +20331,8 @@
     /*
     * The simple type definition corresponding to the <simpleType> element
     * information item in the [children], if present, otherwise the simple
-    * type definition �resolved� to by the �actual value� of the type
-    * [attribute], if present, otherwise the �simple ur-type definition�.
+    * type definition `resolved` to by the `actual value` of the type
+    * [attribute], if present, otherwise the `simple ur-type definition`.
     */
     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
 	return(0);
@@ -20481,11 +20496,11 @@
 
 	    /*
 	    * SPEC src-redefine:
-	    * (6.2.1) "The �actual value� of its own name attribute plus
-	    * target namespace must successfully �resolve� to a model
+	    * (6.2.1) "The `actual value` of its own name attribute plus
+	    * target namespace must successfully `resolve` to a model
 	    * group definition in I."
-	    * (7.2.1) "The �actual value� of its own name attribute plus
-	    * target namespace must successfully �resolve� to an attribute
+	    * (7.2.1) "The `actual value` of its own name attribute plus
+	    * target namespace must successfully `resolve` to an attribute
 	    * group definition in I."
 
 	    *
@@ -20658,10 +20673,10 @@
 		* SPEC src-redefine:
 		* (6.2.2) "The {model group} of the model group definition
 		* which corresponds to it per XML Representation of Model
-		* Group Definition Schema Components (�3.7.2) must be a
-		* �valid restriction� of the {model group} of that model
+		* Group Definition Schema Components ($3.7.2) must be a
+		* `valid restriction` of the {model group} of that model
 		* group definition in I, as defined in Particle Valid
-		* (Restriction) (�3.9.6)."
+		* (Restriction) ($3.9.6)."
 		*/
 		break;
 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
@@ -20670,11 +20685,11 @@
 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
 		* the attribute group definition which corresponds to it
 		* per XML Representation of Attribute Group Definition Schema
-		* Components (�3.6.2) must be �valid restrictions� of the
+		* Components ($3.6.2) must be `valid restrictions` of the
 		* {attribute uses} and {attribute wildcard} of that attribute
 		* group definition in I, as defined in clause 2, clause 3 and
 		* clause 4 of Derivation Valid (Restriction, Complex)
-		* (�3.4.6) (where references to the base type definition are
+		* ($3.4.6) (where references to the base type definition are
 		* understood as references to the attribute group definition
 		* in I)."
 		*/
@@ -20849,9 +20864,9 @@
 
     * (6.2.2) The {model group} of the model group definition which
     * corresponds to it per XML Representation of Model Group
-    * Definition Schema Components (�3.7.2) must be a �valid
-    * restriction� of the {model group} of that model group definition
-    * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
+    * Definition Schema Components ($3.7.2) must be a `valid
+    * restriction` of the {model group} of that model group definition
+    * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
     */
     xmlSchemaCheckSRCRedefineFirst(pctxt);
 
@@ -21535,8 +21550,8 @@
 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
 	else {
 	    /*
-	    * For all �atomic� datatypes other than string (and types �derived�
-	    * by �restriction� from it) the value of whiteSpace is fixed to
+	    * For all `atomic` datatypes other than string (and types `derived`
+	    * by `restriction` from it) the value of whiteSpace is fixed to
 	    * collapse
 	    * Note that this includes built-in list datatypes.
 	    */
@@ -22841,7 +22856,7 @@
 		    xmlChar *str = NULL;
 		    /*
 		    * cvc-identity-constraint:
-		    * 3 For each node in the �target node set� all
+		    * 3 For each node in the `target node set` all
 		    * of the {fields}, with that node as the context
 		    * node, evaluate to either an empty node-set or
 		    * a node-set with exactly one member, which must
@@ -22971,8 +22986,8 @@
 
 	    /*
 	    * 4.1 If the {identity-constraint category} is unique(/key),
-	    * then no two members of the �qualified node set� have
-	    * �key-sequences� whose members are pairwise equal, as
+	    * then no two members of the `qualified node set` have
+	    * `key-sequences` whose members are pairwise equal, as
 	    * defined by Equal in [XML Schemas: Datatypes].
 	    *
 	    * Get the IDC binding from the matcher and check for
@@ -23100,10 +23115,10 @@
 	    {
 		xmlChar *str = NULL;
 		/*
-		* 4.2.1 (KEY) The �target node set� and the
-		* �qualified node set� are equal, that is, every
-		* member of the �target node set� is also a member
-		* of the �qualified node set� and vice versa.
+		* 4.2.1 (KEY) The `target node set` and the
+		* `qualified node set` are equal, that is, every
+		* member of the `target node set` is also a member
+		* of the `qualified node set` and vice versa.
 		*/
 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
 		    XML_SCHEMAV_CVC_IDC, NULL,
@@ -24184,6 +24199,7 @@
 	else
 	    goto pattern_and_enum;
     }
+
     /*
     * Whitespace handling is only of importance for string-based
     * types.
@@ -24194,14 +24210,13 @@
 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
     } else
 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
     /*
     * If the value was not computed (for string or
     * anySimpleType based types), then use the provided
     * type.
     */
-    if (val == NULL)
-	valType = valType;
-    else
+    if (val != NULL)
 	valType = xmlSchemaGetValType(val);
 
     ret = 0;
@@ -24499,14 +24514,14 @@
     */
     /*
     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
-    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
-    * the string must be a �declared entity name�.
+    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
+    * the string must be a `declared entity name`.
     */
     /*
     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
-    * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
-    * then every whitespace-delimited substring of the string must be a �declared
-    * entity name�.
+    * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
+    * then every whitespace-delimited substring of the string must be a `declared
+    * entity name`.
     */
     /*
     * 2.3 otherwise no further condition applies.
@@ -24518,8 +24533,8 @@
     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
 	xmlSchemaTypePtr biType; /* The built-in type. */
 	/*
-	* SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
-	* a literal in the �lexical space� of {base type definition}"
+	* SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
+	* a literal in the `lexical space` of {base type definition}"
 	*/
 	/*
 	* Whitespace-normalize.
@@ -24630,9 +24645,9 @@
 	xmlChar *tmpValue = NULL;
 	unsigned long len = 0;
 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
-	/* 1.2.2 if {variety} is �list� then the string must be a sequence
-	* of white space separated tokens, each of which �match�es a literal
-	* in the �lexical space� of {item type definition}
+	/* 1.2.2 if {variety} is `list` then the string must be a sequence
+	* of white space separated tokens, each of which `match`es a literal
+	* in the `lexical space` of {item type definition}
 	*/
 	/*
 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
@@ -24713,10 +24728,10 @@
     } else if (WXS_IS_UNION(type)) {
 	xmlSchemaTypeLinkPtr memberLink;
 	/*
-	* TODO: For all datatypes �derived� by �union�  whiteSpace does
-	* not apply directly; however, the normalization behavior of �union�
+	* TODO: For all datatypes `derived` by `union`  whiteSpace does
+	* not apply directly; however, the normalization behavior of `union`
 	* types is controlled by the value of whiteSpace on that one of the
-	* �memberTypes� against which the �union� is successfully validated.
+	* `memberTypes` against which the `union` is successfully validated.
 	*
 	* This means that the value is normalized by the first validating
 	* member type, then the facets of the union type are applied. This
@@ -24724,8 +24739,8 @@
 	*/
 
 	/*
-	* 1.2.3 if {variety} is �union� then the string must �match� a
-	* literal in the �lexical space� of at least one member of
+	* 1.2.3 if {variety} is `union` then the string must `match` a
+	* literal in the `lexical space` of at least one member of
 	* {member type definitions}
 	*/
 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
@@ -24764,9 +24779,9 @@
 	*/
 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
 	    /*
-	    * The normalization behavior of �union� types is controlled by
-	    * the value of whiteSpace on that one of the �memberTypes�
-	    * against which the �union� is successfully validated.
+	    * The normalization behavior of `union` types is controlled by
+	    * the value of whiteSpace on that one of the `memberTypes`
+	    * against which the `union` is successfully validated.
 	    */
 	    NORMALIZE(memberLink->type);
 	    ret = xmlSchemaValidateFacets(actxt, node, type,
@@ -24926,14 +24941,14 @@
 
 	    /*
 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
-	    * "The �local type definition� must be validly
+	    * "The `local type definition` must be validly
 	    * derived from the {type definition} given the union of
 	    * the {disallowed substitutions} and the {type definition}'s
 	    * {prohibited substitutions}, as defined in
-	    * Type Derivation OK (Complex) (�3.4.6)
+	    * Type Derivation OK (Complex) ($3.4.6)
 	    * (if it is a complex type definition),
 	    * or given {disallowed substitutions} as defined in Type
-	    * Derivation OK (Simple) (�3.14.6) (if it is a simple type
+	    * Derivation OK (Simple) ($3.14.6) (if it is a simple type
 	    * definition)."
 	    *
 	    * {disallowed substitutions}: the "block" on the element decl.
@@ -25204,8 +25219,8 @@
 
     /*
     * SPEC (cvc-attribute)
-    * (1) "The declaration must not be �absent� (see Missing
-    * Sub-components (�5.3) for how this can fail to be
+    * (1) "The declaration must not be `absent` (see Missing
+    * Sub-components ($5.3) for how this can fail to be
     * the case)."
     * (2) "Its {type definition} must not be absent."
     *
@@ -25255,15 +25270,15 @@
 	    * use with an {attribute declaration} whose {name} matches
 	    * the attribute information item's [local name] and whose
 	    * {target namespace} is identical to the attribute information
-	    * item's [namespace name] (where an �absent� {target namespace}
+	    * item's [namespace name] (where an `absent` {target namespace}
 	    * is taken to be identical to a [namespace name] with no value),
-	    * then the attribute information must be �valid� with respect
+	    * then the attribute information must be `valid` with respect
 	    * to that attribute use as per Attribute Locally Valid (Use)
-	    * (�3.5.4). In this case the {attribute declaration} of that
-	    * attribute use is the �context-determined declaration� for the
+	    * ($3.5.4). In this case the {attribute declaration} of that
+	    * attribute use is the `context-determined declaration` for the
 	    * attribute information item with respect to Schema-Validity
-	    * Assessment (Attribute) (�3.2.4) and
-	    * Assessment Outcome (Attribute) (�3.2.5).
+	    * Assessment (Attribute) ($3.2.4) and
+	    * Assessment Outcome (Attribute) ($3.2.5).
 	    */
 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
 	    iattr->use = attrUse;
@@ -25340,13 +25355,13 @@
 		continue;
 	    /*
 	    * SPEC (cvc-complex-type)
-	    * (3.2.2) "The attribute information item must be �valid� with
-	    * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
+	    * (3.2.2) "The attribute information item must be `valid` with
+	    * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
 	    *
 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
-	    * "... its [namespace name] must be �valid� with respect to
+	    * "... its [namespace name] must be `valid` with respect to
 	    * the wildcard constraint, as defined in Wildcard allows
-	    * Namespace Name (�3.10.4)."
+	    * Namespace Name ($3.10.4)."
 	    */
 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
 		    iattr->nsName) == 0) {
@@ -25382,11 +25397,11 @@
 		    * SPEC (cvc-complex-type)
 		    * (5) "Let [Definition:]  the wild IDs be the set of
 		    * all attribute information item to which clause 3.2
-		    * applied and whose �validation� resulted in a
-		    * �context-determined declaration� of mustFind or no
-		    * �context-determined declaration� at all, and whose
+		    * applied and whose `validation` resulted in a
+		    * `context-determined declaration` of mustFind or no
+		    * `context-determined declaration` at all, and whose
 		    * [local name] and [namespace name] resolve (as
-		    * defined by QName resolution (Instance) (�3.15.4)) to
+		    * defined by QName resolution (Instance) ($3.15.4)) to
 		    * an attribute declaration whose {type definition} is
 		    * or is derived from ID. Then all of the following
 		    * must be true:"
@@ -25396,7 +25411,7 @@
 			iattr->typeDef, XML_SCHEMAS_ID)) {
 			/*
 			* SPEC (5.1) "There must be no more than one
-			* item in �wild IDs�."
+			* item in `wild IDs`."
 			*/
 			if (wildIDs != 0) {
 			    /* VAL TODO */
@@ -25407,7 +25422,7 @@
 			wildIDs++;
 			/*
 			* SPEC (cvc-complex-type)
-			* (5.2) "If �wild IDs� is non-empty, there must not
+			* (5.2) "If `wild IDs` is non-empty, there must not
 			* be any attribute uses among the {attribute uses}
 			* whose {attribute declaration}'s {type definition}
 			* is or is derived from ID."
@@ -25544,7 +25559,7 @@
 		    if (xmlNewProp(defAttrOwnerElem,
 			iattr->localName, value) == NULL) {
 			VERROR_INT("xmlSchemaVAttributesComplex",
-			    "callling xmlNewProp()");
+			    "calling xmlNewProp()");
 			if (normValue != NULL)
 			    xmlFree(normValue);
 			goto internal_error;
@@ -25617,9 +25632,9 @@
 	    fixed = 0;
 	/*
 	* SPEC (cvc-attribute)
-	* (3) "The item's �normalized value� must be locally �valid�
+	* (3) "The item's `normalized value` must be locally `valid`
 	* with respect to that {type definition} as per
-	* String Valid (�3.14.4)."
+	* String Valid ($3.14.4)."
 	*
 	* VAL TODO: Do we already have the
 	* "normalized attribute value" here?
@@ -25657,9 +25672,9 @@
 	if (fixed) {
 	    /*
 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
-	    * "For an attribute information item to be�valid�
+	    * "For an attribute information item to be `valid`
 	    * with respect to an attribute use its *normalized*
-	    * value� must match the *canonical* lexical
+	    * value must match the *canonical* lexical
 	    * representation of the attribute use's {value
 	    * constraint}value, if it is present and fixed."
 	    *
@@ -25668,7 +25683,7 @@
 	    */
 	    /*
 	    * SPEC Attribute Locally Valid (cvc-attribute)
-	    * (4) "The item's *actual* value� must match the *value* of
+	    * (4) "The item's *actual* value must match the *value* of
 	    * the {value constraint}, if it is present and fixed."
 	    */
 	    if (iattr->val == NULL) {
@@ -25898,8 +25913,8 @@
 	* SPEC (2.1) "its {content type} must be a simple type definition
 	* or mixed."
 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
-	* type}'s particle must be �emptiable� as defined by
-	* Particle Emptiable (�3.9.6)."
+	* type}'s particle must be `emptiable` as defined by
+	* Particle Emptiable ($3.9.6)."
 	*/
 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
@@ -25915,14 +25930,14 @@
     }
     /*
     * 1 If the type definition is a simple type definition, then the string
-    * must be �valid� with respect to that definition as defined by String
-    * Valid (�3.14.4).
+    * must be `valid` with respect to that definition as defined by String
+    * Valid ($3.14.4).
     *
     * AND
     *
     * 2.2.1 If the {content type} is a simple type definition, then the
-    * string must be �valid� with respect to that simple type definition
-    * as defined by String Valid (�3.14.4).
+    * string must be `valid` with respect to that simple type definition
+    * as defined by String Valid ($3.14.4).
     */
     if (WXS_IS_SIMPLE(inode->typeDef)) {
 
@@ -26163,10 +26178,10 @@
 	(! INODE_NILLED(inode))) {
 	/*
 	* cvc-elt (3.3.4) : 5.1.1
-	* If the �actual type definition� is a �local type definition�
+	* If the `actual type definition` is a `local type definition`
 	* then the canonical lexical representation of the {value constraint}
-	* value must be a valid default for the �actual type definition� as
-	* defined in Element Default Valid (Immediate) (�3.3.6).
+	* value must be a valid default for the `actual type definition` as
+	* defined in Element Default Valid (Immediate) ($3.3.6).
 	*/
 	/*
 	* NOTE: 'local' above means types acquired by xsi:type.
@@ -26196,9 +26211,9 @@
 	* cvc-elt (3.3.4) : 5.1.2
 	* The element information item with the canonical lexical
 	* representation of the {value constraint} value used as its
-	* �normalized value� must be �valid� with respect to the
-	* �actual type definition� as defined by Element Locally Valid (Type)
-	* (�3.3.4).
+	* `normalized value` must be `valid` with respect to the
+	* `actual type definition` as defined by Element Locally Valid (Type)
+	* ($3.3.4).
 	*/
 	if (WXS_IS_SIMPLE(inode->typeDef)) {
 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
@@ -26245,18 +26260,18 @@
 
     } else if (! INODE_NILLED(inode)) {
 	/*
-	* 5.2.1 The element information item must be �valid� with respect
-	* to the �actual type definition� as defined by Element Locally
-	* Valid (Type) (�3.3.4).
+	* 5.2.1 The element information item must be `valid` with respect
+	* to the `actual type definition` as defined by Element Locally
+	* Valid (Type) ($3.3.4).
 	*/
 	if (WXS_IS_SIMPLE(inode->typeDef)) {
 	     /*
 	    * SPEC (cvc-type) (3.1)
 	    * "If the type definition is a simple type definition, ..."
 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
-	    * (Element) (�3.3.4) did not apply, then the �normalized value�
-	    * must be �valid� with respect to the type definition as defined
-	    * by String Valid (�3.14.4).
+	    * (Element) ($3.3.4) did not apply, then the `normalized value`
+	    * must be `valid` with respect to the type definition as defined
+	    * by String Valid ($3.14.4).
 	    */
 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
 		    inode, inode->typeDef, inode->value);
@@ -26264,14 +26279,14 @@
 	    /*
 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
 	    * definition, then the element information item must be
-	    * �valid� with respect to the type definition as per
-	    * Element Locally Valid (Complex Type) (�3.4.4);"
+	    * `valid` with respect to the type definition as per
+	    * Element Locally Valid (Complex Type) ($3.4.4);"
 	    *
 	    * SPEC (cvc-complex-type) (2.2)
 	    * "If the {content type} is a simple type definition, ...
-	    * the �normalized value� of the element information item is
-	    * �valid� with respect to that simple type definition as
-	    * defined by String Valid (�3.14.4)."
+	    * the `normalized value` of the element information item is
+	    * `valid` with respect to that simple type definition as
+	    * defined by String Valid ($3.14.4)."
 	    */
 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
 		inode, inode->typeDef->contentTypeDef, inode->value);
@@ -26313,8 +26328,8 @@
 		*/
 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
 		    /*
-		    * 5.2.2.2.1 If the {content type} of the �actual type
-		    * definition� is mixed, then the *initial value* of the
+		    * 5.2.2.2.1 If the {content type} of the `actual type
+		    * definition` is mixed, then the *initial value* of the
 		    * item must match the canonical lexical representation
 		    * of the {value constraint} value.
 		    *
@@ -26338,8 +26353,8 @@
 		    }
 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
 		    /*
-		    * 5.2.2.2.2 If the {content type} of the �actual type
-		    * definition� is a simple type definition, then the
+		    * 5.2.2.2.2 If the {content type} of the `actual type
+		    * definition` is a simple type definition, then the
 		    * *actual value* of the item must match the canonical
 		    * lexical representation of the {value constraint} value.
 		    */
@@ -26380,9 +26395,9 @@
 	goto internal_error;
     /*
     * MAYBE TODO:
-    * SPEC (6) "The element information item must be �valid� with
+    * SPEC (6) "The element information item must be `valid` with
     * respect to each of the {identity-constraint definitions} as per
-    * Identity-constraint Satisfied (�3.11.4)."
+    * Identity-constraint Satisfied ($3.11.4)."
     */
     /*
     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
@@ -26460,8 +26475,8 @@
     vctxt->depth--;
     vctxt->inode = vctxt->elemInfos[vctxt->depth];
     /*
-    * VAL TODO: 7 If the element information item is the �validation root�, it must be
-    * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
+    * VAL TODO: 7 If the element information item is the `validation root`, it must be
+    * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
     */
     return (ret);
 
@@ -26542,11 +26557,11 @@
 		 * Fallback to "anyType".
 		 *
 		 * SPEC (cvc-assess-elt)
-		 * "If the item cannot be �strictly assessed�, [...]
+		 * "If the item cannot be `strictly assessed`, [...]
 		 * an element information item's schema validity may be laxly
-		 * assessed if its �context-determined declaration� is not
-		 * skip by �validating� with respect to the �ur-type
-		 * definition� as per Element Locally Valid (Type) (�3.3.4)."
+		 * assessed if its `context-determined declaration` is not
+		 * skip by `validating` with respect to the `ur-type
+		 * definition` as per Element Locally Valid (Type) ($3.3.4)."
 		*/
 		vctxt->inode->typeDef =
 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
@@ -26618,9 +26633,9 @@
 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
 	    * then the sequence of the element information item's
 	    * element information item [children], if any, taken in
-	    * order, is �valid� with respect to the {content type}'s
+	    * order, is `valid` with respect to the {content type}'s
 	    * particle, as defined in Element Sequence Locally Valid
-	    * (Particle) (�3.9.4)."
+	    * (Particle) ($3.9.4)."
 	    */
 	    ret = xmlRegExecPushString2(regexCtxt,
 		vctxt->inode->localName,
@@ -27380,10 +27395,17 @@
 
         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
 	    /*
-	    * Duplicate the value.
+	    * Duplicate the value, changing any &#38; to a literal ampersand.
+	    *
+	    * libxml2 differs from normal SAX here in that it escapes all ampersands
+	    * as &#38; instead of delivering the raw converted string. Changing the
+	    * behavior at this point would break applications that use this API, so
+	    * we are forced to work around it. There is no danger of accidentally
+	    * decoding some entity other than &#38; in this step because without
+	    * unescaped ampersands there can be no other entities in the string.
 	    */
-	    value = xmlStrndup(attributes[j+3],
-		attributes[j+4] - attributes[j+3]);
+	    value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3],
+		attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0);
 	    /*
 	    * TODO: Set the node line.
 	    */
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index a9edc03..5f38599 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -62,7 +62,7 @@
     long		year;
     unsigned int	mon	:4;	/* 1 <=  mon    <= 12   */
     unsigned int	day	:5;	/* 1 <=  day    <= 31   */
-    unsigned int	hour	:5;	/* 0 <=  hour   <= 23   */
+    unsigned int	hour	:5;	/* 0 <=  hour   <= 24   */
     unsigned int	min	:6;	/* 0 <=  min    <= 59	*/
     double		sec;
     unsigned int	tz_flag	:1;	/* is tzo explicitely set? */
@@ -242,6 +242,10 @@
     }
     ret->type = XML_SCHEMA_FACET_MINLENGTH;
     ret->val = xmlSchemaNewValue(XML_SCHEMAS_NNINTEGER);
+    if (ret->val == NULL) {
+        xmlFree(ret);
+	return(NULL);
+    }
     ret->val->value.decimal.lo = value;
     return (ret);
 }
@@ -1135,9 +1139,13 @@
 #define VALID_DATE(dt)						\
 	(VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt))
 
+#define VALID_END_OF_DAY(dt)					\
+	((dt)->hour == 24 && (dt)->min == 0 && (dt)->sec == 0)
+
 #define VALID_TIME(dt)						\
-	(VALID_HOUR(dt->hour) && VALID_MIN(dt->min) &&		\
-	 VALID_SEC(dt->sec) && VALID_TZO(dt->tzo))
+	(((VALID_HOUR(dt->hour) && VALID_MIN(dt->min) &&	\
+	  VALID_SEC(dt->sec)) || VALID_END_OF_DAY(dt)) &&	\
+	 VALID_TZO(dt->tzo))
 
 #define VALID_DATETIME(dt)					\
 	(VALID_DATE(dt) && VALID_TIME(dt))
@@ -1351,7 +1359,7 @@
 	return ret;
     if (*cur != ':')
 	return 1;
-    if (!VALID_HOUR(value))
+    if (!VALID_HOUR(value) && value != 24 /* Allow end-of-day hour */)
 	return 2;
     cur++;
 
@@ -1373,7 +1381,7 @@
     if (ret != 0)
 	return ret;
 
-    if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo)))
+    if (!VALID_TIME(dt))
 	return 2;
 
     *str = cur;
@@ -3844,13 +3852,14 @@
 	     * Coverity detected an overrun in daysInMonth
 	     * of size 12 at position 12 with index variable "((r)->mon - 1)"
 	     */
-	    if (tmon < 0)
-	        tmon = 0;
+	    if (tmon < 1)
+	        tmon = 1;
 	    if (tmon > 12)
 	        tmon = 12;
             tempdays += MAX_DAYINMONTH(tyr, tmon);
             carry = -1;
-        } else if (tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
+        } else if (VALID_YEAR(r->year) && VALID_MONTH(r->mon) &&
+                   tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
             tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
             carry = 1;
         } else
@@ -4929,7 +4938,7 @@
 
     if (y->type == XML_SCHEMAS_STRING)
 	yws = XML_SCHEMA_WHITESPACE_PRESERVE;
-    else if (x->type == XML_SCHEMAS_NORMSTRING)
+    else if (y->type == XML_SCHEMAS_NORMSTRING)
         yws = XML_SCHEMA_WHITESPACE_REPLACE;
     else
         yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
@@ -5298,6 +5307,7 @@
 			       xmlSchemaWhitespaceValueType ws)
 {
     int ret;
+    int stringType;
 
     if (facet == NULL)
 	return(-1);
@@ -5310,7 +5320,15 @@
 	    */
 	    if (value == NULL)
 		return(-1);
-	    ret = xmlRegexpExec(facet->regexp, value);
+	    /*
+	    * If string-derived type, regexp must be tested on the value space of
+	    * the datatype.
+	    * See https://www.w3.org/TR/xmlschema-2/#rf-pattern
+	    */
+	    stringType = val && ((val->type >= XML_SCHEMAS_STRING && val->type <= XML_SCHEMAS_NORMSTRING)
+			      || (val->type >= XML_SCHEMAS_TOKEN && val->type <= XML_SCHEMAS_NCNAME));
+	    ret = xmlRegexpExec(facet->regexp,
+	                        (stringType && val->value.str) ? val->value.str : value);
 	    if (ret == 1)
 		return(0);
 	    if (ret == 0)
@@ -5644,7 +5662,7 @@
  * @val: the precomputed value
  * @retValue: the returned value
  *
- * Get a the cononical lexical representation of the value.
+ * Get the canonical lexical representation of the value.
  * The caller has to FREE the returned retValue.
  *
  * WARNING: Some value types are not supported yet, resulting
@@ -6066,7 +6084,7 @@
  * @retValue: the returned value
  * @ws: the whitespace type of the value
  *
- * Get a the cononical representation of the value.
+ * Get the canonical representation of the value.
  * The caller has to free the returned @retValue.
  *
  * Returns 0 if the value could be built, 1 if the value type is
diff --git a/xmlstring.c b/xmlstring.c
index a37220d..cc85777 100644
--- a/xmlstring.c
+++ b/xmlstring.c
@@ -457,6 +457,8 @@
         return(xmlStrndup(add, len));
 
     size = xmlStrlen(cur);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -484,14 +486,19 @@
     int size;
     xmlChar *ret;
 
-    if (len < 0)
+    if (len < 0) {
         len = xmlStrlen(str2);
+        if (len < 0)
+            return(NULL);
+    }
     if ((str2 == NULL) || (len == 0))
         return(xmlStrdup(str1));
     if (str1 == NULL)
         return(xmlStrndup(str2, len));
 
     size = xmlStrlen(str1);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -538,7 +545,7 @@
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
 int XMLCDECL
-xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
+xmlStrPrintf(xmlChar *buf, int len, const char *msg, ...) {
     va_list args;
     int ret;
 
@@ -566,7 +573,7 @@
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
 int
-xmlStrVPrintf(xmlChar *buf, int len, const xmlChar *msg, va_list ap) {
+xmlStrVPrintf(xmlChar *buf, int len, const char *msg, va_list ap) {
     int ret;
 
     if((buf == NULL) || (msg == NULL)) {
@@ -837,8 +844,8 @@
             break;
         if ( (ch = *ptr++) & 0x80)
             while ((ch<<=1) & 0x80 ) {
-                ptr++;
 		if (*ptr == 0) break;
+                ptr++;
 	    }
     }
     return (ptr - utf);
@@ -980,5 +987,60 @@
     return(xmlUTF8Strndup(utf, len));
 }
 
+/**
+ * xmlEscapeFormatString:
+ * @msg:  a pointer to the string in which to escape '%' characters.
+ * Must be a heap-allocated buffer created by libxml2 that may be
+ * returned, or that may be freed and replaced.
+ *
+ * Replaces the string pointed to by 'msg' with an escaped string.
+ * Returns the same string with all '%' characters escaped.
+ */
+xmlChar *
+xmlEscapeFormatString(xmlChar **msg)
+{
+    xmlChar *msgPtr = NULL;
+    xmlChar *result = NULL;
+    xmlChar *resultPtr = NULL;
+    size_t count = 0;
+    size_t msgLen = 0;
+    size_t resultLen = 0;
+
+    if (!msg || !*msg)
+        return(NULL);
+
+    for (msgPtr = *msg; *msgPtr != '\0'; ++msgPtr) {
+        ++msgLen;
+        if (*msgPtr == '%')
+            ++count;
+    }
+
+    if (count == 0)
+        return(*msg);
+
+    resultLen = msgLen + count + 1;
+    result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar));
+    if (result == NULL) {
+        /* Clear *msg to prevent format string vulnerabilities in
+           out-of-memory situations. */
+        xmlFree(*msg);
+        *msg = NULL;
+        xmlErrMemory(NULL, NULL);
+        return(NULL);
+    }
+
+    for (msgPtr = *msg, resultPtr = result; *msgPtr != '\0'; ++msgPtr, ++resultPtr) {
+        *resultPtr = *msgPtr;
+        if (*msgPtr == '%')
+            *(++resultPtr) = '%';
+    }
+    result[resultLen - 1] = '\0';
+
+    xmlFree(*msg);
+    *msg = result;
+
+    return *msg;
+}
+
 #define bottom_xmlstring
 #include "elfgcchack.h"
diff --git a/xmlwriter.c b/xmlwriter.c
index d3f29f8..69541b8 100644
--- a/xmlwriter.c
+++ b/xmlwriter.c
@@ -31,9 +31,8 @@
 /*
  * The following VA_COPY was coded following an example in
  * the Samba project.  It may not be sufficient for some
- * esoteric implementations of va_list (i.e. it may need
- * something involving a memcpy) but (hopefully) will be
- * sufficient for libxml2.
+ * esoteric implementations of va_list but (hopefully) will
+ * be sufficient for libxml2.
  */
 #ifndef VA_COPY
   #ifdef HAVE_VA_COPY
@@ -42,7 +41,12 @@
     #ifdef HAVE___VA_COPY
       #define VA_COPY(dest,src) __va_copy(dest, src)
     #else
-      #define VA_COPY(dest,src) (dest) = (src)
+      #ifndef VA_LIST_IS_ARRAY
+        #define VA_COPY(dest,src) (dest) = (src)
+      #else
+        #include <string.h>
+        #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
+      #endif
     #endif
   #endif
 #endif
@@ -109,7 +113,7 @@
                                          const xmlChar * str, int len);
 static int xmlTextWriterCloseDocCallback(void *context);
 
-static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr);
+static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr) LIBXML_ATTR_FORMAT(1,0);
 static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len,
                                       const unsigned char *data);
 static void xmlTextWriterStartDocumentCallback(void *ctx);
@@ -149,7 +153,7 @@
  *
  * Handle a writer error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
                const char *msg, int val)
 {
@@ -2238,10 +2242,12 @@
     if (count == -1)
         return -1;
     sum += count;
-    count = xmlTextWriterWriteString(writer, content);
-    if (count == -1)
-        return -1;
-    sum += count;
+    if (content != NULL) {
+	count = xmlTextWriterWriteString(writer, content);
+	if (count == -1)
+	    return -1;
+	sum += count;
+    }
     count = xmlTextWriterEndElement(writer);
     if (count == -1)
         return -1;
diff --git a/xpath.c b/xpath.c
index 97410e7..06897c7 100644
--- a/xpath.c
+++ b/xpath.c
@@ -135,6 +135,298 @@
  * any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
  */
 
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+/**
+ * xmlXPathCmpNodesExt:
+ * @node1:  the first node
+ * @node2:  the second node
+ *
+ * Compare two nodes w.r.t document order.
+ * This one is optimized for handling of non-element nodes.
+ *
+ * Returns -2 in case of error 1 if first point < second point, 0 if
+ *         it's the same node, -1 otherwise
+ */
+static int
+xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
+    int depth1, depth2;
+    int misc = 0, precedence1 = 0, precedence2 = 0;
+    xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
+    xmlNodePtr cur, root;
+    long l1, l2;
+
+    if ((node1 == NULL) || (node2 == NULL))
+	return(-2);
+
+    if (node1 == node2)
+	return(0);
+
+    /*
+     * a couple of optimizations which will avoid computations in most cases
+     */
+    switch (node1->type) {
+	case XML_ELEMENT_NODE:
+	    if (node2->type == XML_ELEMENT_NODE) {
+		if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
+		    (0 > (long) node2->content) &&
+		    (node1->doc == node2->doc))
+		{
+		    l1 = -((long) node1->content);
+		    l2 = -((long) node2->content);
+		    if (l1 < l2)
+			return(1);
+		    if (l1 > l2)
+			return(-1);
+		} else
+		    goto turtle_comparison;
+	    }
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    precedence1 = 1; /* element is owner */
+	    miscNode1 = node1;
+	    node1 = node1->parent;
+	    misc = 1;
+	    break;
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_COMMENT_NODE:
+	case XML_PI_NODE: {
+	    miscNode1 = node1;
+	    /*
+	    * Find nearest element node.
+	    */
+	    if (node1->prev != NULL) {
+		do {
+		    node1 = node1->prev;
+		    if (node1->type == XML_ELEMENT_NODE) {
+			precedence1 = 3; /* element in prev-sibl axis */
+			break;
+		    }
+		    if (node1->prev == NULL) {
+			precedence1 = 2; /* element is parent */
+			/*
+			* URGENT TODO: Are there any cases, where the
+			* parent of such a node is not an element node?
+			*/
+			node1 = node1->parent;
+			break;
+		    }
+		} while (1);
+	    } else {
+		precedence1 = 2; /* element is parent */
+		node1 = node1->parent;
+	    }
+	    if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
+		(0 <= (long) node1->content)) {
+		/*
+		* Fallback for whatever case.
+		*/
+		node1 = miscNode1;
+		precedence1 = 0;
+	    } else
+		misc = 1;
+	}
+	    break;
+	case XML_NAMESPACE_DECL:
+	    /*
+	    * TODO: why do we return 1 for namespace nodes?
+	    */
+	    return(1);
+	default:
+	    break;
+    }
+    switch (node2->type) {
+	case XML_ELEMENT_NODE:
+	    break;
+	case XML_ATTRIBUTE_NODE:
+	    precedence2 = 1; /* element is owner */
+	    miscNode2 = node2;
+	    node2 = node2->parent;
+	    misc = 1;
+	    break;
+	case XML_TEXT_NODE:
+	case XML_CDATA_SECTION_NODE:
+	case XML_COMMENT_NODE:
+	case XML_PI_NODE: {
+	    miscNode2 = node2;
+	    if (node2->prev != NULL) {
+		do {
+		    node2 = node2->prev;
+		    if (node2->type == XML_ELEMENT_NODE) {
+			precedence2 = 3; /* element in prev-sibl axis */
+			break;
+		    }
+		    if (node2->prev == NULL) {
+			precedence2 = 2; /* element is parent */
+			node2 = node2->parent;
+			break;
+		    }
+		} while (1);
+	    } else {
+		precedence2 = 2; /* element is parent */
+		node2 = node2->parent;
+	    }
+	    if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
+		(0 <= (long) node2->content))
+	    {
+		node2 = miscNode2;
+		precedence2 = 0;
+	    } else
+		misc = 1;
+	}
+	    break;
+	case XML_NAMESPACE_DECL:
+	    return(1);
+	default:
+	    break;
+    }
+    if (misc) {
+	if (node1 == node2) {
+	    if (precedence1 == precedence2) {
+		/*
+		* The ugly case; but normally there aren't many
+		* adjacent non-element nodes around.
+		*/
+		cur = miscNode2->prev;
+		while (cur != NULL) {
+		    if (cur == miscNode1)
+			return(1);
+		    if (cur->type == XML_ELEMENT_NODE)
+			return(-1);
+		    cur = cur->prev;
+		}
+		return (-1);
+	    } else {
+		/*
+		* Evaluate based on higher precedence wrt to the element.
+		* TODO: This assumes attributes are sorted before content.
+		*   Is this 100% correct?
+		*/
+		if (precedence1 < precedence2)
+		    return(1);
+		else
+		    return(-1);
+	    }
+	}
+	/*
+	* Special case: One of the helper-elements is contained by the other.
+	* <foo>
+	*   <node2>
+	*     <node1>Text-1(precedence1 == 2)</node1>
+	*   </node2>
+	*   Text-6(precedence2 == 3)
+	* </foo>
+	*/
+	if ((precedence2 == 3) && (precedence1 > 1)) {
+	    cur = node1->parent;
+	    while (cur) {
+		if (cur == node2)
+		    return(1);
+		cur = cur->parent;
+	    }
+	}
+	if ((precedence1 == 3) && (precedence2 > 1)) {
+	    cur = node2->parent;
+	    while (cur) {
+		if (cur == node1)
+		    return(-1);
+		cur = cur->parent;
+	    }
+	}
+    }
+
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+turtle_comparison:
+
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+    /*
+     * compute depth to root
+     */
+    for (depth2 = 0, cur = node2; cur->parent != NULL; cur = cur->parent) {
+	if (cur->parent == node1)
+	    return(1);
+	depth2++;
+    }
+    root = cur;
+    for (depth1 = 0, cur = node1; cur->parent != NULL; cur = cur->parent) {
+	if (cur->parent == node2)
+	    return(-1);
+	depth1++;
+    }
+    /*
+     * Distinct document (or distinct entities :-( ) case.
+     */
+    if (root != cur) {
+	return(-2);
+    }
+    /*
+     * get the nearest common ancestor.
+     */
+    while (depth1 > depth2) {
+	depth1--;
+	node1 = node1->parent;
+    }
+    while (depth2 > depth1) {
+	depth2--;
+	node2 = node2->parent;
+    }
+    while (node1->parent != node2->parent) {
+	node1 = node1->parent;
+	node2 = node2->parent;
+	/* should not happen but just in case ... */
+	if ((node1 == NULL) || (node2 == NULL))
+	    return(-2);
+    }
+    /*
+     * Find who's first.
+     */
+    if (node1 == node2->prev)
+	return(1);
+    if (node1 == node2->next)
+	return(-1);
+    /*
+     * Speedup using document order if availble.
+     */
+    if ((node1->type == XML_ELEMENT_NODE) &&
+	(node2->type == XML_ELEMENT_NODE) &&
+	(0 > (long) node1->content) &&
+	(0 > (long) node2->content) &&
+	(node1->doc == node2->doc)) {
+
+	l1 = -((long) node1->content);
+	l2 = -((long) node2->content);
+	if (l1 < l2)
+	    return(1);
+	if (l1 > l2)
+	    return(-1);
+    }
+
+    for (cur = node1->next;cur != NULL;cur = cur->next)
+	if (cur == node2)
+	    return(1);
+    return(-1); /* assume there is no sibling list corruption */
+}
+#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
+
 /*
  * Wrapper for the Timsort argorithm from timsort.h
  */
@@ -154,7 +446,6 @@
 static
 int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
 #ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
-    static int xmlXPathCmpNodesExt(xmlNodePtr, xmlNodePtr);
     static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
     {
         int res = xmlXPathCmpNodesExt(x, y);
@@ -327,7 +618,7 @@
     "Encoding error\n",
     "Char out of XML range\n",
     "Invalid or incomplete context\n",
-    "Stack usage errror\n",
+    "Stack usage error\n",
     "Forbidden variable\n",
     "?? Unknown error ??\n"	/* Must be last in the list! */
 };
@@ -348,7 +639,7 @@
             xmlChar buf[200];
 
             xmlStrPrintf(buf, 200,
-                         BAD_CAST "Memory allocation failed : %s\n",
+                         "Memory allocation failed : %s\n",
                          extra);
             ctxt->lastError.message = (char *) xmlStrdup(buf);
         } else {
@@ -654,7 +945,7 @@
     xmlXPathStepOp *steps;	/* ops for computation of this expression */
     int last;			/* index of last step in expression */
     xmlChar *expr;		/* the expression being computed */
-    xmlDictPtr dict;		/* the dictionnary to use if any */
+    xmlDictPtr dict;		/* the dictionary to use if any */
 #ifdef DEBUG_EVAL_COUNTS
     int nb;
     xmlChar *string;
@@ -2885,6 +3176,12 @@
 				fraction_place, number);
 	    }
 
+	    /* Remove leading spaces sometimes inserted by snprintf */
+	    while (work[0] == ' ') {
+	        for (ptr = &work[0];(ptr[0] = ptr[1]);ptr++);
+		size--;
+	    }
+
 	    /* Remove fractional trailing zeroes */
 	    after_fraction = work + size;
 	    ptr = after_fraction;
@@ -2896,7 +3193,7 @@
 
 	    /* Finally copy result back to caller */
 	    size = strlen(work) + 1;
-	    if (size > buffersize) {
+	    if (size > buffersize && buffersize <= (int)sizeof(work)) {
 		work[buffersize - 1] = 0;
 		size = buffersize;
 	    }
@@ -3110,298 +3407,6 @@
     return(-1); /* assume there is no sibling list corruption */
 }
 
-#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
-/**
- * xmlXPathCmpNodesExt:
- * @node1:  the first node
- * @node2:  the second node
- *
- * Compare two nodes w.r.t document order.
- * This one is optimized for handling of non-element nodes.
- *
- * Returns -2 in case of error 1 if first point < second point, 0 if
- *         it's the same node, -1 otherwise
- */
-static int
-xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
-    int depth1, depth2;
-    int misc = 0, precedence1 = 0, precedence2 = 0;
-    xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
-    xmlNodePtr cur, root;
-    long l1, l2;
-
-    if ((node1 == NULL) || (node2 == NULL))
-	return(-2);
-
-    if (node1 == node2)
-	return(0);
-
-    /*
-     * a couple of optimizations which will avoid computations in most cases
-     */
-    switch (node1->type) {
-	case XML_ELEMENT_NODE:
-	    if (node2->type == XML_ELEMENT_NODE) {
-		if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */
-		    (0 > (long) node2->content) &&
-		    (node1->doc == node2->doc))
-		{
-		    l1 = -((long) node1->content);
-		    l2 = -((long) node2->content);
-		    if (l1 < l2)
-			return(1);
-		    if (l1 > l2)
-			return(-1);
-		} else
-		    goto turtle_comparison;
-	    }
-	    break;
-	case XML_ATTRIBUTE_NODE:
-	    precedence1 = 1; /* element is owner */
-	    miscNode1 = node1;
-	    node1 = node1->parent;
-	    misc = 1;
-	    break;
-	case XML_TEXT_NODE:
-	case XML_CDATA_SECTION_NODE:
-	case XML_COMMENT_NODE:
-	case XML_PI_NODE: {
-	    miscNode1 = node1;
-	    /*
-	    * Find nearest element node.
-	    */
-	    if (node1->prev != NULL) {
-		do {
-		    node1 = node1->prev;
-		    if (node1->type == XML_ELEMENT_NODE) {
-			precedence1 = 3; /* element in prev-sibl axis */
-			break;
-		    }
-		    if (node1->prev == NULL) {
-			precedence1 = 2; /* element is parent */
-			/*
-			* URGENT TODO: Are there any cases, where the
-			* parent of such a node is not an element node?
-			*/
-			node1 = node1->parent;
-			break;
-		    }
-		} while (1);
-	    } else {
-		precedence1 = 2; /* element is parent */
-		node1 = node1->parent;
-	    }
-	    if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
-		(0 <= (long) node1->content)) {
-		/*
-		* Fallback for whatever case.
-		*/
-		node1 = miscNode1;
-		precedence1 = 0;
-	    } else
-		misc = 1;
-	}
-	    break;
-	case XML_NAMESPACE_DECL:
-	    /*
-	    * TODO: why do we return 1 for namespace nodes?
-	    */
-	    return(1);
-	default:
-	    break;
-    }
-    switch (node2->type) {
-	case XML_ELEMENT_NODE:
-	    break;
-	case XML_ATTRIBUTE_NODE:
-	    precedence2 = 1; /* element is owner */
-	    miscNode2 = node2;
-	    node2 = node2->parent;
-	    misc = 1;
-	    break;
-	case XML_TEXT_NODE:
-	case XML_CDATA_SECTION_NODE:
-	case XML_COMMENT_NODE:
-	case XML_PI_NODE: {
-	    miscNode2 = node2;
-	    if (node2->prev != NULL) {
-		do {
-		    node2 = node2->prev;
-		    if (node2->type == XML_ELEMENT_NODE) {
-			precedence2 = 3; /* element in prev-sibl axis */
-			break;
-		    }
-		    if (node2->prev == NULL) {
-			precedence2 = 2; /* element is parent */
-			node2 = node2->parent;
-			break;
-		    }
-		} while (1);
-	    } else {
-		precedence2 = 2; /* element is parent */
-		node2 = node2->parent;
-	    }
-	    if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
-		(0 <= (long) node1->content))
-	    {
-		node2 = miscNode2;
-		precedence2 = 0;
-	    } else
-		misc = 1;
-	}
-	    break;
-	case XML_NAMESPACE_DECL:
-	    return(1);
-	default:
-	    break;
-    }
-    if (misc) {
-	if (node1 == node2) {
-	    if (precedence1 == precedence2) {
-		/*
-		* The ugly case; but normally there aren't many
-		* adjacent non-element nodes around.
-		*/
-		cur = miscNode2->prev;
-		while (cur != NULL) {
-		    if (cur == miscNode1)
-			return(1);
-		    if (cur->type == XML_ELEMENT_NODE)
-			return(-1);
-		    cur = cur->prev;
-		}
-		return (-1);
-	    } else {
-		/*
-		* Evaluate based on higher precedence wrt to the element.
-		* TODO: This assumes attributes are sorted before content.
-		*   Is this 100% correct?
-		*/
-		if (precedence1 < precedence2)
-		    return(1);
-		else
-		    return(-1);
-	    }
-	}
-	/*
-	* Special case: One of the helper-elements is contained by the other.
-	* <foo>
-	*   <node2>
-	*     <node1>Text-1(precedence1 == 2)</node1>
-	*   </node2>
-	*   Text-6(precedence2 == 3)
-	* </foo>
-	*/
-	if ((precedence2 == 3) && (precedence1 > 1)) {
-	    cur = node1->parent;
-	    while (cur) {
-		if (cur == node2)
-		    return(1);
-		cur = cur->parent;
-	    }
-	}
-	if ((precedence1 == 3) && (precedence2 > 1)) {
-	    cur = node2->parent;
-	    while (cur) {
-		if (cur == node1)
-		    return(-1);
-		cur = cur->parent;
-	    }
-	}
-    }
-
-    /*
-     * Speedup using document order if availble.
-     */
-    if ((node1->type == XML_ELEMENT_NODE) &&
-	(node2->type == XML_ELEMENT_NODE) &&
-	(0 > (long) node1->content) &&
-	(0 > (long) node2->content) &&
-	(node1->doc == node2->doc)) {
-
-	l1 = -((long) node1->content);
-	l2 = -((long) node2->content);
-	if (l1 < l2)
-	    return(1);
-	if (l1 > l2)
-	    return(-1);
-    }
-
-turtle_comparison:
-
-    if (node1 == node2->prev)
-	return(1);
-    if (node1 == node2->next)
-	return(-1);
-    /*
-     * compute depth to root
-     */
-    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
-	if (cur == node1)
-	    return(1);
-	depth2++;
-    }
-    root = cur;
-    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
-	if (cur == node2)
-	    return(-1);
-	depth1++;
-    }
-    /*
-     * Distinct document (or distinct entities :-( ) case.
-     */
-    if (root != cur) {
-	return(-2);
-    }
-    /*
-     * get the nearest common ancestor.
-     */
-    while (depth1 > depth2) {
-	depth1--;
-	node1 = node1->parent;
-    }
-    while (depth2 > depth1) {
-	depth2--;
-	node2 = node2->parent;
-    }
-    while (node1->parent != node2->parent) {
-	node1 = node1->parent;
-	node2 = node2->parent;
-	/* should not happen but just in case ... */
-	if ((node1 == NULL) || (node2 == NULL))
-	    return(-2);
-    }
-    /*
-     * Find who's first.
-     */
-    if (node1 == node2->prev)
-	return(1);
-    if (node1 == node2->next)
-	return(-1);
-    /*
-     * Speedup using document order if availble.
-     */
-    if ((node1->type == XML_ELEMENT_NODE) &&
-	(node2->type == XML_ELEMENT_NODE) &&
-	(0 > (long) node1->content) &&
-	(0 > (long) node2->content) &&
-	(node1->doc == node2->doc)) {
-
-	l1 = -((long) node1->content);
-	l2 = -((long) node2->content);
-	if (l1 < l2)
-	    return(1);
-	if (l1 > l2)
-	    return(-1);
-    }
-
-    for (cur = node1->next;cur != NULL;cur = cur->next)
-	if (cur == node2)
-	    return(1);
-    return(-1); /* assume there is no sibling list corruption */
-}
-#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
-
 /**
  * xmlXPathNodeSetSort:
  * @set:  the node set
@@ -3701,7 +3706,7 @@
 
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
     /*
-     * prevent duplcates
+     * prevent duplicates
      */
     for (i = 0;i < cur->nodeNr;i++)
         if (cur->nodeTab[i] == val) return(0);
@@ -7928,14 +7933,14 @@
 xmlNodePtr
 xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
     if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
-    if (cur == NULL) {
-	if (ctxt->context->node == NULL)
-	    return(NULL);
-	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
-	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
-	    return(NULL);
+    if (cur == NULL)
         return(ctxt->context->node);
-    }
+
+    if (ctxt->context->node == NULL)
+        return(NULL);
+    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+        (ctxt->context->node->type == XML_NAMESPACE_DECL))
+        return(NULL);
 
     return(xmlXPathNextDescendant(ctxt, cur));
 }
@@ -8385,7 +8390,7 @@
 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
     if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
     if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-    if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
+    if (cur == NULL) {
         if (ctxt->context->tmpNsList != NULL)
 	    xmlFree(ctxt->context->tmpNsList);
 	ctxt->context->tmpNsList =
@@ -9991,7 +9996,7 @@
         (c == '[') || (c == ']') || (c == '@') || /* accelerators */
         (c == '*') || /* accelerators */
 	(!IS_LETTER(c) && (c != '_') &&
-         ((qualified) && (c != ':')))) {
+         ((!qualified) || (c != ':')))) {
 	return(NULL);
     }
 
@@ -12374,11 +12379,6 @@
                     STRANGE
 		    goto error;
                 case NODE_TEST_TYPE:
-		    /*
-		    * TODO: Don't we need to use
-		    *  xmlXPathNodeSetAddNs() for namespace nodes here?
-		    *  Surprisingly, some c14n tests fail, if we do this.
-		    */
 		    if (type == NODE_TYPE_NODE) {
 			switch (cur->type) {
 			    case XML_DOCUMENT_NODE:
@@ -12392,9 +12392,17 @@
 			    case XML_COMMENT_NODE:
 			    case XML_CDATA_SECTION_NODE:
 			    case XML_TEXT_NODE:
-			    case XML_NAMESPACE_DECL:
 				XP_TEST_HIT
 				break;
+			    case XML_NAMESPACE_DECL: {
+				if (axis == AXIS_NAMESPACE) {
+				    XP_TEST_HIT_NS
+				} else {
+	                            hasNsNodes = 1;
+				    XP_TEST_HIT
+				}
+				break;
+                            }
 			    default:
 				break;
 			}
@@ -12420,7 +12428,14 @@
                     if (axis == AXIS_ATTRIBUTE) {
                         if (cur->type == XML_ATTRIBUTE_NODE)
 			{
-			    XP_TEST_HIT
+                            if (prefix == NULL)
+			    {
+				XP_TEST_HIT
+                            } else if ((cur->ns != NULL) &&
+				(xmlStrEqual(URI, cur->ns->href)))
+			    {
+				XP_TEST_HIT
+                            }
                         }
                     } else if (axis == AXIS_NAMESPACE) {
                         if (cur->type == XML_NAMESPACE_DECL)
@@ -12679,6 +12694,14 @@
     * Reset the context node.
     */
     xpctxt->node = oldContextNode;
+    /*
+    * When traversing the namespace axis in "toBool" mode, it's
+    * possible that tmpNsList wasn't freed.
+    */
+    if (xpctxt->tmpNsList != NULL) {
+        xmlFree(xpctxt->tmpNsList);
+        xpctxt->tmpNsList = NULL;
+    }
 
 #ifdef DEBUG_STEP
     xmlGenericError(xmlGenericErrorContext,
@@ -13512,10 +13535,15 @@
                 int frame;
 
                 frame = xmlXPathSetFrame(ctxt);
-                if (op->ch1 != -1)
+                if (op->ch1 != -1) {
                     total +=
                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
-		if (ctxt->valueNr < op->value) {
+                    if (ctxt->error != XPATH_EXPRESSION_OK) {
+                        xmlXPathPopFrame(ctxt, frame);
+                        return (total);
+                    }
+                }
+		if (ctxt->valueNr < ctxt->valueFrame + op->value) {
 		    xmlGenericError(xmlGenericErrorContext,
 			    "xmlXPathCompOpEval: parameter error\n");
 		    ctxt->error = XPATH_INVALID_OPERAND;
@@ -13577,17 +13605,20 @@
 	    bak = ctxt->context->node;
 	    pp = ctxt->context->proximityPosition;
 	    cs = ctxt->context->contextSize;
-            if (op->ch1 != -1)
+            if (op->ch1 != -1) {
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
-	    ctxt->context->contextSize = cs;
-	    ctxt->context->proximityPosition = pp;
-	    ctxt->context->node = bak;
-	    ctxt->context->doc = bakd;
-	    CHECK_ERROR0;
+                ctxt->context->contextSize = cs;
+                ctxt->context->proximityPosition = pp;
+                ctxt->context->node = bak;
+                ctxt->context->doc = bakd;
+	        CHECK_ERROR0;
+            }
             if (op->ch2 != -1) {
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
-	        ctxt->context->doc = bakd;
-	        ctxt->context->node = bak;
+                ctxt->context->contextSize = cs;
+                ctxt->context->proximityPosition = pp;
+                ctxt->context->node = bak;
+                ctxt->context->doc = bakd;
 	        CHECK_ERROR0;
 	    }
             return (total);
@@ -13974,9 +14005,14 @@
                 xmlNodeSetPtr oldset;
                 int i, j;
 
-                if (op->ch1 != -1)
+                if (op->ch1 != -1) {
                     total +=
                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+                    CHECK_ERROR0;
+                }
+                if (ctxt->value == NULL) {
+                    XP_ERROR0(XPATH_INVALID_OPERAND);
+                }
                 if (op->ch2 == -1)
                     return (total);
 
@@ -14719,8 +14755,9 @@
     * internal representation.
     */
 
-    if ((op->ch1 != -1) &&
-        (op->op == XPATH_OP_COLLECT /* 11 */))
+    if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
+        (op->ch1 != -1) &&
+        (op->ch2 == -1 /* no predicate */))
     {
         xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
 
@@ -14763,6 +14800,10 @@
 	}
     }
 
+    /* OP_VALUE has invalid ch1. */
+    if (op->op == XPATH_OP_VALUE)
+        return;
+
     /* Recurse */
     if (op->ch1 != -1)
         xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
diff --git a/xpointer.c b/xpointer.c
index 46f11e8..676c510 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -85,7 +85,7 @@
  *
  * Handle a redefinition of attribute error
  */
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
 xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
            const char * msg, const xmlChar *extra)
 {
@@ -1375,6 +1375,8 @@
 	return(NULL);
 
     ctxt = xmlXPathNewParserContext(str, ctx);
+    if (ctxt == NULL)
+	return(NULL);
     ctxt->xptr = 1;
     xmlXPtrEvalXPointer(ctxt);
 
@@ -1807,6 +1809,8 @@
 	 */
 	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
 	xmlXPathFreeObject(obj);
+	if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
 	obj = tmp;
     }
 
@@ -1901,10 +1905,16 @@
 	 */
 	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
 	xmlXPathFreeObject(obj);
+	if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
 	obj = tmp;
     }
 
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+	xmlXPathFreeObject(obj);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     oldset = (xmlLocationSetPtr) obj->user;
     if (oldset != NULL) {
 	int i;
@@ -2049,6 +2059,8 @@
 	 */
 	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
 	xmlXPathFreeObject(set);
+	if (tmp == NULL)
+            XP_ERROR(XPATH_MEMORY_ERROR)
 	set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;
@@ -2057,6 +2069,10 @@
      * The loop is to compute the covering range for each item and add it
      */
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+	xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     for (i = 0;i < oldset->locNr;i++) {
 	xmlXPtrLocationSetAdd(newset,
 		xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
@@ -2195,6 +2211,8 @@
 	 */
 	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
 	xmlXPathFreeObject(set);
+	if (tmp == NULL)
+	     XP_ERROR(XPATH_MEMORY_ERROR)
 	set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;
@@ -2203,6 +2221,10 @@
      * The loop is to compute the covering range for each item and add it
      */
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+	xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     for (i = 0;i < oldset->locNr;i++) {
 	xmlXPtrLocationSetAdd(newset,
 		xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
@@ -2461,8 +2483,6 @@
         ((*end)->type == XML_NAMESPACE_DECL) || (endindex == NULL))
 	return(-1);
     cur = start;
-    if (cur == NULL)
-	return(-1);
     pos = startindex - 1;
     stringlen = xmlStrlen(string);
 
@@ -2798,6 +2818,10 @@
 
     set = valuePop(ctxt);
     newset = xmlXPtrLocationSetCreate(NULL);
+    if (newset == NULL) {
+	xmlXPathFreeObject(set);
+        XP_ERROR(XPATH_MEMORY_ERROR);
+    }
     if (set->nodesetval == NULL) {
         goto error;
     }
@@ -2809,6 +2833,8 @@
 	 */
 	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
 	xmlXPathFreeObject(set);
+	if (tmp == NULL)
+	     XP_ERROR(XPATH_MEMORY_ERROR)
 	set = tmp;
     }
     oldset = (xmlLocationSetPtr) set->user;