Roll libxml to e4fb36841800038c289997432ca547c9bfef9db1

- roll.py has been updated to apply local patches *before* attempting to
  configure libxml. This allows issues at Makefile generation to also be
  locally patched if needed.
- roll.py now uses input redirection for applying patches, so missing
  patch files are now a fatal error. Missing files would previously be
  ignored, since only the exit code of the final command in a sequence
  of piped commands is considered for success/failure.
- libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch
  is no longer needed. This has been fixed an alternate way upstream,
  though it is somewhat unclear why parsing a port number larger than
  65535 is desirable.
- revert-non-recursive-xml-parsing.patch: recursive to non-recursive
  conversion of XML parser is causing test failures.
- add-missing-ifdef-in-xml-reader.patch: add a preprocessor check around
  error handling for a feature that is disabled in Chrome.

Change-Id: Iee172f9142146224b70cc35d3b97ced6786c1b25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2142719
Reviewed-by: Stephen Chenney <schenney@chromium.org>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#759622}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 4677fa6fd696cca268666097b8ba8c132bbe3ab5
diff --git a/README.chromium b/README.chromium
index bbe3179..638320e 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,6 +1,6 @@
 Name: libxml
 URL: http://xmlsoft.org
-Version: a7fe7ee45938c53a8dd028dd40baa461191a2fd2
+Version: e4fb36841800038c289997432ca547c9bfef9db1
 CPEPrefix: cpe:/a:xmlsoft:libxml2:2.9.9
 License: MIT
 License File: src/Copyright
@@ -11,16 +11,20 @@
 libxml2 from libxml.org.
 
 Modifications:
-- Add helper classes in the chromium/ subdirectory.
-- Applied these patches in chromium/*.patch:
-  chromium-issue-599427.patch: workaround for VS 2015 Update 2 code-gen bug
-  chromium-issue-628581.patch: See https://crbug.com/628581#c18
-  chromium-issue-894933.patch: Use ptrdiff_t instead of unsigned long for
+
+- chromium-issue-599427.patch: workaround for VS 2015 Update 2 code-gen bug
+- chromium-issue-628581.patch: See https://crbug.com/628581#c18
+- chromium-issue-894933.patch: Use ptrdiff_t instead of unsigned long for
     pointer differences in parser.c
-  libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch:
+- libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch:
     See https://crbug.com/708433
-  libxml2-2.9.4-security-xpath-nodetab-uaf.patch: See https://crbug.com/705445
-  chromium-issue-708434.patch: Guard against input counter overflow.
+- libxml2-2.9.4-security-xpath-nodetab-uaf.patch: See https://crbug.com/705445
+- chromium-issue-708434.patch: Guard against input counter overflow.
+- revert-non-recursive-xml-parsing.patch: Making parts of the XML parser
+    non-recursive broke a few web platform tests.
+- add-missing-ifdef-in-xml-reader.patch: Bug fix forgot to guard functionality
+    with appropriate #ifdef.
+- Add helper classes in the chromium/ subdirectory.
 - Delete various unused files, see chromium/roll.py
 
 This import was generated by the chromium/roll.py script.
diff --git a/chromium/add-missing-ifdef-in-xml-reader.patch b/chromium/add-missing-ifdef-in-xml-reader.patch
new file mode 100644
index 0000000..17cd15a
--- /dev/null
+++ b/chromium/add-missing-ifdef-in-xml-reader.patch
@@ -0,0 +1,13 @@
+--- a/xmlreader.c
++++ b/xmlreader.c
+@@ -2262,8 +2262,10 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
+ 	    reader->dict = NULL;
+ 	if ((reader->ctxt->vctxt.vstateTab != NULL) &&
+ 	    (reader->ctxt->vctxt.vstateMax > 0)){
++#ifdef LIBXML_REGEXP_ENABLED
+             while (reader->ctxt->vctxt.vstateNr > 0)
+                 xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
++#endif /* LIBXML_REGEXP_ENABLED */
+ 	    xmlFree(reader->ctxt->vctxt.vstateTab);
+ 	    reader->ctxt->vctxt.vstateTab = NULL;
+ 	    reader->ctxt->vctxt.vstateMax = 0;
diff --git a/chromium/chromium-issue-628581.patch b/chromium/chromium-issue-628581.patch
index 2fcf4e5..a4bb714 100644
--- a/chromium/chromium-issue-628581.patch
+++ b/chromium/chromium-issue-628581.patch
@@ -57,7 +57,7 @@
 index ca9fde2c..4264445a 100644
 --- a/parser.c
 +++ b/parser.c
-@@ -137,18 +137,24 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
+@@ -143,18 +143,25 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
       * This may look absurd but is needed to detect
       * entities problems
       */
@@ -65,10 +65,11 @@
 +        xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
 +        return (1);
 +    }
++
      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;
+ 	unsigned long oldnbent = ctxt->nbentities, diff;
  	xmlChar *rep;
  
 +        ent->guard = XML_ENTITY_BEING_CHECKED;
@@ -82,7 +83,7 @@
  	if ((rep == NULL) || (ctxt->errNo == XML_ERR_ENTITY_LOOP)) {
  	    ent->content[0] = 0;
  	}
-@@ -7105,23 +7111,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
+@@ -7116,23 +7123,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
  	 * if its replacement text matches the production labeled
  	 * content.
  	 */
@@ -128,7 +129,7 @@
  
  	/*
  	 * Store the number of entities needing parsing for this entity
-@@ -7229,23 +7240,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
+@@ -7239,23 +7251,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
  	    else
  		user_data = ctxt->userData;
  
diff --git a/chromium/libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch b/chromium/libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch
deleted file mode 100644
index d0d877d..0000000
--- a/chromium/libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-https://bugzilla.gnome.org/show_bug.cgi?id=780690
-
---- src/uri.c
-+++ src/uri.c
-@@ -334,7 +335,7 @@ xmlParse3986Port(xmlURIPtr uri, const char **str)
- 	    cur++;
- 	}
- 	if (uri != NULL)
--	    uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */
-+	    uri->port = port & USHRT_MAX; /* port value modulo USHRT_MAX+1 */
- 	*str = cur;
- 	return(0);
-     }
diff --git a/chromium/revert-non-recursive-xml-parsing.patch b/chromium/revert-non-recursive-xml-parsing.patch
new file mode 100644
index 0000000..e81c7c2
--- /dev/null
+++ b/chromium/revert-non-recursive-xml-parsing.patch
@@ -0,0 +1,268 @@
+diff --git a/parser.c b/parser.c
+index 072eb22d..f863edd1 100644
+--- a/parser.c
++++ b/parser.c
+@@ -96,12 +96,6 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+ 
+ static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+ 
+-static int
+-xmlParseElementStart(xmlParserCtxtPtr ctxt);
+-
+-static void
+-xmlParseElementEnd(xmlParserCtxtPtr ctxt);
+-
+ /************************************************************************
+  *									*
+  *	Arbitrary limits set in the parser. See XML_PARSE_HUGE		*
+@@ -1828,6 +1822,7 @@ nodePop(xmlParserCtxtPtr ctxt)
+     return (ret);
+ }
+ 
++#ifdef LIBXML_PUSH_ENABLED
+ /**
+  * nameNsPush:
+  * @ctxt:  an XML parser context
+@@ -1863,11 +1858,6 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value,
+ 	    goto mem_error;
+         }
+ 	ctxt->pushTab = tmp2;
+-    } else if (ctxt->pushTab == NULL) {
+-        ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
+-                                            sizeof(ctxt->pushTab[0]));
+-        if (ctxt->pushTab == NULL)
+-            goto mem_error;
+     }
+     ctxt->nameTab[ctxt->nameNr] = value;
+     ctxt->name = value;
+@@ -1879,7 +1869,6 @@ mem_error:
+     xmlErrMemory(ctxt, NULL);
+     return (-1);
+ }
+-#ifdef LIBXML_PUSH_ENABLED
+ /**
+  * nameNsPop:
+  * @ctxt: an XML parser context
+@@ -9812,10 +9801,9 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ 
+ void
+ xmlParseContent(xmlParserCtxtPtr ctxt) {
+-    int nameNr = ctxt->nameNr;
+-
+     GROW;
+     while ((RAW != 0) &&
++	   ((RAW != '<') || (NXT(1) != '/')) &&
+ 	   (ctxt->instate != XML_PARSER_EOF)) {
+ 	const xmlChar *test = CUR_PTR;
+ 	unsigned int cons = ctxt->input->consumed;
+@@ -9849,13 +9837,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
+ 	 * Fourth case :  a sub-element.
+ 	 */
+ 	else if (*cur == '<') {
+-            if (NXT(1) == '/') {
+-                if (ctxt->nameNr <= nameNr)
+-                    break;
+-	        xmlParseElementEnd(ctxt);
+-            } else {
+-	        xmlParseElementStart(ctxt);
+-            }
++	    xmlParseElement(ctxt);
+ 	}
+ 
+ 	/*
+@@ -9890,7 +9872,7 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
+  * xmlParseElement:
+  * @ctxt:  an XML parser context
+  *
+- * parse an XML element
++ * parse an XML element, this is highly recursive
+  *
+  * [39] element ::= EmptyElemTag | STag content ETag
+  *
+@@ -9902,23 +9884,6 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
+ 
+ void
+ xmlParseElement(xmlParserCtxtPtr ctxt) {
+-    if (xmlParseElementStart(ctxt) != 0)
+-        return;
+-    xmlParseContent(ctxt);
+-    if (ctxt->instate == XML_PARSER_EOF)
+-	return;
+-    xmlParseElementEnd(ctxt);
+-}
+-
+-/**
+- * xmlParseElementStart:
+- * @ctxt:  an XML parser context
+- *
+- * Parse the start of an XML element. Returns -1 in case of error, 0 if an
+- * opening tag was parsed, 1 if an empty element was parsed.
+- */
+-static int
+-xmlParseElementStart(xmlParserCtxtPtr ctxt) {
+     const xmlChar *name;
+     const xmlChar *prefix = NULL;
+     const xmlChar *URI = NULL;
+@@ -9933,7 +9898,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
+ 		 "Excessive depth in document: %d use XML_PARSE_HUGE option\n",
+ 			  xmlParserMaxDepth);
+ 	xmlHaltParser(ctxt);
+-	return(-1);
++	return;
+     }
+ 
+     /* Capture start position */
+@@ -9960,17 +9925,12 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
+ 	name = xmlParseStartTag(ctxt);
+ #endif /* LIBXML_SAX1_ENABLED */
+     if (ctxt->instate == XML_PARSER_EOF)
+-	return(-1);
++	return;
+     if (name == NULL) {
+ 	spacePop(ctxt);
+-        return(-1);
++        return;
+     }
+-    if (ctxt->sax2)
+-        nameNsPush(ctxt, name, prefix, URI, ctxt->nsNr - nsNr);
+-#ifdef LIBXML_SAX1_ENABLED
+-    else
+-        namePush(ctxt, name);
+-#endif /* LIBXML_SAX1_ENABLED */
++    namePush(ctxt, name);
+     ret = ctxt->node;
+ 
+ #ifdef LIBXML_VALID_ENABLED
+@@ -10011,7 +9971,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
+ 	   node_info.node = ret;
+ 	   xmlParserAddNodeInfo(ctxt, &node_info);
+ 	}
+-	return(1);
++	return;
+     }
+     if (RAW == '>') {
+         NEXT1;
+@@ -10039,39 +9999,41 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
+ 	   node_info.node = ret;
+ 	   xmlParserAddNodeInfo(ctxt, &node_info);
+ 	}
+-	return(-1);
++	return;
+     }
+ 
+-    return(0);
+-}
+-
+-/**
+- * xmlParseElementEnd:
+- * @ctxt:  an XML parser context
+- *
+- * Parse the end of an XML element.
+- */
+-static void
+-xmlParseElementEnd(xmlParserCtxtPtr ctxt) {
+-    xmlParserNodeInfo node_info;
+-    xmlNodePtr ret = ctxt->node;
++    /*
++     * Parse the content of the element:
++     */
++    xmlParseContent(ctxt);
++    if (ctxt->instate == XML_PARSER_EOF)
++	return;
++    if (!IS_BYTE_CHAR(RAW)) {
++        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
++	 "Premature end of data in tag %s line %d\n",
++		                name, line, NULL);
+ 
+-    if (ctxt->nameNr <= 0)
+-        return;
++	/*
++	 * end of parsing of this node.
++	 */
++	nodePop(ctxt);
++	namePop(ctxt);
++	spacePop(ctxt);
++	if (nsNr != ctxt->nsNr)
++	    nsPop(ctxt, ctxt->nsNr - nsNr);
++	return;
++    }
+ 
+     /*
+      * parse the end of tag: '</' should be here.
+      */
+     if (ctxt->sax2) {
+-        const xmlChar *prefix = ctxt->pushTab[ctxt->nameNr * 3 - 3];
+-        const xmlChar *URI = ctxt->pushTab[ctxt->nameNr * 3 - 2];
+-        int nsNr = (ptrdiff_t) ctxt->pushTab[ctxt->nameNr * 3 - 1];
+-	xmlParseEndTag2(ctxt, prefix, URI, 0, nsNr, 0);
++	xmlParseEndTag2(ctxt, prefix, URI, line, ctxt->nsNr - nsNr, tlen);
+ 	namePop(ctxt);
+     }
+ #ifdef LIBXML_SAX1_ENABLED
+-    else
+-	xmlParseEndTag1(ctxt, 0);
++      else
++	xmlParseEndTag1(ctxt, line);
+ #endif /* LIBXML_SAX1_ENABLED */
+ 
+     /*
+@@ -12388,6 +12350,13 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
+ 	return(NULL);
+     }
+     ctxt->dictNames = 1;
++    ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 * sizeof(xmlChar *));
++    if (ctxt->pushTab == NULL) {
++        xmlErrMemory(ctxt, NULL);
++	xmlFreeParserInputBuffer(buf);
++	xmlFreeParserCtxt(ctxt);
++	return(NULL);
++    }
+     if (sax != NULL) {
+ #ifdef LIBXML_SAX1_ENABLED
+ 	if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
+@@ -14835,6 +14804,16 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
+ 
+     xmlCtxtReset(ctxt);
+ 
++    if (ctxt->pushTab == NULL) {
++        ctxt->pushTab = (void **) xmlMalloc(ctxt->nameMax * 3 *
++	                                    sizeof(xmlChar *));
++        if (ctxt->pushTab == NULL) {
++	    xmlErrMemory(ctxt, NULL);
++            xmlFreeParserInputBuffer(buf);
++            return(1);
++        }
++    }
++
+     if (filename == NULL) {
+         ctxt->directory = NULL;
+     } else {
+diff --git a/result/errors/754947.xml.err b/result/errors/754947.xml.err
+index 51e9b4ed..f45cb5a2 100644
+--- a/result/errors/754947.xml.err
++++ b/result/errors/754947.xml.err
+@@ -2,6 +2,6 @@
+ Bytes: 0xEE 0x5D 0x5D 0x3E
+ <d><![CDATA[0000000000000î]]>
+                          ^
+-./test/errors/754947.xml:1: parser error : EndTag: '</' not found
++./test/errors/754947.xml:1: parser error : Premature end of data in tag d line 1
+ <d><![CDATA[0000000000000î]]>
+                              ^
+diff --git a/result/errors/759398.xml.err b/result/errors/759398.xml.err
+index bc9e5e03..f6036a3b 100644
+--- a/result/errors/759398.xml.err
++++ b/result/errors/759398.xml.err
+@@ -1,10 +1,10 @@
+ ./test/errors/759398.xml:210: parser error : StartTag: invalid element name
+ need to worry about parsers whi<! don't expand PErefs finding
+                                 ^
+-./test/errors/759398.xml:309: parser error : Opening and ending tag mismatch: №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№m line 205 and termdef
++./test/errors/759398.xml:309: parser error : Opening and ending tag mismatch: №№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№№m line 308 and termdef
+ and provide access to their content and structure.</termdef> <termdef
+                                                             ^
+-./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 205 and p
++./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 50 and p
+ data and the information it must provide to the application.</p>
+                                                                 ^
+ ./test/errors/759398.xml:316: parser error : Extra content at the end of the document
diff --git a/chromium/roll.py b/chromium/roll.py
index 5dadf62..a75c3bb 100755
--- a/chromium/roll.py
+++ b/chromium/roll.py
@@ -31,8 +31,14 @@
 # 2. On Linux:
 #    a. sudo apt-get install libicu-dev
 #    b. git clone https://github.com/GNOME/libxml2.git somewhere
-# 3. On Mac, install these MacPorts:
-#    autoconf automake libtool pkgconfig icu
+# 3. On Mac, install these packages with brew:
+#      autoconf automake libtool pkgconfig icu4c
+#
+#    Important! Before running roll.py, set these environmental variables so the
+#    configure script can find ICU:
+#      export LDFLAGS="-L/path/to/homebrew/opt/icu4c/lib"
+#      export CPPFLAGS="-I/path/to/homebrew/opt/icu4c/include"
+#      export PKG_CONFIG_PATH="/path/to/homebrew/opt/icu4c/lib/pkgconfig"
 #
 # Procedure:
 #
@@ -66,11 +72,14 @@
 #    e. Complete the review as usual
 
 PATCHES = [
+    # TODO(dcheng): reach out upstream to see what's going on here.
+    'revert-non-recursive-xml-parsing.patch',
     'chromium-issue-599427.patch',
     'chromium-issue-628581.patch',
-    'libxml2-2.9.4-security-CVE-2017-7376-nanohttp-out-of-bounds-write.patch',
     'libxml2-2.9.4-security-xpath-nodetab-uaf.patch',
     'chromium-issue-708434.patch',
+    # TODO(dcheng): Merge this back upstream.
+    'add-missing-ifdef-in-xml-reader.patch',
 ]
 
 
@@ -295,10 +304,11 @@
             raise Exception('check COPYING')
 
 
-def prepare_libxml_distribution(libxml2_repo_path, temp_dir):
+def prepare_libxml_distribution(src_path, libxml2_repo_path, temp_dir):
     """Makes a libxml2 distribution.
 
     Args:
+        src_path: The path to the Chromium checkout.
         libxml2_repo_path: The path to the local clone of the libxml2 repo.
         temp_dir: A temporary directory to stage the distribution to.
 
@@ -326,6 +336,13 @@
             shell=True)
     with WorkingDir(temp_src_path):
         os.remove('.gitignore')
+        for patch in PATCHES:
+            print('applying %s' % patch)
+            subprocess.check_call(
+                'patch -p1 --fuzz=0 < %s' % os.path.join(
+                    src_path, THIRD_PARTY_LIBXML_SRC, '..', 'chromium', patch),
+                shell=True)
+
     with WorkingDir(temp_config_path):
         print('../src/autogen.sh %s' % XML_CONFIGURE_OPTIONS)
         subprocess.check_call(['../src/autogen.sh'] + XML_CONFIGURE_OPTIONS)
@@ -346,8 +363,8 @@
             temp_dir = tempfile.mkdtemp()
             print('temporary directory: %s' % temp_dir)
 
-            commit, tar_file = prepare_libxml_distribution(libxml2_repo_path,
-                                                           temp_dir)
+            commit, tar_file = prepare_libxml_distribution(
+                src_path, libxml2_repo_path, temp_dir)
 
             # Remove all of the old libxml to ensure only desired cruft
             # accumulates
@@ -366,12 +383,6 @@
             sed_in_place('../README.chromium',
                          's/Version: .*$/Version: %s/' % commit)
 
-            for patch in PATCHES:
-                print(patch)
-                subprocess.check_call(
-                    'cat ../chromium/%s | patch -p1 --fuzz=0' % patch,
-                    shell=True)
-
             with WorkingDir('../linux'):
                 subprocess.check_call(
                     ['../src/autogen.sh'] + XML_CONFIGURE_OPTIONS)
diff --git a/linux/config.h b/linux/config.h
index 7d273f6..e334240 100644
--- a/linux/config.h
+++ b/linux/config.h
@@ -267,7 +267,7 @@
 #define VA_LIST_IS_ARRAY 1
 
 /* Version number of package */
-#define VERSION "2.9.9"
+#define VERSION "2.9.10"
 
 /* Determine what socket length (socklen_t) data type is */
 #define XML_SOCKLEN_T socklen_t
diff --git a/linux/include/libxml/xmlversion.h b/linux/include/libxml/xmlversion.h
index 59cc485..37f673e 100644
--- a/linux/include/libxml/xmlversion.h
+++ b/linux/include/libxml/xmlversion.h
@@ -1,6 +1,6 @@
 /*
- * Summary: compile-time version informations
- * Description: compile-time version informations for the XML library
+ * Summary: compile-time version information
+ * Description: compile-time version information for the XML library
  *
  * Copy: See Copyright for the status of this software.
  *
@@ -29,21 +29,21 @@
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.9.9"
+#define LIBXML_DOTTED_VERSION "2.9.10"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20909
+#define LIBXML_VERSION 20910
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20909"
+#define LIBXML_VERSION_STRING "20910"
 
 /**
  * LIBXML_VERSION_EXTRA:
@@ -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(20909);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20910);
 
 #ifndef VMS
 #if 0
@@ -91,11 +91,8 @@
  * Whether the thread support is configured in
  */
 #if 0
-#if defined(_REENTRANT) || defined(__MT__) || \
-    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
 #define LIBXML_THREAD_ENABLED
 #endif
-#endif
 
 /**
  * LIBXML_THREAD_ALLOC_ENABLED:
@@ -353,6 +350,8 @@
  * LIBXML_EXPR_ENABLED:
  *
  * Whether the formal expressions interfaces are compiled in
+ *
+ * This code is unused and disabled unconditionally for now.
  */
 #if 0
 #define LIBXML_EXPR_ENABLED
diff --git a/linux/xml2-config b/linux/xml2-config
index 9ae2109..7a271d4 100755
--- a/linux/xml2-config
+++ b/linux/xml2-config
@@ -4,6 +4,8 @@
 exec_prefix=${prefix}
 includedir=${prefix}/include
 libdir=${exec_prefix}/lib
+cflags=
+libs=
 
 usage()
 {
@@ -15,6 +17,7 @@
   --prefix=DIR		change libxml prefix [default $prefix]
   --exec-prefix=DIR	change libxml exec prefix [default $exec_prefix]
   --libs		print library linking information
+                        add --dynamic to print only shared libraries
   --cflags		print pre-processor and compiler flags
   --modules		module support enabled
   --help		display this help and exit
@@ -28,9 +31,6 @@
     usage 1
 fi
 
-cflags=false
-libs=false
-
 while test $# -gt 0; do
     case "$1" in
     -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
@@ -58,7 +58,7 @@
       ;;
 
     --version)
-	echo 2.9.9
+	echo 2.9.10
 	exit 0
 	;;
 
@@ -67,7 +67,7 @@
 	;;
 
     --cflags)
-       	echo -I${includedir}/libxml2 
+        cflags="-I${includedir}/libxml2 "
        	;;
 
     --libtool-libs)
@@ -82,25 +82,29 @@
        	;;
 
     --libs)
-        if [ "`uname`" = "Linux" ]
-	then
-	    if [ "-L${libdir}" = "-L/usr/lib" -o "-L${libdir}" = "-L/usr/lib64" ]
-	    then
-		echo -lxml2     -licui18n -licuuc -licudata -lm  
-	    else
-		echo -L${libdir} -lxml2     -licui18n -licuuc -licudata -lm  
-	    fi
-	else
-	    echo -L${libdir} -lxml2     -licui18n -licuuc -licudata -lm   
-	fi
-       	;;
+        if [ "$2" = "--dynamic" ]; then
+            shift
+            libs="-lxml2"
+        else
+            libs="-lxml2     -licui18n -licuuc -licudata -lm  "
+        fi
+
+        if [ "-L${libdir}" != "-L/usr/lib" -a "-L${libdir}" != "-L/usr/lib64" ]; then
+            libs="-L${libdir} $libs"
+        fi
+
+        libs="$libs "
+        ;;
 
     *)
-	usage
-	exit 1
+	usage 1
 	;;
     esac
     shift
 done
 
+if test -n "$cflags$libs"; then
+    echo $cflags $libs
+fi
+
 exit 0
diff --git a/mac/config.h b/mac/config.h
index 047e066..16cd0ae 100644
--- a/mac/config.h
+++ b/mac/config.h
@@ -267,7 +267,7 @@
 #define VA_LIST_IS_ARRAY 1
 
 /* Version number of package */
-#define VERSION "2.9.9"
+#define VERSION "2.9.10"
 
 /* Determine what socket length (socklen_t) data type is */
 #define XML_SOCKLEN_T socklen_t
diff --git a/mac/include/libxml/xmlversion.h b/mac/include/libxml/xmlversion.h
index 59cc485..37f673e 100644
--- a/mac/include/libxml/xmlversion.h
+++ b/mac/include/libxml/xmlversion.h
@@ -1,6 +1,6 @@
 /*
- * Summary: compile-time version informations
- * Description: compile-time version informations for the XML library
+ * Summary: compile-time version information
+ * Description: compile-time version information for the XML library
  *
  * Copy: See Copyright for the status of this software.
  *
@@ -29,21 +29,21 @@
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.9.9"
+#define LIBXML_DOTTED_VERSION "2.9.10"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20909
+#define LIBXML_VERSION 20910
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20909"
+#define LIBXML_VERSION_STRING "20910"
 
 /**
  * LIBXML_VERSION_EXTRA:
@@ -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(20909);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20910);
 
 #ifndef VMS
 #if 0
@@ -91,11 +91,8 @@
  * Whether the thread support is configured in
  */
 #if 0
-#if defined(_REENTRANT) || defined(__MT__) || \
-    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
 #define LIBXML_THREAD_ENABLED
 #endif
-#endif
 
 /**
  * LIBXML_THREAD_ALLOC_ENABLED:
@@ -353,6 +350,8 @@
  * LIBXML_EXPR_ENABLED:
  *
  * Whether the formal expressions interfaces are compiled in
+ *
+ * This code is unused and disabled unconditionally for now.
  */
 #if 0
 #define LIBXML_EXPR_ENABLED
diff --git a/src/ChangeLog b/src/ChangeLog
index 896fbbb..2640670 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -379,7 +379,7 @@
 	* test/schemas/regexp-char-ref_0.xml test/schemas/regexp-char-ref_0.xsd
 	  test/schemas/regexp-char-ref_1.xsd result/schemas/regexp-char-ref_0_0
 	  result/schemas/regexp-char-ref_1_0: Volker Grabsch also provided
-	  regession tests for this
+	  regression tests for this
 
 Tue Aug 26 09:25:39 CEST 2008 Daniel Veillard <daniel@veillard.com>
 
@@ -463,7 +463,7 @@
 	  allow to make Name and NmToken validations based on the parser
 	  flags, more specifically the 5th edition of XML or not
 	* HTMLparser.c tree.c: small side effects for the previous changes
-	* parser.c SAX2.c valid.c: the bulk of teh changes are here,
+	* parser.c SAX2.c valid.c: the bulk of the changes are here,
 	  the parser and validation behaviour can be affected, parsing
 	  flags need to be copied, lot of changes. Also fixing various
 	  validation problems in the regression tests.
@@ -475,7 +475,7 @@
 	* include/libxml/xmlerror.h parser.c: clean up namespace errors
 	  checking and reporting, errors when a document is labelled
 	  as UTF-16 while it is parsed as UTF-8 and no encoding was given
-	  explicitely.
+	  explicitly.
 	* result/errors/webdav.xml.*: some warnings are no recategorized
 	  as Namespace errors
 
@@ -663,7 +663,7 @@
 
 Thu Apr  3 11:02:02 CEST 2008 Daniel Veillard <daniel@veillard.com>
 
-	* HTMLparser.c: apparently it's okay to forget the semicolumn after
+	* HTMLparser.c: apparently it's okay to forget the semicolon after
 	  entity refs in HTML, fixing char refs parsing accordingly based on
 	  T. Manske patch, this should fix #517653
 
@@ -787,7 +787,7 @@
 
 Wed Mar 12 10:22:01 CET 2008 Daniel Veillard <daniel@veillard.com>
 
-	* python/types.c: fix a memory errro when using namespace nodes
+	* python/types.c: fix a memory error when using namespace nodes
 	  returned from XPath queries, should fix #521699
 	* python/tests/Makefile.am python/tests/xpathns.py: add a specific
 	  regression test for it
@@ -917,7 +917,7 @@
 
 Thu Jan 24 15:37:04 CET 2008 Daniel Veillard <daniel@veillard.com>
 
-	* parser.c: fix a memeory leak in internal subset parsing with
+	* parser.c: fix a memory leak in internal subset parsing with
 	  a fix from Ashwin
 	* test/errors/content1.xml result/errors/content1.xml*:
 	  add test to regressions
@@ -1230,7 +1230,7 @@
 
 	* list.c: applied patch to fix xmlListAppend() from 
 	  Georges-André SILBER
-	* valid.c: also fix the place wher it was called.
+	* valid.c: also fix the place where it was called.
 
 Wed May  2 18:47:33 CEST 2007 Daniel Veillard <daniel@veillard.com>
 
@@ -1328,7 +1328,7 @@
 Tue Mar 20 09:58:13 CET 2007  Daniel Veillard <daniel@veillard.com>
 
 	* nanoftp.c: applied patch from Björn Wiberg to try to fix again
-	  the silly __ss_familly problem on various AIXes, should fix #420184
+	  the silly __ss_family problem on various AIXes, should fix #420184
 
 Wed Mar 14 20:30:38 HKT 2007 William Brack <wbrack@mmm.com.hk>
 
@@ -1424,7 +1424,7 @@
 	  test/relaxng/empty1_0.xml test/relaxng/comps.rng
 	  test/relaxng/empty0.rng test/relaxng/empty0_0.xml
 	  test/relaxng/empty1_1.xml: tests which were apparently 
-	  never commited to CVS
+	  never committed to CVS
 
 Wed Jan  3 16:05:21 PST 2007 Aleksey Sanin <aleksey@aleksey.com>
 
@@ -1519,7 +1519,7 @@
 
 Tue Oct 17 22:04:31 CEST 2006 Daniel Veillard <daniel@veillard.com>
 
-	* HTMLparser.c: fixed teh 2 stupid bugs affecting htmlReadDoc() and
+	* HTMLparser.c: fixed the 2 stupid bugs affecting htmlReadDoc() and
 	  htmlReadIO() this should fix #340322
 
 Tue Oct 17 21:39:23 CEST 2006 Daniel Veillard <daniel@veillard.com>
@@ -1531,7 +1531,7 @@
 	* HTMLparser.c: fixing HTML minimized attribute values to be generated
 	  internally if not present, fixes bug #332124
 	* result/HTML/doc2.htm.sax result/HTML/doc3.htm.sax 
-	  result/HTML/wired.html.sax: this affects the SAX event strem for
+	  result/HTML/wired.html.sax: this affects the SAX event stream for
 	  a few test cases
 
 Tue Oct 17 17:56:31 CEST 2006 Daniel Veillard <daniel@veillard.com>
@@ -1627,7 +1627,7 @@
 
 Wed Oct 11 18:40:00 CEST 2006 Daniel Veillard <daniel@veillard.com>
 
-	* valid.c: fixed a weird error where validity context whould not
+	* valid.c: fixed a weird error where validity context would not
 	  show up if warnings were disabled pointed out by Bob Stayton
 	* xmlIO.c doc/generator.py: cleanup and fix to regenerate the docs
 	* doc//* testapi.c: rebuilt the docs
@@ -1680,7 +1680,7 @@
 Tue Oct 10 10:33:43 CEST 2006 Daniel Veillard <daniel@veillard.com>
 
 	* python/libxml.py python/types.c: applied patch from Ross Reedstrom,
-	  Brian West and Stefan Anca to add XPointer suport to the Python bindings
+	  Brian West and Stefan Anca to add XPointer support to the Python bindings
 
 Fri Sep 29 11:13:59 CEST 2006 Daniel Veillard <daniel@veillard.com>
 
@@ -1740,7 +1740,7 @@
 Wed Aug 16 01:15:12 CEST 2006 Rob Richards <rrichards@ctindustries.net>
 
 	* HTMLtree.c xmlsave.c: Add linefeeds to error messages allowing 
-	  for consistant handling.
+	  for consistent handling.
 
 Tue Aug 15 15:02:18 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
@@ -1857,7 +1857,7 @@
 	  initialized to zero here; this could lead to the activation
 	  of the axis rewrite code in xmlXPathNodeCollectAndTest() when
 	  @rewriteType is randomly set to the value 1. A test
-	  (hardcoding the intial value to 1) revealed that the
+	  (hardcoding the initial value to 1) revealed that the
 	  resulting incorrect behaviour is similar to the behaviour
 	  as described by Arnold Hendriks on the mailing list; so I
 	  hope that will fix the issue.	  
@@ -1912,7 +1912,7 @@
 	  for my custom handling of ns-references in my DOM wrapper.
 	  Substituted code which created the XML namespace decl on
 	  the doc for a call to xmlTreeEnsureXMLDecl(). Removed
-	  those nastly "warnigns" from the docs of the clone/adopt
+	  those nasty "warnings" from the docs of the clone/adopt
 	  functions; they work fine on my side.
 	  
 Mon Jun 12 13:23:11 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
@@ -2022,7 +2022,7 @@
 
 	* xpath.c: Enhanced xmlXPathNodeCollectAndTest() to avoid
 	  recreation (if possible) of the node-set which is used to
-	  collect the nodes in the current axis for the currect context
+	  collect the nodes in the current axis for the current context
 	  node. Especially for "//foo" this will decrease dramatically
 	  the number of created node-sets, since for each node in the
 	  result node-set of the evaluation of descendant-or-self::node()
@@ -2033,7 +2033,7 @@
 Mon May 29 18:06:17 CEST 2006 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
 	* xpath.c include/libxml/xpath.h: Added an XPath object cache.
-	  It sits on an xmlXPathContext and need to be explicitely
+	  It sits on an xmlXPathContext and need to be explicitly
 	  activated (or deactivated again) with
 	  xmlXPathContextSetObjectCache(). The cache consists of 5
 	  lists for node-set, string, number, boolean and misc XPath
@@ -2052,18 +2052,18 @@
 
 	* xpath.c: Removed a memcpy if xmlXPathNodeSetMerge(); it
 	  seems we really need to walk the whole list, since those
-	  nastly namespace nodes need to be added with
+	  nasty namespace nodes need to be added with
 	  xmlXPathNodeSetDupNs(); thus a pure memcpy is not possible.
 	  A flag on the node-set indicating if namespace nodes are in
 	  the set would help here; this is the 3rd flag which would
-	  be usefull with node-sets. The current flags I have in mind:
+	  be useful with node-sets. The current flags I have in mind:
 	  1) Is a node-set already sorted?
 	     This would allow for rebust and optimizable sorting
 	     behaviour.
 	  2) Of what type are the nodes in the set (or of mixed type)?
 	     This would allow for faster merging of node-sets.
 	  3) Are namespace nodes in the set?
-	     This would allow to skipp all the namespace node specific
+	     This would allow to skip all the namespace node specific
 	     special handling. Faster node-set merging if the first
 	     set is empty; just memcpy the set.
 
@@ -2112,7 +2112,7 @@
 	  compilation time (unlike normal XPath, where we can bind
 	  namespace names to prefixes at execution time).
 	* pattern.c: Enhanced to use a string dict for local-names,
-	  ns-prefixes and and namespace-names.
+	  ns-prefixes and namespace-names.
 	  Fixed xmlStreamPushInternal() not to use string-pointer
 	  comparison if a dict is available; this won't work, since
 	  one does not know it the given strings originate from the
@@ -2269,7 +2269,7 @@
 Fri Mar 10 08:40:55 EST 2006 Daniel Veillard <daniel@veillard.com>
 
 	* c14n.c encoding.c xmlschemas.c xpath.c xpointer.c: fix a few
-	  warning raised by gcc-4.1 and latests changes
+	  warning raised by gcc-4.1 and latest changes
 
 Fri Mar 10 01:34:42 CET 2006 Daniel Veillard <daniel@veillard.com>
 
@@ -2485,7 +2485,7 @@
 
 Thu Jan  5 16:25:06 CET 2006 Daniel Veillard <daniel@veillard.com>
 
-	* NEWS configure.in libxml.spec.in testapi.c doc/*: upated the news
+	* NEWS configure.in libxml.spec.in testapi.c doc/*: updated the news
 	  regenerated the docs, preparing for release of 2.6.23
 	* pattern.c xmlschemas.c: fixed some comments
 	
@@ -2520,7 +2520,7 @@
 Wed Jan  4 15:00:51 CET 2006 Daniel Veillard <daniel@veillard.com>
 
 	* SAX2.c: fix bug #324432 with <xml:foo/>
-	* test/ns7 resul//ns7*: added to the regression tests
+	* test/ns7 result/ns7*: added to the regression tests
 
 Wed Jan  4 10:53:56 CET 2006 Daniel Veillard <daniel@veillard.com>
 
@@ -2861,7 +2861,7 @@
 
 Wed Oct 19 16:53:47 BST 2005 Daniel Veillard <daniel@veillard.com>
 
-	* xmlregexp.c: commiting a some fixes and debug done yesterday in
+	* xmlregexp.c: committing a some fixes and debug done yesterday in
 	  the London airport.
 
 Thu Oct 20 12:54:23 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
@@ -2932,7 +2932,7 @@
 	  Allowed IDCs to resolve also to nodes of complex type with
 	  simple content.
 	  Added check for keyrefs with references to keyrefs.
-	  IDC target-nodes were interferring with IDC node-tables,
+	  IDC target-nodes were interfering with IDC node-tables,
 	  since they used one list of entries only. I separated this
 	  one big list into 3 lists: 1 for IDC node-table entries,
 	  1 for _duplicates_ of IDC node-table entries and 1 for
@@ -2967,12 +2967,12 @@
 	  Fixed default/fixed values for attributes (looks like they
 	  did not work in the last  releases).
 	  Completed constraints for attribute uses.
-	  Seperated attribute derivation from attribute constraints.
+	  Separated attribute derivation from attribute constraints.
 	  Completed constraints for attribute group definitions.
 	  Disallowing <import>s of schemas in no target namespace if the
 	  importing schema is a chameleon schema. This contradicts
 	  the way Saxon, Xerces-J, XSV and IBM's SQC works, but the
-	  W3C XML Schema WG, thinks it is correct to dissalow such
+	  W3C XML Schema WG, thinks it is correct to disallow such
 	  imports.
 	  Added cos-all-limited constraints.
 	  Restructured reference resolution to model groups and element
@@ -3053,7 +3053,7 @@
 	* xmlschemas.c include/libxml/schemasInternals.h
 	  include/libxml/xmlerror.h: Completion of the schema graph.
 	  Centralisation, more robustness of the schema document
-	  aquisition story. Centralised and restructured component fixup.
+	  acquisition story. Centralised and restructured component fixup.
 	  Fixed attribute derivation when 'prohibiting' attribute uses.
 	  Added warnings: when schema documents cannot be localized
 	  during imports; when we get duplicate and pointless attribute
@@ -3385,7 +3385,7 @@
 	  list values.
 	* test/relaxng/307377* result/relaxng/307377* Makefile.am runtest.c:
 	  added examples to the regression tests, problem is that streaming
-	  version gives slightly more informations.
+	  version gives slightly more information.
 
 Wed Aug 10 15:25:53 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
@@ -3398,7 +3398,7 @@
 Tue Aug  9 23:37:22 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
 	* xmlregexp.c: fixed a determinism detection problem exposed by
-	  ##other tests commited by Kasimier, also added a small speedup
+	  ##other tests committed by Kasimier, also added a small speedup
 	  of determinism detection.
 	* test/results/any6_2_0* any8_1_0* any7_1_2* any7_2_2*: added 
 	  the results to the regression tests now
@@ -3424,7 +3424,7 @@
 	* result/schemas/any7* test/schemas/any7: completed the tests
 	  and added the results
 	* result/schemas/any3_0_0.err result/schemas/any5_0_0.err
-	  result/schemas/any5_1_0.err: this slightly chnages the output
+	  result/schemas/any5_1_0.err: this slightly changes the output
 	  from 3 existing tests
 
 Mon Aug  8 22:33:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
@@ -3468,7 +3468,7 @@
 
 Sun Aug  7 12:39:35 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
-	* test/relaxng/docbook_0.xml: get rid of the dependancy on a locally
+	* test/relaxng/docbook_0.xml: get rid of the dependency on a locally
 	  installed DTD
 	* uri.c include/libxml/uri.h xmlIO.c nanoftp.c nanohttp.c: try to
 	  cleanup the Path/URI conversion mess, needed fixing in various 
@@ -3522,7 +3522,7 @@
 
 Sat Jul 30 17:08:07 EDT 2005 Daniel Veillard <daniel@veillard.com>
 
-	* schematron.c xmllint.c include/libxml/schematron.h: commiting
+	* schematron.c xmllint.c include/libxml/schematron.h: committing
 	  work done on the plane last week-end
 
 Sat Jul 30 15:16:29 CEST 2005 Daniel Veillard <daniel@veillard.com>
@@ -4029,7 +4029,7 @@
 
 Sun Jun 26 20:08:24 CEST 2005 Daniel Veillard <daniel@veillard.com>
 
-	* include/libxml/valid.h valid.c: avoid name glob in agruments as
+	* include/libxml/valid.h valid.c: avoid name glob in arguments as
 	  it matches the glob() routine.
 	* runtest.c Makefile.am: first steps toward a C regression test
 	  framework.
@@ -4463,7 +4463,7 @@
 
 	* doc/apibuild.py doc/elfgcchack.xsl: revamped the elfgcchack.h 
 	  format to cope with gcc4 change of aliasing allowed scopes, had
-	  to add extra informations to doc/libxml2-api.xml to separate
+	  to add extra information to doc/libxml2-api.xml to separate
 	  the header from the c module source.
 	* *.c: updated all c library files to add a #define bottom_xxx
 	  and reimport elfgcchack.h thereafter, and a bit of cleanups.
@@ -4955,9 +4955,9 @@
 
 Fri Jan 28 16:51:47 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
-	* xmlschemas.c: Corrected an ambigious symbol-space for
+	* xmlschemas.c: Corrected an ambiguous symbol-space for
 	  local attribute declarations. IFDEFed more IDC code to
-	  surpress compiler warnings.
+	  suppress compiler warnings.
 
 Fri Jan 28 00:57:04 CET 2005 Daniel Veillard <daniel@veillard.com>
 
@@ -4978,9 +4978,9 @@
 	  Added an initial skeleton for indentity-constraints. This is all
 	  defined out, since not complete, plus it needs support from other
 	  modules.
-	  Added machanism to store element information for the
+	  Added mechanism to store element information for the
 	  ancestor-or-self axis; this is needed for identity-constraints
-	  and should be helpfull for a future streamable validation.
+	  and should be helpful for a future streamable validation.
 	* include/libxml/xmlerror.h: Added an error code for
 	  identity-constraints.
 
@@ -5028,7 +5028,7 @@
 
 Sun Jan 23 18:35:00 CET 2005 Daniel Veillard <daniel@veillard.com>
 
-	* parser.c: boosting common commnent parsing code, it was really
+	* parser.c: boosting common comment parsing code, it was really
 	  slow.
 	* test/comment[3-5].xml result//comment[3-5].xml*: added sprecific
 	  regression tests
@@ -5179,7 +5179,7 @@
 Fri Jan  7 14:54:51 CET 2005 Daniel Veillard <daniel@veillard.com>
 
 	* TODO: small update
-	* xmlregexp.c: trying to add an API to get useful error informations
+	* xmlregexp.c: trying to add an API to get useful error information
 	  back from a failing regexp context.
 
 Thu Jan  6 17:35:41 HKT 2005 William Brack <wbrack@mmm.com.hk>
@@ -5280,7 +5280,7 @@
 	
 Fri Dec 24 16:31:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
 
-	* python/generator.py: added most required entires to
+	* python/generator.py: added most required entries to
 	  foreign encoding table, plus some additional logic to
 	  assure only the 1st param uses the 't#' format.  Fixes
 	  bug #152286, but may still have some other UTF-16 problems.
@@ -5360,7 +5360,7 @@
 	  of elements for which a declaration existed were still processed
 	  by the wildcard mechanism (reported by philippe ventrillon to the
 	  mailing list).
-	  Changed the import and include machanism to share dictionaries.
+	  Changed the import and include mechanism to share dictionaries.
 
 Fri Nov 26 11:44:36 CET 2004 Daniel Veillard <daniel@veillard.com>
 
@@ -5639,8 +5639,8 @@
 	  automatic API regression test tool.
 	* SAX2.c nanoftp.c parser.c parserInternals.c tree.c xmlIO.c
 	  xmlstring.c: various API hardeing changes as a result of running
-	  teh first set of automatic API regression tests.
-	* test/slashdot16.xml: apparently missing from CVS, commited it
+	  the first set of automatic API regression tests.
+	* test/slashdot16.xml: apparently missing from CVS, committed it
 
 Mon Nov  1 15:54:18 CET 2004 Daniel Veillard <daniel@veillard.com>
 
@@ -5729,7 +5729,7 @@
 
 Fri Oct 22 21:04:20 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
-	* python/libxml.c: fixed a problem occuring only in x86_64 when
+	* python/libxml.c: fixed a problem occurring only in x86_64 when
 	  very large error messages are raised to the Python handlers.
 
 Thu Oct 21 18:03:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
@@ -5867,7 +5867,7 @@
 	  model group "all".
 	* test/schemas/bug152470_1.xsd: Removed an "abstract" attribute,
 	  which broke the test.
-	* xstc/xstc.py:  Workaround to accomodate case insensitive
+	* xstc/xstc.py:  Workaround to accommodate case insensitive
 	  test definitions in ms-test.def.xml (was missing in a previous
 	  commit).
 
@@ -5908,7 +5908,7 @@
 
 Thu Sep 23 18:23:46 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
-	* xmlschemastypes.c: fixing an out of bound adressing issue
+	* xmlschemastypes.c: fixing an out of bound addressing issue
 
 Thu Sep 23 15:14:12 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
@@ -5961,7 +5961,7 @@
 
 	* xmlschemas.c include/libxml/schemasInternals.h 
 	  test/schemas/bug152470_1.* result/schemas/bug152470_1_1*: 
-	  Simpified attribute wildcard creation and assignment to get rid 
+	  Simplified attribute wildcard creation and assignment to get rid 
 	  of memory leaks.
 	  Restructured the validation process.
 	  Restructured and expanded parsing of <attributeGroup>.
@@ -5978,7 +5978,7 @@
 	  'anyType' using the short-hand form (see bug # 152470,
 	  submitted by Thilo Jeremias).
 	* include/libxml/xmlschematypes.h: Cleaned up some comments.
-	* xstc/xstc.py: Workaround to accomodate case insensitive
+	* xstc/xstc.py: Workaround to accommodate case insensitive
 	  test definitions in ms-test.def.xml.
 	* result/schemas/deter0_0_0.err result/schemas/ns0_0_2.err
 	  result/schemas/ns0_1_2.err: Adapted.
@@ -6069,7 +6069,7 @@
 	  of the wildcard.
 	  Added a check for circular attribute group references.
 	  Added a check for circular model group definition references.
-	  Fixed a dublicate xmlParserErrors enum value - see bug #151738.
+	  Fixed a duplicate xmlParserErrors enum value - see bug #151738.
 
 Fri Sep  3 10:08:13 PDT 2004 William Brack <wbrack@mmmm.com.hk>
 
@@ -6275,7 +6275,7 @@
 	  include/libxml/xmlerror.h: cleanup to avoid 'error' identifier 
 	  in includes #137414
 	* parser.c SAX2.c debugXML.c include/libxml/parser.h:
-	  first version of the inplementation of parsing within
+	  first version of the implementation of parsing within
 	  the context of a node in the tree #142359, new function
 	  xmlParseInNodeContext(), added support at the xmllint --shell
 	  level as the "set" function
@@ -6321,7 +6321,7 @@
 	  to document xmlSchemasSetValidErrors() limitations, #141827
 	* error.c: Add information in generic and structured error
 	  setter functions that this need to be done per thread #144308
-	* xmlsave.c: fixed bug whith missing NOTATION(s) serialization
+	* xmlsave.c: fixed bug with missing NOTATION(s) serialization
 	  bug #144162
 	* doc/xmllint.xml: typo fix #144840
 
@@ -6691,7 +6691,7 @@
 Tue Jun  8 14:01:14 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c xmlreader.c include/libxml/parser.h: fixed a serious
-	  problem when substituing entities using the Reader, the entities
+	  problem when substituting entities using the Reader, the entities
 	  content might be freed and if rereferenced would crash
 	* Makefile.am test/* result/*: added a new test case and a new
 	  test operation for the reader with substitution of entities.
@@ -6847,7 +6847,7 @@
 Sat May 15 20:14:21 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
 	* doc/ChangeLog.awk doc/ChangeLog.xsl: first steps of a good
-	  ChangeLog page generation. The awk shoudl escape characters
+	  ChangeLog page generation. The awk should escape characters
 	  not okay in XML and the xslt should make links to functions
 	  or variables or bug reported in the entries.
 
@@ -6938,7 +6938,7 @@
 
 Sun May  9 19:46:13 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
-	* xmlsave.c: apply fix for XHTML1 formating from Nick Wellnhofer
+	* xmlsave.c: apply fix for XHTML1 formatting from Nick Wellnhofer
 	  fixes bug #141266
 	* test/xhtmlcomp result//xhtmlcomp*: added the specific regression
 	  test
@@ -7049,7 +7049,7 @@
 
 Sun Apr 18 22:51:43 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
-	* xpath.c: relaxed id() to not check taht the name(s) passed
+	* xpath.c: relaxed id() to not check that the name(s) passed
 	  are actually NCName, decided this in agreement with Aleksey Sanin
 	  since existing specs like Visa3D broke that conformance checking
 	  and other tools seems to not implement it sigh...
@@ -7062,7 +7062,7 @@
 	* xpath.c: work around Microsoft compiler NaN bug raise reported
 	  by Mark Vakoc
 	* xmlschemas.c include/libxml/schemasInternals.h 
-	  include/libxml/xmlerror.h: fixed a recusive extention schemas
+	  include/libxml/xmlerror.h: fixed a recursive extension schemas
 	  compilation error raised by taihei goi
 
 Sun Apr 18 16:57:02 CEST 2004 Daniel Veillard <daniel@veillard.com>
@@ -7228,7 +7228,7 @@
 
 	* configure.in doc/* News: preparing 2.6.8 release, updated and rebuilt
 	  the docs.
-	* Makefile.am: use valgring fro the new Python based regression tests
+	* Makefile.am: use valgring for the new Python based regression tests
 
 Mon Mar 22 20:07:27 CET 2004 Daniel Veillard <daniel@veillard.com>
 
@@ -7292,7 +7292,7 @@
 
 Wed Mar 10 19:42:22 HKT 2004 William Brack <wbrack@mmm.com.hk>
 
-	* doc/search.php: Minor change for later verson of php requiring
+	* doc/search.php: Minor change for later version of php requiring
 	  $HTTP_GET_VARS.
 
 Wed Mar 10 00:12:31 HKT 2004 William Brack <wbrack@mmm.com.hk>
@@ -7361,8 +7361,8 @@
 
 Thu Mar  4 14:39:38 CET 2004 Daniel Veillard <daniel@veillard.com>
 
-	* Makefile.am tree.c xmlsave.c include/libxml/xmlsave.h: commiting
-	  the new xmlsave module before the actuall big code change.
+	* Makefile.am tree.c xmlsave.c include/libxml/xmlsave.h: committing
+	  the new xmlsave module before the actual big code change.
 
 Thu Mar  4 12:38:53 CET 2004 Daniel Veillard <daniel@veillard.com>
 
@@ -7753,7 +7753,7 @@
 	  This is needed for XSLT to keep the stylesheet dictionary read-only
 	  while being able to reuse the strings for the transformation
 	  dictionary.
-	* xinclude.c: fixed a dictionary reference counting problem occuring
+	* xinclude.c: fixed a dictionary reference counting problem occurring
 	  when document parsing failed.
 	* testSAX.c: adding option --repeat for timing 100times the parsing
 	* doc/* : rebuilt all the docs
@@ -7872,7 +7872,7 @@
 
 Tue Jan  6 00:10:33 CET 2004 Daniel Veillard <daniel@veillard.com>
 
-	* rngparser.c: commiting the compact relax ng parser. It's not
+	* rngparser.c: committing the compact relax ng parser. It's not
 	  completely finished, it's not integrated but I want to save the
 	  current state
 
@@ -8026,7 +8026,7 @@
 Tue Dec 23 15:14:37 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
 	* valid.c: fixed bug concerning validation using external
-	  dtd of element with mutiple namespace declarations
+	  dtd of element with multiple namespace declarations
 	  (Bug 129821)
 
 Tue Dec 23 11:41:42 HKT 2003 William Brack <wbrack@mmm.com.hk>
@@ -8407,7 +8407,7 @@
 	* doc/examples/*: added his test as the xmlWriter example
 	* doc/html/ doc/*.html: this resulted in some improvements
 	* include/libxml/hash.h: fixed an inclusion problem when
-	  <libxml/hash.h> wasn't preceeded by <xml/parser.h>
+	  <libxml/hash.h> wasn't preceded by <xml/parser.h>
 
 Wed Nov 19 17:19:35 CET 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -8430,7 +8430,7 @@
 Tue Nov 18 21:51:15 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* include/libxml/*.h include/libxml/*.h.in: modified the file
-	  header to add more informations, painful...
+	  header to add more information, painful...
 	* genChRanges.py genUnicode.py: updated to generate said changes
 	  in headers
 	* doc/apibuild.py: extract headers, add them to libxml2-api.xml
@@ -8572,7 +8572,7 @@
 	  added autogeneration of a web page for the examples
 	* doc/examples/example1.c doc/examples/.cvsignore
 	  doc/examples/examples.xml doc/examples/index.py: updated the
-	  informations extracted, improved the format and indexing.
+	  information extracted, improved the format and indexing.
 
 Tue Nov 11 22:08:59 CET 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -8774,7 +8774,7 @@
 	* error.c valid.c include/libxml/xmlerror.h: fixing bug #125653
 	  sometimes the error handlers can get a parser context on DTD
 	  errors, and sometime they don't. So be very careful when trying
-	  to grab those informations.
+	  to grab those information.
 
 Tue Oct 28 15:26:18 CET 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -8884,7 +8884,7 @@
 	* python/tests/Makefile.am python/tests/reader7.py
 	  python/tests/walker.py: adding regression testing for the
 	  new xmlreader APIs, new APIs for reader creation, including
-	  makeing reader "walker" operating on preparsed document trees.
+	  making reader "walker" operating on preparsed document trees.
 
 Sun Oct 20 22:37:03 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
@@ -8947,7 +8947,7 @@
 	* include/libxml/parserInternals.h HTMLparser.c HTMLtree.c
 	  SAX2.c catalog.c debugXML.c entities.c parser.c relaxng.c
 	  testSAX.c tree.c valid.c xmlschemas.c xmlschemastypes.c
-	  xpath.c: Changed all (?) occurences where validation macros
+	  xpath.c: Changed all (?) occurrences where validation macros
 	  (IS_xxx) had single-byte arguments to use IS_xxx_CH instead
 	  (e.g. IS_BLANK changed to IS_BLANK_CH).  This gets rid of
 	  many warning messages on certain platforms, and also high-
@@ -8972,7 +8972,7 @@
 	  a new source, like the xmlReadxx and xmlCtxtReadxxx
 	* win32/libxml2.def.src doc/libxml2-api.xml doc/apibuild.py
 	  doc/Makefile.am: regenerated the APIs
-	* doc/xml.html: applied a patch from Stefan Kost for namesapce docs
+	* doc/xml.html: applied a patch from Stefan Kost for namespace docs
 
 Sat Oct 18 12:46:02 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
@@ -9084,7 +9084,7 @@
 Fri Oct 10 16:19:17 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* include/libxml/tree.h: make room in Doc, Element, Attributes
-	  for PSVI type informations.
+	  for PSVI type information.
 
 Fri Oct 10 16:08:02 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -9179,7 +9179,7 @@
 	  on Windows from Jesse Pelton
 	* parser.c: tiny safety patch for xmlStrPrintf() make sure the
 	  return is always zero terminated. Should also help detecting
-	  passing wrong buffer size easilly.
+	  passing wrong buffer size easily.
 	* result/VC/* result/valid/rss.xml.err result/valid/xlink.xml.err:
 	  updated the results to follow the errors string generated by
 	  last commit.
@@ -9192,7 +9192,7 @@
 Tue Oct  7 13:30:39 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
 	* error.c relaxng.c include/libxml/xmlerror.h: switched Relax-NG
-	  module to teh new error reporting. Better default report, adds
+	  module to the new error reporting. Better default report, adds
 	  the element associated if found, context and node are included
 	  in the xmlError
 	* python/tests/reader2.py: the error messages changed.
@@ -9251,7 +9251,7 @@
 	  scrolling to see where thing broke wasn't pleasant
 	* configure.in: some beta4 preparation, but not ready yet
 	* error.c globals.c include/libxml/globals.h include/libxml/xmlerror.h:
-	  new error handling code, last error informations are stored
+	  new error handling code, last error information are stored
 	  in the parsing context or a global variable, new APIs to
 	  handle the xmlErrorPtr type.
 	* parser.c parserInternals.c valid.c : started migrating to the
@@ -9261,7 +9261,7 @@
 	* parser.c: small potential buffer access problem in push code
 	  provided by Justin Fletcher
 	* result/*.sax result/VC/PENesting* result/namespaces/*
-	  result/valid/*.err: some error messages were sligthly changed.
+	  result/valid/*.err: some error messages were slightly changed.
 
 Thu Oct  2 13:01:13 2003  Aleksey Sanin  <aleksey@aleksey.com>
 
@@ -9369,7 +9369,7 @@
 	* include/libxml/SAX.h include/libxml/parser.h: move the 
 	  SAXv1 block definitions to parser.h fixes bug #123380
 	* xmlreader.c include/libxml/xmlreader.h: reinstanciate
-	  the attribute and element pool borken 2 commits ago.
+	  the attribute and element pool broken 2 commits ago.
 	  Start playing with an entry point to preserve a subtree.
 	* entities.c: remove a warning.
 
@@ -9436,7 +9436,7 @@
 	  include/libxml/globals.h include/libxml/SAX.h: make sure the
 	  global variables for the default SAX handler are V1 ones to
 	  avoid ABI compat problems.
-	* xmlreader.c: cleanup of uneeded code
+	* xmlreader.c: cleanup of unneeded code
 	* hash.c: fix a comment
 
 Thu Sep 25 14:16:51 CEST 2003 Daniel Veillard <daniel@veillard.com>
@@ -9734,7 +9734,7 @@
 	* dict.c: allow to give -1 for undefined length in lookups
 	* include/libxml/parser.h parser.c parserInternals.c testSAX.c:
 	  first round of work on the new SAX2 interfaces, the API
-	  will change but commiting before changing for historical
+	  will change but committing before changing for historical
 	  reference.
 
 Sat Sep  6 10:55:01 PTD 2003 William Brack <wbrack@mmm.com.hk>
@@ -10091,7 +10091,7 @@
 Wed Aug  6 12:32:11 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
 	* error.c trionan.[ch] testThreads.c python/generator.py:
-	  further small changes to elminate most of the remaining
+	  further small changes to eliminate most of the remaining
 	  warnings.
 
 Tue Aug  5 23:51:21 HKT 2003 William Brack <wbrack@mmm.com.hk>
@@ -10130,7 +10130,7 @@
 	* valid.c: fixed another problem with namespaces on element
 	  in mixed content case
 	* python/tests/reader2.py: updated the testcase with 
-	  Bjorn Reese fix to reader for unsignificant white space
+	  Bjorn Reese fix to reader for insignificant white space
 	* parser.c HTMLparser.c: cleanup.
 
 Sun Aug  3 20:55:40 EDT 2003 Daniel Veillard <daniel@veillard.com>
@@ -10151,7 +10151,7 @@
 Fri Aug 1 23:55:23 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
 	Coninuing work on bug 118559
-	* DOCBparser.c: removed 2 unsed vars
+	* DOCBparser.c: removed 2 unused vars
 	* xmlregexp.c: changed some numeric const to their enum symbols
 	* xmlreader.c: changed one var define from int to enum
 	  (a little more to be done, awaiting co-ordination)
@@ -10318,7 +10318,7 @@
 
 Tue Jul  8 16:02:19 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
-	* globals.c threads.c: fixes some problem when freeing unititialized
+	* globals.c threads.c: fixes some problem when freeing uninitialized
 	  mutexes
 
 Tue Jul  8 14:15:07 CEST 2003 Daniel Veillard <daniel@veillard.com>
@@ -10373,7 +10373,7 @@
 Sat Jul 5 00:51:30 HKT 2003 William Brack <wbrack@mmm.com.hk>
 
 	Fixed problem with multi-threading, shown by the test program
-	testThreads.  After fix, ran mutiple tests on various speed
+	testThreads.  After fix, ran multiple tests on various speed
 	machines (single and dual processor X86), which all seem okay.
 
 	* catalog.c: added missing xmlRMutexUnlock in xmlLoadCatalog
@@ -10424,7 +10424,7 @@
 
 	* doc/Makefile.am doc/html/*: reverted back patch for #113521,
 	  due to #115104 and while fixing #115101 . HTML URLs must not
-	  be version dependant.
+	  be version dependent.
 
 Fri Jun 13 12:03:30 CEST 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -10451,7 +10451,7 @@
 
 Mon Jun  2 21:56:15 MVT 2003 Daniel Veillard <daniel@veillard.com>
 
-	* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: commiting
+	* relaxng.c xmlschemas.c include/libxml/schemasInternals.h: committing
 	  some work done while in the Maldives (hence the timezone on the
 	  laptop !)
 	* result/schemas/length3* test/schemas/deter0_*
@@ -10627,7 +10627,7 @@
 
 	* python/generator.py: fixed a problem in the generator where
 	  the way functions are remapped as methods on classes was
-	  not symetric and dependant on python internal hash order,
+	  not symmetric and dependent on python internal hash order,
 	  as reported by Stéphane Bidoul
 
 Fri Apr 25 21:52:33 MDT 2003 John Fleck <jfleck@inkstain.net>
@@ -11162,7 +11162,7 @@
 Mon Mar 17 16:34:07 CET 2003 Daniel Veillard <daniel@veillard.com>
 
 	* relaxng.c: fixed the last core RelaxNG bug known #107083,
-	  shemas datatype ID/IDREF support still missing though.
+	  schemas datatype ID/IDREF support still missing though.
 	* xmlreader.c: fix a crashing bug with prefix raised by
 	  Merijn Broeren
 	* test/relaxng/testsuite.xml: augmented the testsuite with
@@ -11398,7 +11398,7 @@
 
 Wed Feb 19 01:17:48 CET 2003 Daniel Veillard <daniel@veillard.com>
 
-	* relaxng.c: guess what ! Relax-NG bugfixing, what a surprize...
+	* relaxng.c: guess what ! Relax-NG bugfixing, what a surprise...
 
 Tue Feb 18 22:09:50 CET 2003 Daniel Veillard <daniel@veillard.com>
 
@@ -11882,7 +11882,7 @@
 
 Fri Jan 10 00:16:49 CET 2003 Daniel Veillard <daniel@veillard.com>
 
-	* parser.c: one more IsEmptyElement crazyness, that time in
+	* parser.c: one more IsEmptyElement craziness, that time in
 	  external parsed entities if substitution is asked.
 	* python/tests/reader3.py: added a specific test.
 
@@ -11929,10 +11929,10 @@
 
 	* configure.in NEWS: preparing 2.5.0 release
 	* SAX.c: only warn in pedantic mode about namespace name 
-	  brokeness
+	  brokenness
 	* globals.c: fix a doc generation problem
 	* uri.c: fix #101520
-	* doc/*: updated and rebuilt the doc for the release, includuding
+	* doc/*: updated and rebuilt the doc for the release, including
 	  stylesheet update
 	* python/Makefile.am: fix a filename bug
 
@@ -12092,7 +12092,7 @@
 Sat Dec 28 23:49:12 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* xmlreader.c include/libxml/xmlreader.h doc/libxml2-api.xml:
-	  extended the XmlTextReader API a bit, addding accessors for
+	  extended the XmlTextReader API a bit, adding accessors for
 	  the current doc and node, and an entity substitution mode for
 	  the parser.
 	* python/libxml.py python/libxml2class.txt: related updates
@@ -12145,7 +12145,7 @@
 Mon Dec 23 16:54:22 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* xmlreader.c: Fixed the empty node detection to avoid reporting
-	  an inexistant close tag.
+	  an nonexistent close tag.
 
 Mon Dec 23 15:42:24 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -12479,10 +12479,10 @@
 
 Sat Nov 16 16:30:25 CET 2002 Daniel Veillard <daniel@veillard.com>
 
-	* parser.c xpath.c: fixing #96925 wich was also dependent on the
+	* parser.c xpath.c: fixing #96925 which was also dependent on the
 	  processing of parsed entities, and XPath computation on sustitued
 	  entities.
-	* testXPath.c: make sure entities are substitued.
+	* testXPath.c: make sure entities are substituted.
 
 Fri Nov 15 16:22:54 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -12673,7 +12673,7 @@
 Mon Oct 21 09:57:10 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c: tried to fix bug #91500 where doc->children may
-	  be overriden by a call to xmlParseBalancedChunkMemory()
+	  be overridden by a call to xmlParseBalancedChunkMemory()
 
 Mon Oct 21 09:04:32 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -12715,7 +12715,7 @@
 
 Tue Oct 15 12:41:01 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
-	* README: updated the contact informations
+	* README: updated the contact information
 
 Tue Oct 15 10:35:57 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -12800,7 +12800,7 @@
 
 	* configure.in include/libxml/xmlwin32version.h: preparing release
 	  of 2.4.25
-	* doc/*: updated and regenerated teh docs and web pages.
+	* doc/*: updated and regenerated the docs and web pages.
 
 Thu Sep 26 17:33:46 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -13009,7 +13009,7 @@
 
 Thu Sep  5 12:57:38 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
-	* valid.c: try to provide file and line informations, not all
+	* valid.c: try to provide file and line information, not all
 	  messages are covered, but it's a (good) start
 
 Thu Sep  5 12:49:35 CEST 2002 Daniel Veillard <daniel@veillard.com>
@@ -13026,7 +13026,7 @@
 
 Wed Sep  4 14:13:34 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
-	* libxml.spec.in: fixes libary path for x86_64 AMD
+	* libxml.spec.in: fixes library path for x86_64 AMD
 
 Tue Sep  3 21:14:19 MDT 2002 John Fleck <jfleck@inkstain.net>
 
@@ -13060,7 +13060,7 @@
 
 Sun Aug 25 16:38:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
-	* xmlIO.c: handle Windows sepecific file://localhost/ semantic ...
+	* xmlIO.c: handle Windows specific file://localhost/ semantic ...
 
 Thu Aug 22 22:03:19 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -13085,7 +13085,7 @@
 Thu Aug 22 11:45:50 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* python/Makefile.am: typo in target name resulted in libxml2.py
-	  to not be rebuilt. fixed DESTDIR similary to the libxslt one.
+	  to not be rebuilt. fixed DESTDIR similarly to the libxslt one.
 
 Thu Aug 22 09:15:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -13394,7 +13394,7 @@
 
 	* tree.h: added xmlDocFormatDump which is just as xmlDocDump
 	  but with the format parameter
-	* tree.c: made xmlDocDump a wrapper arround xmlDocFormatDump
+	* tree.c: made xmlDocDump a wrapper around xmlDocFormatDump
 
 Fri May 31 12:16:48 2002  Aleksey Sanin  <aleksey@aleksey.com>
 
@@ -13499,13 +13499,13 @@
 
 Tue May 14 13:00:48 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
-	* xpath.c: fixing an XPath function evalutation bug pointed out
+	* xpath.c: fixing an XPath function evaluation bug pointed out
 	  by Alexey Efimov where the context was lost when evaluating
 	  the function arguments
 
 Mon 13 May 2002 11:37:39 PM PDT Aleksey Sanin <aleksey@aleksey.com>
 
-	* xpath.c include/libxml/xpathInternals.h: maked xmlXPathNodeSetAddNs() 
+	* xpath.c include/libxml/xpathInternals.h: made xmlXPathNodeSetAddNs() 
 	  function public for XMLSec performance optimizations
 
 Mon May 13 12:32:22 CEST 2002 Daniel Veillard <daniel@veillard.com>
@@ -13542,7 +13542,7 @@
 	* include/libxml/xmlIO.h win32/dsp/libxml2.def.src
 	win32/libxml2.def.src xmlIO.c: exported default
 	'file:', 'http:' and 'ftp:' protocols input handlers 
-	and maked protocols comparisson case insensitive
+	and made protocols comparison case insensitive
 
 Tue Apr 30 16:29:05 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -13999,7 +13999,7 @@
 Sun Mar 10 17:47:58 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* valid.c: applied patch from Dodji Seketeli fixing an
-	  uninitailized variable in xmlValidGetValidElements()
+	  uninitialized variable in xmlValidGetValidElements()
 
 Sat Mar  9 15:10:49 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14044,7 +14044,7 @@
 Thu Mar  7 12:19:36 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* configure.in xmllint.c: trying to fix #71457 for timing
-	  precision when gettimeofday() is not availble but ftime() is
+	  precision when gettimeofday() is not available but ftime() is
 
 Thu Mar  7 11:24:02 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14139,12 +14139,12 @@
 
 Fri Mar  1 13:56:12 CET 2002 Daniel Veillard <daniel@veillard.com>
 
-	* python/*: commiting some Python bindings work done while travelling
+	* python/*: committing some Python bindings work done while travelling
 
 Fri Mar  1 10:11:15 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* xmllint.c: close #72663 and #72658, don't memdump unless compiled
-	  explicitely with memory debugging switched on
+	  explicitly with memory debugging switched on
 
 Sat Feb 23 11:08:09 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14208,7 +14208,7 @@
 	  when a document is standalone seems correctly handled. There
 	  is a couple of open issues left which need consideration especially
 	  PE93 on external unparsed entities and standalone status. 
-	  Ran 1819 tests: 1817 suceeded, 2 failed and 0 generated an error in 8.26 s.
+	  Ran 1819 tests: 1817 succeeded, 2 failed and 0 generated an error in 8.26 s.
 	  The 2 tests left failing are actually in error. Cleanup done.
 
 Tue Feb 19 15:17:02 CET 2002 Daniel Veillard <daniel@veillard.com>
@@ -14225,7 +14225,7 @@
 
 	* parser.c valid.c: a couple of errors were reported but not
 	  saved back as such in the parsing context. Down to 1% failure rate
-	  Ran 1819 tests: 1801 suceeded, 18 failed and 0 generated an error
+	  Ran 1819 tests: 1801 succeeded, 18 failed and 0 generated an error
 
 Mon Feb 18 20:16:15 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14266,7 +14266,7 @@
 	* check-xml-test-suite.py: improved the behaviour a bit as
 	  well as the logs
 	* parser.c valid.c SAX.c: fixed a few more bugs 
-	  "Ran 1819 tests: 1778 suceeded, 41 failed, and 0 generated an error"
+	  "Ran 1819 tests: 1778 succeeded, 41 failed, and 0 generated an error"
 
 Sun Feb 17 20:41:37 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14453,7 +14453,7 @@
 	  context, allow to switch on and check validity
 	* python/tests/Makefile.am python/tests/error.py
 	  python/tests/invalid.xml python/tests/valid.xml
-	  python/tests/validate.py: attded more test and and added error.py
+	  python/tests/validate.py: added more test and added error.py
 	  which I forgot to commit in the last step
 
 Sun Feb  3 16:03:55 CET 2002 Daniel Veillard <daniel@veillard.com>
@@ -14496,7 +14496,7 @@
 Sat Feb  2 10:13:52 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* configure.in libxml.spec.in python/Makefile.am python/TODO
-	  python/generator.py python/libxml2class.txt: added more informations
+	  python/generator.py python/libxml2class.txt: added more information
 	  in the libxml2-python package including docs. Slightly changed
 	  the class hierarchy
 	* python/tests/*: added basic regression tests infrastructure too
@@ -14543,7 +14543,7 @@
 Wed Jan 30 17:35:33 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* python/generator.py python/libxml.c python/libxml.py
-	  python/libxml_wrap.h: commited early version of a python binding
+	  python/libxml_wrap.h: committed early version of a python binding
 	  for private use only ATM
 
 Sat Jan 26 22:41:13 CET 2002 Daniel Veillard <daniel@veillard.com>
@@ -14576,7 +14576,7 @@
 Wed Jan 23 15:14:22 CET 2002 Daniel Veillard <daniel@veillard.com>
 
 	* parserInternals.h: Greg Sjaardema suggested to use an
-	  eponential buffer groth policy in xmlParserAddNodeInfo()
+	  exponential buffer growth policy in xmlParserAddNodeInfo()
 
 Wed Jan 23 13:32:40 CET 2002 Daniel Veillard <daniel@veillard.com>
 
@@ -14660,7 +14660,7 @@
 
 Fri Jan 18 17:22:50 CET 2002 Daniel Veillard <daniel@veillard.com>
 
-	* globals.c xmlIO.c xmlcatalog.c: removed the last occurences
+	* globals.c xmlIO.c xmlcatalog.c: removed the last occurrences
 	  of strdup usage in the code
 
 Fri Jan 18 12:47:15 CET 2002 Daniel Veillard <daniel@veillard.com>
@@ -15441,7 +15441,7 @@
 Wed Sep 19 10:01:37 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 	* Makefile.am libxml.spec.in: backing up non-documented changes
-	  commited without review or aproval by Jens Finke <jens@gnome.org>
+	  committed without review or approval by Jens Finke <jens@gnome.org>
 	* HACKING: made 100% clear that no commit should be done directly
 
 Mon Sep 17 18:52:37 CEST 2001 Daniel Veillard <daniel@veillard.com>
@@ -15488,7 +15488,7 @@
 Tue Sep 11 11:25:36 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 	* parser.c result/noent/wml.xml: fixed bug #59981 related
-	  to handling of '&' in attributes when entities are substitued
+	  to handling of '&' in attributes when entities are substituted
 
 Mon Sep 10 22:14:42 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
@@ -15586,7 +15586,7 @@
 Thu Aug 23 23:16:32 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
 	* catalog.c xmlIO.c: started some serious testing and fixed
-	  a few bug and optmization needs.
+	  a few bug and optimization needs.
 
 Thu Aug 23 17:26:58 CEST 2001 Daniel Veillard <daniel@veillard.com>
 
@@ -15874,7 +15874,7 @@
 	  this slightly
 	* include/libxml/parser.h SAX.c parser.c parserInternals.c
 	  xmllint.c: make element content line number generation
-	  optionnal to avoid breaking old apps added interface to switch
+	  optional to avoid breaking old apps added interface to switch
 
 Tue Jul 24 15:06:58 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -16120,7 +16120,7 @@
 
 	* configure.in doc/xml.html include/libxml/xmlwin32version.h:
 	  release of 2.3.12
-	* parser.c: make an error message if unknow entities in all cases
+	* parser.c: make an error message if unknown entities in all cases
 
 Tue Jun 26 09:46:29 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -16543,7 +16543,7 @@
 
 Sat May 19 17:11:15 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
-	* doc/xml.html: update with 2.3.9 informations
+	* doc/xml.html: update with 2.3.9 information
 
 Sat May 19 16:50:47 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -16738,7 +16738,7 @@
 Sat Apr 28 16:33:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* xpath.c: simple and efficient optimization, XPath functions
-	  aways bind to the same code, cache this
+	  always bind to the same code, cache this
 	* TODO: updated (by saying some is obsolete)
 
 Sat Apr 28 14:23:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
@@ -16943,7 +16943,7 @@
 Wed Apr 18 15:06:30 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* debugXML.c hash.c tree.h valid.c : some changes related to
-	  the validation suport to improve speed with DocBook
+	  the validation support to improve speed with DocBook
 	* result/VC/OneID2 result/VC/OneID3 : this slightly changes
 	  the way validation errors get reported
 
@@ -16977,7 +16977,7 @@
 Wed Apr 11 16:37:50 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* tree.h: include xmlmemory.h this seems to havoid a nasty glibc
-	  bug where the linktime verions of free() won't work ...
+	  bug where the linktime versions of free() won't work ...
 
 Wed Apr 11 14:21:31 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -17003,7 +17003,7 @@
 	* xpath.c: trying to get 52979 solved
 	* tree.c result/ result/noent/: trying to get 52712 solved, this
 	  also made me clean up the fact that XML output in general should
-	  not add formating blanks by default, this changed the output of
+	  not add formatting blanks by default, this changed the output of
 	  a few tests
 
 Tue Apr 10 16:30:20 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
@@ -17219,7 +17219,7 @@
 
 	* parser.c SAX.c: the new content parsing code raised an
 	  ugly bug in the characters() SAX callback. Found it
-	  just because of strangeness in XSLT XML Rec ouptut :-(
+	  just because of strangeness in XSLT XML Rec output :-(
 
 Wed Mar  7 16:50:22 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -17376,7 +17376,7 @@
 Wed Feb 14 11:35:39 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* hash.[ch]: added Paolo Casarini patch to provide Delete from
-	  hash functionnalities.
+	  hash functionalities.
 	* doc/html/* : rebuild the doc
 
 Tue Feb 13 18:01:48 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
@@ -17514,7 +17514,7 @@
 
 Wed Jan 24 20:27:28 COT 2001 Alejandro Forero <bachue@bachue.com>
 
-	* xmlIO.c (xmlFileOpen, xmlFileOpenW): Removed unnecesary checks.
+	* xmlIO.c (xmlFileOpen, xmlFileOpenW): Removed unnecessary checks.
 
 	* xmlIO.c (xmlCheckFilename): Function added to know whether a given
 	  filename points to a valid file (not a directory).
@@ -17541,17 +17541,17 @@
 
 Mon Jan 22 11:43:21 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
-	* xpath.c: when copying a XSLT tree object teh tree need to be copied
+	* xpath.c: when copying a XSLT tree object the tree need to be copied
 	  too, and deallocation need to occur the same way.
 
 Mon Jan 22 10:35:40 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
 	* xpathInternals.h xpath.[ch] debugXML.c: added the XPATH_XSLT_TREE
-	  type correponding to an XSLT result tree fragment. Share most
+	  type corresponding to an XSLT result tree fragment. Share most
 	  of the data format with node set, as well as operators.
 	* HTMLtree.c: added a newline at the end of the doctype output
 	  whe this one is not present initially.
-	* tree.c: make sure taht the parent and doc pointers are properly
+	* tree.c: make sure that the parent and doc pointers are properly
 	  set when copying attributes (lists).
 
 Sun Jan 21 10:47:38 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
@@ -17613,7 +17613,7 @@
 
 Sat Jan  6 19:13:27 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
-	* Makefile.am: applied patch fro make check from Martin Vidner
+	* Makefile.am: applied patch for make check from Martin Vidner
 
 Thu Jan  4 19:07:49 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
 
@@ -17667,7 +17667,7 @@
 	  of xmllint too when using --memory flag, added a memory test
 	  suite at the Makefile level.
 	* xpathInternals.h xpath.[ch] xpointer.c: fixed problems
-	  with namespace use when encountering QNames in XPath evalation,
+	  with namespace use when encountering QNames in XPath evaluation,
 	  added xmlns() scheme in XPointer.
 	* nanoftp.c : incorporated a fix
 	* parser.c xmlIO.c: fixed problems raised with encoding when using
@@ -17892,7 +17892,7 @@
 	* valid.c: handling of blank nodes in DTd validation (raised
 	  by problems with a posteriori validation).
 	* nanohttp.c: changing behaviour on HTTP write stuff.
-	* HTMLtree.c: forced body and html to be explicitely closed.
+	* HTMLtree.c: forced body and html to be explicitly closed.
 	* xpath.h: exported more XPath functions.
 
 Sun Oct 15 22:28:32 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
@@ -17904,7 +17904,7 @@
 Sun Oct 15 16:21:27 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* SAX.c: HTML attributes need normalization too (Bjorn Reese)
-	* HTMLparser.[ch]: addded htmlIsScriptAttribute()
+	* HTMLparser.[ch]: added htmlIsScriptAttribute()
 
 Sun Oct 15 13:18:36 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
@@ -18010,7 +18010,7 @@
 	* include/Makefile.am include/win32config.h: new directory
 	  for includes
 	* win32/Makefile.mingw win32/README.MSDev win32/libxml2/libxml2.dsp
-	  updated teh makefiles and instructions for WIN32
+	  updated the makefiles and instructions for WIN32
 	* xpath.c: small fixes
 	* test/XPath/ results/XPath: updated the testcases and results
 	* HTMLparser.c nanohttp.c testXPath.c: incorporated provided or
@@ -18037,7 +18037,7 @@
 
 Thu Oct  5 18:13:15 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
 
-	* debugXML.c testXPath.c xpath.[ch]: got pissed by some nastyness
+	* debugXML.c testXPath.c xpath.[ch]: got pissed by some nastiness
 	  in the XPath engine, rewrote large parts of it, now it's far
 	  cleaner and in sync with the REC not an old WD. Fixed a parsing
 	  problem in the interactive XML shell found when testing XPath.
@@ -18255,7 +18255,7 @@
 	  patches from Wayne Davison <wayned@users.sourceforge.net>,
 	  adding htmlEncodeEntities()
 	* HTMLparser.c: fixed an ignorable white space detection bug
-	  occuring when parsing with SAX only
+	  occurring when parsing with SAX only
 	* result/HTML/*.sax: updated since the output is now HTML
 	  encoded...
 
@@ -18420,7 +18420,7 @@
 	  when using Sun Pro cc compiler
 	* xpath.c : cleanup memleaks
 	* nanoftp.c : added a TESTING preprocessor flag for standalong
-	  compile so that people can report bugs more easilly
+	  compile so that people can report bugs more easily
 	* nanohttp.c : ditched socklen_t which was a portability mess
 	  and replaced it with unsigned int.
 	* tree.[ch]: added xmlHasProp()
@@ -18594,7 +18594,7 @@
 	  Makefile.am : added compile-time customization of libxml
 	  --with-ftp --with-http --with-html --with-xpath --with-debug
 	  --with-mem-debug
-	* *.[ch] autoconf.sh : moved to an absolute adressing of includes : 
+	* *.[ch] autoconf.sh : moved to an absolute addressing of includes : 
 	  #include <libxml/xxx.h> I hope it won't break too much stuff
 	  and will be manageable in the future...
 	* xmllint.c Makefile.am libxml.spec.in : renamed tester.c to xmllint.c
@@ -18625,7 +18625,7 @@
 	  libxml default allocation function with another set (like gmalloc/
 	  gfree).
 	* Makefile.am, uri.c, uri.h: added a set of functions to do
-	  exact (litteraly copied from the RFC 2396 productions) parsing
+	  exact (literally copied from the RFC 2396 productions) parsing
 	  and handling of URI. Will be needed for XLink, one XML WFC, 
 	  XML Base and reused in the nano[ftp/http] modules. Still work
 	  to be done.
@@ -18688,7 +18688,7 @@
 
 	* nanoftp.c nanohttp.c tree.c HTMLtree.[ch] debugXML.c xpath.c: Fixed
 	  compilation warnings on various platforms.
-	* parser.c: Fixed #5281 validity error callbacks are now desactived
+	* parser.c: Fixed #5281 validity error callbacks are now deactivated
 	  by default if not validating.
 
 Thu Feb  3 13:46:14 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
@@ -18895,7 +18895,7 @@
 	* result/HTML/*.htm*: Updated the HTML examples regression tests output
 	* SAX.c tree.c: fixed bug on defaulting namespaces on attributes
 	* debugXML.c: fixed a bug on printing default namespaces.
-	* HTMLtree.c: fixed a problem when outputing XML parsed docs as HTML
+	* HTMLtree.c: fixed a problem when outputting XML parsed docs as HTML
 
 Mon Dec 20 16:20:55 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
 
@@ -18922,7 +18922,7 @@
 Thu Dec 16 16:19:29 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* tree.c: fixed a bug introduced in 1.8.0 and breaking default
-	  namespace recognition, and Dia as a resul :-(
+	  namespace recognition, and Dia as a result :-(
 	* encoding.c: closed bug #3950
 
 Wed Dec 15 19:22:23 CET 1999 Daniel Veillard <Daniel.Veillard@w3.org>
@@ -18952,7 +18952,7 @@
 	  buffers instead, this was really needed, validation was breaking
 	  in strange ways due to that. Added xmlParseStringPEReference()
 	  and other parsing from strings functions. Entities processing
-	  modified again, but PERef are still not handled correcly but
+	  modified again, but PERef are still not handled correctly but
 	  unless you're Eve Maller you won't notice :-)
 	* HTMLparser.c: large changes toward reliability, and switched to
 	  lowercase internal tags, XHTML is lowercase, so it will help
@@ -19042,8 +19042,8 @@
 	            a new release out
 	* HTMLparser.c: fixed auto-close bugs on list items, zeroing
 	            some structures, comments before and after the
-		    main element, and other nastyness
-	* HTMLtree.c tree.c: accomodate the extended HTML supported	    
+		    main element, and other nastiness
+	* HTMLtree.c tree.c: accommodate the extended HTML supported	    
 	* configure.in: pushing 1.7.4
 	* test/ent8 and related outputs : added a new test for bug #2784
 	* test/HTML/wired.html and related output: a nasty HTML example
@@ -19125,7 +19125,7 @@
 
 	* parser.h: modified the parser context struct to regain 1.4.0
 	            binary compatibility
-	* parser.c, xml-error.h: added errno ot teh context and defined
+	* parser.c, xml-error.h: added errno to the context and defined
 	            a set of errors values with update of errno
 	* nanohttp.[ch]: minimalist HTTP front-end for fetching remote
 	            DTDs and entities
@@ -19450,7 +19450,7 @@
 
 	* valid.[ch], tree.c, parser.c : more work toward full parsing
 	  of XML DTDs.
-	* README: added informations about mailing-list and on-line
+	* README: added information about mailing-list and on-line
 	  documentation
 
 1999-01-27  Raja R Harinath  <harinath@cs.umn.edu>
@@ -19535,7 +19535,7 @@
 
 Wed Oct 28 17:56:35 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
-	* tree.[ch]: more cleanup on the API, made the tree mor conformant.
+	* tree.[ch]: more cleanup on the API, made the tree more conformant.
 
 Tue Oct 27 17:54:00 EST 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
@@ -19562,7 +19562,7 @@
 
 Sat Oct 24 14:23:51 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
-	* parser.c: Set up the fonctions comment block, boring but useful.
+	* parser.c: Set up the functions comment block, boring but useful.
 	* parser.h, SAX.c, parser.c: now attributes are processed through
 	  the SAX interface. The problem is that my SAX interface diverged
 	  quite a bit from the original one, well this is not an official
@@ -19571,7 +19571,7 @@
 Tue Oct 20 02:11:21 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* SAX.c, entities.c, tree.c, encoding.c, error.c: Set up the
-	  fonctions comment block, boring but useful.
+	  functions comment block, boring but useful.
 
 Sun Oct 18 20:40:58 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
@@ -19594,7 +19594,7 @@
 Tue Oct 13 21:46:57 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* tree.h, tree.c, parser.c: added prev and doc pointers to Node,
-	  and changed NODEs contants for conformity with DOM Level 1
+	  and changed NODEs constants for conformity with DOM Level 1
 
 Wed Oct  7 23:42:46 EDT 1998 Daniel Veillard <Daniel.Veillard@w3.org>
 
@@ -19631,7 +19631,7 @@
 
 1998-08-20  Raja R Harinath  <harinath@cs.umn.edu>
 
-	* error.h: New file.  Contains prototyes from `error.c'.
+	* error.h: New file.  Contains prototypes from `error.c'.
 
 Thu Aug 13 19:02:34 1998  Tom Tromey  <tromey@cygnus.com>
 
@@ -19662,13 +19662,13 @@
 Sun Jul 26 00:17:51 EDT 1998  Daniel Veillard <Daniel.Veillard@w3.org>
 
 	* configure.in: added test for CPP
-	* AUTHORS, Changelog: the original ones didn't get commited but the
+	* AUTHORS, Changelog: the original ones didn't get committed but the
 	    glib ones instead, fixed.
 	* Makefile.am: corrected an error in library naming
 
 Fri Jul 24 16:47:14 1998  Daniel Veillard <Daniel.Veillard@w3.org>
 
-	* integrated code developped at W3C
+	* integrated code developed at W3C
 	* changed the original Copyright
 	* migrated to automake
 	* prefixed the filenames by xml_ to avoid filename clashes
diff --git a/src/HTMLparser.c b/src/HTMLparser.c
index 9e60e27..5dd62df 100644
--- a/src/HTMLparser.c
+++ b/src/HTMLparser.c
@@ -69,7 +69,7 @@
 /**
  * htmlErrMemory:
  * @ctxt:  an HTML parser context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a redefinition of attribute error
  */
@@ -317,7 +317,7 @@
 
 #define SKIP_BLANKS htmlSkipBlankChars(ctxt)
 
-/* Inported from XML */
+/* Imported from XML */
 
 /* #define CUR (ctxt->token ? ctxt->token : (int) (*ctxt->input->cur)) */
 #define CUR ((int) (*ctxt->input->cur))
@@ -537,7 +537,7 @@
 encoding_error:
     /*
      * If we detect an UTF8 error that probably mean that the
-     * input encoding didn't get properly advertized in the
+     * input encoding didn't get properly advertised in the
      * declaration header. Report the error and switch the encoding
      * to ISO-Latin-1 (if you don't like this policy, just declare the
      * encoding !)
@@ -602,8 +602,8 @@
  ************************************************************************/
 
 /*
- *  Start Tag: 1 means the start tag can be ommited
- *  End Tag:   1 means the end tag can be ommited
+ *  Start Tag: 1 means the start tag can be omitted
+ *  End Tag:   1 means the end tag can be omitted
  *             2 means it's forbidden (empty elements)
  *             3 means the tag is stylistic and should be closed easily
  *  Depr:      this element is deprecated
@@ -1342,7 +1342,7 @@
         if (xmlStrEqual(newtag, ctxt->nameTab[i]))
             break;
         /*
-         * A missplaced endtag can only close elements with lower
+         * A misplaced endtag can only close elements with lower
          * or equal priority, so if we find an element with higher
          * priority before we find an element with
          * matching name, we just ignore this endtag
@@ -2176,6 +2176,7 @@
  *									*
  ************************************************************************/
 
+#ifdef LIBXML_PUSH_ENABLED
 /**
  * htmlNewInputStream:
  * @ctxt:  an HTML parser context
@@ -2207,6 +2208,7 @@
     input->length = 0;
     return(input);
 }
+#endif
 
 
 /************************************************************************
@@ -2216,9 +2218,9 @@
  ************************************************************************/
 /*
  * all tags allowing pc data from the html 4.01 loose dtd
- * NOTE: it might be more apropriate to integrate this information
+ * NOTE: it might be more appropriate to integrate this information
  * into the html40ElementTable array but I don't want to risk any
- * binary incomptibility
+ * binary incompatibility
  */
 static const char *allowPCData[] = {
     "a", "abbr", "acronym", "address", "applet", "b", "bdo", "big",
@@ -2959,6 +2961,7 @@
 	}
 	COPY_BUF(l,buf,nbchar,cur);
 	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
+            buf[nbchar] = 0;
 	    if (ctxt->sax->cdataBlock!= NULL) {
 		/*
 		 * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
@@ -2983,6 +2986,7 @@
     }
 
     if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
+        buf[nbchar] = 0;
 	if (ctxt->sax->cdataBlock!= NULL) {
 	    /*
 	     * Insert as CDATA, which is the same as HTML_PRESERVE_NODE
@@ -3028,6 +3032,8 @@
 	    COPY_BUF(l,buf,nbchar,cur);
 	}
 	if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
+            buf[nbchar] = 0;
+
 	    /*
 	     * Ok the segment is to be consumed as chars.
 	     */
@@ -5476,7 +5482,7 @@
 		if (avail < 1)
 		    goto done;
 		/*
-		 * not enouth chars in buffer
+		 * not enough chars in buffer
 		 */
 		if (avail < 2) {
 		    if (!terminate)
@@ -5642,7 +5648,7 @@
 		if (avail < 1)
 		    goto done;
 		/*
-		 * not enouth chars in buffer
+		 * not enough chars in buffer
 		 */
 		if (avail < 2) {
 		    if (!terminate)
@@ -5762,13 +5768,13 @@
                 break;
 	    }
             case XML_PARSER_CONTENT: {
+		xmlChar chr[2] = { 0, 0 };
 		long cons;
+
                 /*
 		 * Handle preparsed entities and charRef
 		 */
 		if (ctxt->token != 0) {
-		    xmlChar chr[2] = { 0 , 0 } ;
-
 		    chr[0] = (xmlChar) ctxt->token;
 		    htmlCheckParagraph(ctxt);
 		    if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL))
@@ -5780,21 +5786,22 @@
 		    cur = in->cur[0];
 		    if ((cur != '<') && (cur != '&')) {
 			if (ctxt->sax != NULL) {
+                            chr[0] = cur;
 			    if (IS_BLANK_CH(cur)) {
 				if (ctxt->keepBlanks) {
 				    if (ctxt->sax->characters != NULL)
 					ctxt->sax->characters(
-						ctxt->userData, &in->cur[0], 1);
+						ctxt->userData, chr, 1);
 				} else {
 				    if (ctxt->sax->ignorableWhitespace != NULL)
 					ctxt->sax->ignorableWhitespace(
-						ctxt->userData, &in->cur[0], 1);
+						ctxt->userData, chr, 1);
 				}
 			    } else {
 				htmlCheckParagraph(ctxt);
 				if (ctxt->sax->characters != NULL)
 				    ctxt->sax->characters(
-					    ctxt->userData, &in->cur[0], 1);
+					    ctxt->userData, chr, 1);
 			    }
 			}
 			ctxt->token = 0;
diff --git a/src/HTMLtree.c b/src/HTMLtree.c
index 21cfcfe..fe5d086 100644
--- a/src/HTMLtree.c
+++ b/src/HTMLtree.c
@@ -226,7 +226,7 @@
 found_meta:
     /*
      * Search and update all the remaining the meta elements carrying
-     * encoding informations
+     * encoding information
      */
     while (cur != NULL) {
 	if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
@@ -345,7 +345,7 @@
  ************************************************************************/
 /**
  * htmlSaveErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -359,7 +359,7 @@
  * htmlSaveErr:
  * @code:  the error number
  * @node:  the location of the error.
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -1048,7 +1048,7 @@
  * @cur:  the document
  * @encoding:  the encoding string
  *
- * Dump an HTML document. Formating return/spaces are added.
+ * Dump an HTML document. Formatting return/spaces are added.
  */
 void
 htmlDocContentDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr cur,
diff --git a/src/Makefile.am b/src/Makefile.am
index 174b984..be1a883 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -915,7 +915,10 @@
 	      if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
 	      rm result.$$name ; \
 	  fi ; fi ; done)
-	@echo "## Formal expresssions regression tests"
+
+# Disabled for now
+Exptests: testRegexp$(EXEEXT)
+	@echo "## Formal expressions regression tests"
 	-@(for i in $(srcdir)/test/expr/* ; do \
 	  name=`basename $$i`; \
 	  if [ ! -d $$i ] ; then \
@@ -1231,6 +1234,7 @@
 	    -e 's?\@XML_INCLUDEDIR\@?$(XML_INCLUDEDIR)?g' \
 	    -e 's?\@VERSION\@?$(VERSION)?g' \
 	    -e 's?\@XML_LIBS\@?$(XML_LIBS)?g' \
+	    -e 's?\@XML_PRIVATE_LIBS\@?$(XML_PRIVATE_LIBS)?g' \
 	       < $(srcdir)/xml2Conf.sh.in > xml2Conf.tmp \
 	&& mv xml2Conf.tmp xml2Conf.sh
 
diff --git a/src/Makefile.tests b/src/Makefile.tests
index 619cbfb..9f08dcf 100644
--- a/src/Makefile.tests
+++ b/src/Makefile.tests
@@ -1,5 +1,5 @@
 #
-# You may have to ajust to call the right compiler, or other oprions
+# You may have to adjust to call the right compiler, or other options
 # for compiling and linking
 #
 
diff --git a/src/NEWS b/src/NEWS
index 5504bed..b55c63b 100644
--- a/src/NEWS
+++ b/src/NEWS
@@ -1398,7 +1398,7 @@
       on Windows (Igor Zlatkovic), htmlCtxtReset fix (Michael Day), XPath
       principal node of axis bug, HTML serialization of some codepoint
       (Steven Rainwater), user data propagation in XInclude (Michael Day),
-      standalone and XML decl detection (Michael Day), Python id ouptut
+      standalone and XML decl detection (Michael Day), Python id output
       for some id, fix the big python string memory leak, URI parsing fixes
       (Stéphane Bidoul and William), long comments parsing bug (William),
       concurrent threads initialization (Ted Phelps), invalid char
@@ -1410,7 +1410,7 @@
       min occurs of 0 (William), HTML script/style parsing (Mike Day)
    - Improvement: make xmlTextReaderSetup() public
    - Compilation and postability: fix a missing include problem (William),
-      __ss_familly on AIX again (Björn Wiberg), compilation without zlib
+      __ss_family on AIX again (Björn Wiberg), compilation without zlib
       (Michael Day), catalog patch for Win32 (Christian Ehrlicher),
       Windows CE fixes (Andreas Stricke)
    - Various CVS to SVN infrastructure changes
@@ -1449,7 +1449,7 @@
       fix attribute serialization in writer (Rob Richards), PHP4 DTD validation
       crasher, parser safety patch (Ben Darnell), _private context propagation
       when parsing entities (with Michael Day), fix entities behaviour when 
-      using SAX, URI to file path fix (Mikhail Zabaluev), disapearing validity
+      using SAX, URI to file path fix (Mikhail Zabaluev), disappearing validity
       context, arg error in SAX callback (Mike Hommey), fix mixed-content
       autodetect when using --noblanks, fix xmlIOParseDTD error handling,
       fix bug in xmlSplitQName on special Names, fix Relax-NG element content
@@ -1533,7 +1533,7 @@
     split problem (William), issues with non-namespaced attributes in
     xmlAddChild() xmlAddNextSibling() and xmlAddPrevSibling() (Rob Richards),
     HTML parsing of script, Python must not output to stdout (Nic Ferrier),
-    exclusive C14N namespace visibility (Aleksey Sanin), XSD dataype
+    exclusive C14N namespace visibility (Aleksey Sanin), XSD datatype
     totalDigits bug (Kasimier Buchcik), error handling when writing to an
     xmlBuffer (Rob Richards), runtest schemas error not reported (Hisashi
     Fujinaka), signed/unsigned problem in date/time code (Albert Chin), fix
@@ -1542,7 +1542,7 @@
     (Gary Coady), regexp bug affecting schemas (Kasimier), configuration of
     runtime debugging (Kasimier), xmlNodeBufGetContent bug on entity refs
     (Oleksandr Kononenko), xmlRegExecPushString2 bug (Sreeni Nair),
-    compilation and build fixes (Michael Day), removed dependancies on
+    compilation and build fixes (Michael Day), removed dependencies on
     xmlSchemaValidError (Kasimier), bug with <xml:foo/>, more XPath
     pattern based evaluation fixes (Kasimier)
    - improvements: XSD Schemas redefinitions/restrictions (Kasimier
@@ -1587,7 +1587,7 @@
     foreign namespaces handling, XML Schemas facet comparison (Kupriyanov
     Anatolij), xmlSchemaPSimpleTypeErr error report (Kasimier Buchcik), xml:
     namespace ahndling in Schemas (Kasimier), empty model group in Schemas
-    (Kasimier), wilcard in Schemas (Kasimier), URI composition (William),
+    (Kasimier), wildcard in Schemas (Kasimier), URI composition (William),
     xs:anyType in Schemas (Kasimier), Python resolver emmitting error
     messages directly, Python xmlAttr.parent (Jakub Piotr Clapa), trying to
     fix the file path/URI conversion, xmlTextReaderGetAttribute fix (Rob
@@ -1761,7 +1761,7 @@
     Buchcik), XInclude testing, Notation serialization, UTF8ToISO8859x
     transcoding (Mark Itzcovitz), lots of XML Schemas cleanup and fixes
     (Kasimier), ChangeLog cleanup (Stepan Kasal), memory fixes (Mark Vakoc),
-    handling of failed realloc(), out of bound array adressing in Schemas
+    handling of failed realloc(), out of bound array addressing in Schemas
     date handling, Python space/tabs cleanups (Malcolm Tredinnick), NMTOKENS
     E20 validation fix (Malcolm),
    - improvements: added W3C XML Schemas testsuite (Kasimier Buchcik), add
@@ -1778,7 +1778,7 @@
     (Kasimier Buchcik), Schemas validation crash, xmlCheckUTF8 (William Brack
     and Julius Mittenzwei), Schemas facet check (Kasimier), default namespace
     problem (William), Schemas hexbinary empty values, encoding error could
-    genrate a serialization loop.
+    generate a serialization loop.
    - Improvements: Schemas validity improvements (Kasimier), added --path
     and --load-trace options to xmllint
    - documentation: tutorial update (John Fleck)
@@ -1936,7 +1936,7 @@
     --with-minimum configuration.
    - XInclude: allow the 2001 namespace without warning.
    - Documentation: missing example/index.html (John Fleck), version
-    dependancies (John Fleck)
+    dependencies (John Fleck)
    - reader API: structured error reporting (Steve Ball)
    - Windows compilation: mingw, msys (Mikhail Grushinskiy), function
     prototype (Cameron Johnson), MSVC6 compiler warnings, _WINSOCKAPI_
@@ -2070,7 +2070,7 @@
     intercepted at a structured level, with precise information
   available.
    - New simpler and more generic XML and HTML parser APIs, allowing to
-    easilly modify the parsing options and reuse parser context for multiple
+    easily modify the parsing options and reuse parser context for multiple
     consecutive documents.
    - Similar new APIs for the xmlReader, for options and reuse, provided new
     functions to access content as const strings, use them for Python
diff --git a/src/README b/src/README
index 749e671..4957517 100644
--- a/src/README
+++ b/src/README
@@ -8,6 +8,7 @@
 
 To build on an Unixised setup:
    ./configure ; make ; make install
+   if the ./configure file does not exist, run ./autogen.sh instead.
 To build on Windows:
    see instructions on win32/Readme.txt
 
@@ -18,7 +19,7 @@
        There is 3 standalone tools runtest.c runsuite.c testapi.c, which
        should compile as part of the build or as any application would.
        Launch them from this directory to get results, runtest checks 
-       the proper functionning of libxml2 main APIs while testapi does
+       the proper functioning of libxml2 main APIs while testapi does
        a full coverage check. Report failures to the list.
 
 To report bugs, follow the instructions at: 
diff --git a/src/README.zOS b/src/README.zOS
index 6b6669a..e6a6d6e 100644
--- a/src/README.zOS
+++ b/src/README.zOS
@@ -7,7 +7,7 @@
 
 - since the name of files (or qualifier) in PDS are limited to 8 I had to
   rename xmlschemas.c and xmlschemastypes.c in (resp.) xmlsche.c xmlschet.c
-  (and I had to modify all occurences of these files accordingly in the
+  (and I had to modify all occurrences of these files accordingly in the
   rest of the Makefile !!!).
 
 - in order to copy objects to PDS, I had the cp command at line 860
diff --git a/src/SAX2.c b/src/SAX2.c
index fee66b7..9df0184 100644
--- a/src/SAX2.c
+++ b/src/SAX2.c
@@ -40,7 +40,7 @@
  * TODO:
  *
  * macro to flag unimplemented blocks
- * XML_CATALOG_PREFER user env to select between system/public prefered
+ * XML_CATALOG_PREFER user env to select between system/public preferred
  * option. C.f. Richard Tobin <richard@cogsci.ed.ac.uk>
  *> Just FYI, I am using an environment variable XML_CATALOG_PREFER with
  *> values "system" and "public".  I have made the default be "system" to
@@ -590,36 +590,6 @@
     } else {
 	ret = xmlGetDocEntity(ctxt->myDoc, name);
     }
-    if ((ret != NULL) &&
-	((ctxt->validate) || (ctxt->replaceEntities)) &&
-	(ret->children == NULL) &&
-	(ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
-	int val;
-
-	/*
-	 * for validation purposes we really need to fetch and
-	 * parse the external entity
-	 */
-	xmlNodePtr children;
-	unsigned long oldnbent = ctxt->nbentities;
-
-        val = xmlParseCtxtExternalEntity(ctxt, ret->URI,
-		                         ret->ExternalID, &children);
-	if (val == 0) {
-	    xmlAddChildList((xmlNodePtr) ret, children);
-	} else {
-	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_PROCESSING,
-		           "Failure to process entity %s\n", name, NULL);
-	    ctxt->validate = 0;
-	    return(NULL);
-	}
-	ret->owner = 1;
-	if (ret->checked == 0) {
-	    ret->checked = (ctxt->nbentities - oldnbent + 1) * 2;
-	    if ((ret->content != NULL) && (xmlStrchr(ret->content, '<')))
-	        ret->checked |= 1;
-	}
-    }
     return(ret);
 }
 
@@ -1512,8 +1482,8 @@
 	attr = elemDecl->attributes;
 	while (attr != NULL) {
 	    /*
-	     * Make sure that attributes redefinition occuring in the
-	     * internal subset are not overriden by definitions in the
+	     * Make sure that attributes redefinition occurring in the
+	     * internal subset are not overridden by definitions in the
 	     * external subset.
 	     */
 	    if (attr->defaultValue != NULL) {
@@ -1736,8 +1706,8 @@
     }
 
     /*
-     * set the namespace node, making sure that if the default namspace
-     * is unbound on a parent we simply kee it NULL
+     * set the namespace node, making sure that if the default namespace
+     * is unbound on a parent we simply keep it NULL
      */
     if ((ns != NULL) && (ns->href != NULL) &&
 	((ns->href[0] != 0) || (ns->prefix != NULL)))
@@ -2012,7 +1982,7 @@
 	else
 	    ret->name = xmlStrdup(localname);
 
-        /* link at the end to preserv order, TODO speed up with a last */
+        /* link at the end to preserve order, TODO speed up with a last */
 	if (ctxt->node->properties == NULL) {
 	    ctxt->node->properties = ret;
 	} else {
@@ -2104,7 +2074,7 @@
 	    } else {
 	        /*
 		 * dup now contains a string of the flattened attribute
-		 * content with entities substitued. Check if we need to
+		 * content with entities substituted. Check if we need to
 		 * apply an extra layer of normalization.
 		 * It need to be done twice ... it's an extra burden related
 		 * to the ability to keep references in attributes
@@ -2137,7 +2107,7 @@
 	    }
 	} else {
 	    /*
-	     * if entities already have been substitued, then
+	     * if entities already have been substituted, then
 	     * the attribute as passed is already normalized
 	     */
 	    dup = xmlStrndup(value, valueend - value);
@@ -2203,7 +2173,7 @@
  *               attribute values.
  *
  * SAX2 callback when an element start has been detected by the parser.
- * It provides the namespace informations for the element, as well as
+ * It provides the namespace information for the element, as well as
  * the new namespace declarations on the element.
  */
 void
@@ -2400,7 +2370,7 @@
     if (nb_attributes > 0) {
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
 	    /*
-	     * Handle the rare case of an undefined atribute prefix
+	     * Handle the rare case of an undefined attribute prefix
 	     */
 	    if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
 		if (ctxt->dictNames) {
@@ -2456,7 +2426,7 @@
  * @URI:  the element namespace name if available
  *
  * SAX2 callback when an element end has been detected by the parser.
- * It provides the namespace informations for the element.
+ * It provides the namespace information for the element.
  */
 void
 xmlSAX2EndElementNs(void *ctx,
@@ -2586,7 +2556,7 @@
 	     * The whole point of maintaining nodelen and nodemem,
 	     * xmlTextConcat is too costly, i.e. compute length,
 	     * reallocate a new buffer, move data, append ch. Here
-	     * We try to minimaze realloc() uses and avoid copying
+	     * We try to minimize realloc() uses and avoid copying
 	     * and recomputing length over and over.
 	     */
 	    if (lastChild->content == (xmlChar *)&(lastChild->properties)) {
diff --git a/src/TODO b/src/TODO
index 9c32224..94d34c8 100644
--- a/src/TODO
+++ b/src/TODO
@@ -202,7 +202,7 @@
   by the XML parser, UTF-8 should be checked when there is no "encoding"
   declared !
 - Support for UTF-8 and UTF-16 encoding
-  => added some convertion routines provided by Martin Durst
+  => added some conversion routines provided by Martin Durst
      patched them, got fixes from @@@
      I plan to keep everything internally as UTF-8 (or ISO-Latin-X)
      this is slightly more costly but more compact, and recent processors
@@ -212,7 +212,7 @@
      is enabled, tested the ISO->UTF-8 stuff
 - External entities loading: 
    - allow override by client code
-   - make sure it is alled for all external entities referenced
+   - make sure it is called for all external entities referenced
   Done, client code should use xmlSetExternalEntityLoader() to set
   the default loading routine. It will be called each time an external
   entity entity resolution is triggered.
@@ -245,8 +245,8 @@
   most cases !
 
 - progressive reading. The entity support is a first step toward
-  asbtraction of an input stream. A large part of the context is still
-  located on the stack, moving to a state machine and putting everyting
+  abstraction of an input stream. A large part of the context is still
+  located on the stack, moving to a state machine and putting everything
   in the parsing context should provide an adequate solution.
   => Rather than progressive parsing, give more power to the SAX-like
      interface. Currently the DOM-like representation is built but
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 6db5ac1..1fc8000 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -296,7 +296,7 @@
 AS_VAR_IF([$1], [""], [$5], [$4])dnl
 ])dnl PKG_CHECK_VAR
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -311,7 +311,7 @@
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.2], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -327,14 +327,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.2])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -386,7 +386,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -417,7 +417,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -608,7 +608,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -647,7 +647,9 @@
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -674,7 +676,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -871,7 +873,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -892,7 +894,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -914,7 +916,7 @@
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -949,7 +951,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -992,7 +994,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1031,7 +1033,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1060,7 +1062,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1107,7 +1109,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1126,7 +1128,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1207,7 +1209,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1267,7 +1269,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1295,7 +1297,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1314,7 +1316,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/src/buf.c b/src/buf.c
index 21cb9d8..8ad18a1 100644
--- a/src/buf.c
+++ b/src/buf.c
@@ -1,7 +1,7 @@
 /*
  * buf.c: memory buffers for libxml2
  *
- * new buffer structures and entry points to simplify the maintainance
+ * new buffer structures and entry points to simplify the maintenance
  * of libxml2 and ensure we keep good control over memory allocations
  * and stay 64 bits clean.
  * The new entry point use the xmlBufPtr opaque structure and
@@ -83,7 +83,7 @@
 
 /**
  * xmlBufMemoryError:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  * To be improved...
@@ -98,7 +98,7 @@
 
 /**
  * xmlBufOverflowError:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a buffer overflow error
  * To be improved...
@@ -396,7 +396,7 @@
         ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
 	/*
 	 * we just move the content pointer, but also make sure
-	 * the perceived buffer size has shrinked accordingly
+	 * the perceived buffer size has shrunk accordingly
 	 */
         buf->content += len;
 	buf->size -= len;
@@ -958,7 +958,7 @@
 
 	if (start_buf > (unsigned int) len) {
 	    /*
-	     * We can add it in the space previously shrinked
+	     * We can add it in the space previously shrunk
 	     */
 	    buf->content -= len;
             memmove(&buf->content[0], str, len);
@@ -1204,10 +1204,10 @@
 xmlBufBackToBuffer(xmlBufPtr buf) {
     xmlBufferPtr ret;
 
-    if ((buf == NULL) || (buf->error))
+    if (buf == NULL)
         return(NULL);
     CHECK_COMPAT(buf)
-    if (buf->buffer == NULL) {
+    if ((buf->error) || (buf->buffer == NULL)) {
         xmlBufFree(buf);
         return(NULL);
     }
@@ -1233,10 +1233,12 @@
          * Keep the buffer but provide a truncated size value.
          */
         xmlBufOverflowError(buf, "Allocated size too big for xmlBuffer");
+        ret->use = (int) buf->use;
         ret->size = INT_MAX;
+    } else {
+        ret->use = (int) buf->use;
+        ret->size = (int) buf->size;
     }
-    ret->use = (int) buf->use;
-    ret->size = (int) buf->size;
     ret->alloc = buf->alloc;
     ret->content = buf->content;
     ret->contentIO = buf->contentIO;
@@ -1307,7 +1309,7 @@
     CHECK_COMPAT(buf)
     base = input->base - buf->content;
     /*
-     * We could do some pointer arythmetic checks but that's probably
+     * We could do some pointer arithmetic checks but that's probably
      * sufficient.
      */
     if (base > buf->size) {
diff --git a/src/check-xinclude-test-suite.py b/src/check-xinclude-test-suite.py
index f470011..416ea21 100755
--- a/src/check-xinclude-test-suite.py
+++ b/src/check-xinclude-test-suite.py
@@ -209,7 +209,7 @@
 	old_test_failed = test_failed
 	old_test_error = test_error
         runTestCases(case)
-	print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
+	print "   Ran %d tests: %d succeeded, %d failed and %d generated an error" % (
 	       test_nr - old_test_nr, test_succeed - old_test_succeed,
 	       test_failed - old_test_failed, test_error - old_test_error)
     case = case.next
@@ -217,5 +217,5 @@
 conf.freeDoc()
 log.close()
 
-print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
+print "Ran %d tests: %d succeeded, %d failed and %d generated an error in %.2f s." % (
       test_nr, test_succeed, test_failed, test_error, time.time() - start)
diff --git a/src/check-xml-test-suite.py b/src/check-xml-test-suite.py
index 2de07b1..399a8db 100755
--- a/src/check-xml-test-suite.py
+++ b/src/check-xml-test-suite.py
@@ -326,7 +326,7 @@
 	#elif extra == 'both' or extra == 'parameter':
 	res = testNotWfEntDtd(URI, id)
 	#else:
-	#    print "Unknow value %s for an ENTITIES test value" % (extra)
+	#    print "Unknown value %s for an ENTITIES test value" % (extra)
 	#    return -1
     elif type == "error":
 	res = testError(URI, id)
@@ -397,7 +397,7 @@
 	old_test_failed = test_failed
 	old_test_error = test_error
         runTestCases(case)
-	print "   Ran %d tests: %d suceeded, %d failed and %d generated an error" % (
+	print "   Ran %d tests: %d succeeded, %d failed and %d generated an error" % (
 	       test_nr - old_test_nr, test_succeed - old_test_succeed,
 	       test_failed - old_test_failed, test_error - old_test_error)
     case = case.next
@@ -405,5 +405,5 @@
 conf.freeDoc()
 log.close()
 
-print "Ran %d tests: %d suceeded, %d failed and %d generated an error in %.2f s." % (
+print "Ran %d tests: %d succeeded, %d failed and %d generated an error in %.2f s." % (
       test_nr, test_succeed, test_failed, test_error, time.time() - start)
diff --git a/src/configure.ac b/src/configure.ac
index 9cae50c..09418af 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -9,7 +9,7 @@
 
 LIBXML_MAJOR_VERSION=2
 LIBXML_MINOR_VERSION=9
-LIBXML_MICRO_VERSION=9
+LIBXML_MICRO_VERSION=10
 LIBXML_MICRO_VERSION_SUFFIX=
 LIBXML_VERSION=$LIBXML_MAJOR_VERSION.$LIBXML_MINOR_VERSION.$LIBXML_MICRO_VERSION$LIBXML_MICRO_VERSION_SUFFIX
 LIBXML_VERSION_INFO=`expr $LIBXML_MAJOR_VERSION + $LIBXML_MINOR_VERSION`:$LIBXML_MICRO_VERSION:$LIBXML_MINOR_VERSION
@@ -217,7 +217,7 @@
 AM_CONDITIONAL([REBUILD_DOCS], [test "$enable_rebuild_docs" = "yes" -o "$USER" = "veillard"])
 
 dnl
-dnl hard dependancies on options
+dnl hard dependencies on options
 dnl
 if test "$with_schemas" = "yes"
 then
@@ -396,7 +396,7 @@
         # Try pkg-config first so that static linking works.
         PKG_CHECK_MODULES([Z],[zlib],
             [WITH_ZLIB=1],
-            [ ])
+            [:])
     fi
 
     if test "$WITH_ZLIB" = "0"; then
@@ -435,7 +435,7 @@
         # Try pkg-config first so that static linking works.
         PKG_CHECK_MODULES([LZMA],[liblzma],
             [WITH_LZMA=1],
-            [ ])
+            [:])
     fi
 
     # If pkg-config failed, fall back to AC_CHECK_LIB. This
@@ -770,8 +770,8 @@
 
     # warnings we'd like to see
     EXTRA_CFLAGS="${EXTRA_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls"
-    # warnings we'd like to supress
-    EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-long-long -Wno-format-extra-args -Wno-array-bounds"
+    # warnings we'd like to suppress
+    EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-long-long -Wno-format-extra-args"
     case "${host}" in
           alpha*-*-linux* )
 	       EXTRA_CFLAGS="${EXTRA_CFLAGS} -mieee"
@@ -1533,7 +1533,8 @@
         WITH_ICU=1
     fi
 fi
-XML_LIBS="-lxml2 $Z_LIBS $LZMA_LIBS $THREAD_LIBS $ICONV_LIBS $ICU_LIBS $M_LIBS $LIBS"
+XML_LIBS="-lxml2"
+XML_PRIVATE_LIBS="$Z_LIBS $LZMA_LIBS $THREAD_LIBS $ICONV_LIBS $ICU_LIBS $M_LIBS $LIBS"
 XML_LIBTOOLLIBS="libxml2.la"
 AC_SUBST(WITH_ICU)
 
@@ -1654,7 +1655,7 @@
 dnl
 dnl Also *win32*config.h files redefine them for various MSC compilers.
 dnl
-dnl So do not redefine {v}snprintf to _{v}snprintf like follwing:
+dnl So do not redefine {v}snprintf to _{v}snprintf like following:
 dnl  AC_DEFINE([snprintf],[_snprintf],[Win32 Std C name mangling work-around])
 dnl  AC_DEFINE([vsnprintf],[_vsnprintf],[Win32 Std C name mangling work-around])
 dnl and do not redefine those functions is C-source files.
@@ -1678,6 +1679,7 @@
 
 AC_SUBST(XML_LIBDIR)
 AC_SUBST(XML_LIBS)
+AC_SUBST(XML_PRIVATE_LIBS)
 AC_SUBST(XML_LIBTOOLLIBS)
 AC_SUBST(ICONV_LIBS)
 AC_SUBST(ICU_LIBS)
diff --git a/src/dict.c b/src/dict.c
index 0ef3718..90e4d81 100644
--- a/src/dict.c
+++ b/src/dict.c
@@ -10,7 +10,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  * Author: daniel@veillard.com
@@ -38,7 +38,8 @@
  *  list we will use the BigKey algo as soon as the hash size grows
  *  over MIN_DICT_SIZE so this actually works
  */
-#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME) && \
+    !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
 #define DICT_RANDOMIZATION
 #endif
 
@@ -371,6 +372,9 @@
  * http://burtleburtle.net/bob/hash/doobs.html
  */
 
+#ifdef __clang__
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
+#endif
 static uint32_t
 xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
     uint32_t hash;
@@ -403,6 +407,9 @@
  *
  * Neither of the two strings must be NULL.
  */
+#ifdef __clang__
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
+#endif
 static unsigned long
 xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
                       const xmlChar *name, int len, int seed)
@@ -445,7 +452,7 @@
     unsigned long value = seed;
 
     if (name == NULL) return(0);
-    value = *name;
+    value += *name;
     value <<= 5;
     if (namelen > 10) {
         value += name[namelen - 1];
@@ -727,7 +734,7 @@
 		dict->dict[key].next = entry;
 	    } else {
 	        /*
-		 * we don't have much ways to alert from herei
+		 * we don't have much ways to alert from here
 		 * result is losing an entry and unicity guarantee
 		 */
 	        ret = -1;
@@ -1202,7 +1209,7 @@
  * @dict: the dictionary
  * @str: the string
  *
- * check if a string is owned by the disctionary
+ * check if a string is owned by the dictionary
  *
  * Returns 1 if true, 0 if false and -1 in case of error
  * -1 in case of error
diff --git a/src/elfgcchack.h b/src/elfgcchack.h
index 5ac93bf..af8ad11 100644
--- a/src/elfgcchack.h
+++ b/src/elfgcchack.h
@@ -4312,6 +4312,16 @@
 #endif
 
 #ifdef bottom_hash
+#undef xmlHashDefaultDeallocator
+extern __typeof (xmlHashDefaultDeallocator) xmlHashDefaultDeallocator __attribute((alias("xmlHashDefaultDeallocator__internal_alias")));
+#else
+#ifndef xmlHashDefaultDeallocator
+extern __typeof (xmlHashDefaultDeallocator) xmlHashDefaultDeallocator__internal_alias __attribute((visibility("hidden")));
+#define xmlHashDefaultDeallocator xmlHashDefaultDeallocator__internal_alias
+#endif
+#endif
+
+#ifdef bottom_hash
 #undef xmlHashFree
 extern __typeof (xmlHashFree) xmlHashFree __attribute((alias("xmlHashFree__internal_alias")));
 #else
diff --git a/src/enc.h b/src/enc.h
index 057d206..a69a5d0 100644
--- a/src/enc.h
+++ b/src/enc.h
@@ -1,7 +1,7 @@
 /*
  * Summary: Internal Interfaces for encoding in libxml2
  * Description: this module describes a few interfaces which were
- *              addded along with the API changes in 2.9.0
+ *              added along with the API changes in 2.9.0
  *              those are private routines at this point
  *
  * Copy: See Copyright for the status of this software.
diff --git a/src/encoding.c b/src/encoding.c
index a3aaf10..65c5889 100644
--- a/src/encoding.c
+++ b/src/encoding.c
@@ -76,7 +76,7 @@
 
 /**
  * xmlEncodingErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -1795,7 +1795,7 @@
  *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
+ * The value of @outlen after return is the number of octets consumed.
  */
 static int
 xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
@@ -1863,7 +1863,7 @@
  *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
+ * The value of @outlen after return is the number of octets consumed.
  */
 static int
 xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
@@ -1972,7 +1972,7 @@
 
 /**
  * xmlCharEncFirstLineInt:
- * @handler:	char enconding transformation data structure
+ * @handler:	char encoding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
  * @len:  number of bytes to convert for the first line, or -1
@@ -2059,7 +2059,7 @@
 
 /**
  * xmlCharEncFirstLine:
- * @handler:	char enconding transformation data structure
+ * @handler:	char encoding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
  *
@@ -2546,7 +2546,7 @@
 
 /**
  * xmlCharEncOutFunc:
- * @handler:	char enconding transformation data structure
+ * @handler:	char encoding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
  *
@@ -2710,7 +2710,7 @@
 
 /**
  * xmlCharEncCloseFunc:
- * @handler:	char enconding transformation data structure
+ * @handler:	char encoding transformation data structure
  *
  * Generic front-end for encoding handler close function
  *
@@ -2811,7 +2811,7 @@
 	xmlCharEncodingHandler * handler = in->buf->encoder;
         /*
 	 * Encoding conversion, compute the number of unused original
-	 * bytes from the input not consumed and substract that from
+	 * bytes from the input not consumed and subtract that from
 	 * the raw consumed value, this is not a cheap operation
 	 */
         if (in->end - in->cur > 0) {
@@ -2860,7 +2860,7 @@
  * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
- * The value of @outlen after return is the number of ocetes consumed.
+ * The value of @outlen after return is the number of octets consumed.
  */
 static int
 UTF8ToISO8859x(unsigned char* out, int *outlen,
@@ -2976,7 +2976,7 @@
  * block of chars out.
  * Returns 0 if success, or -1 otherwise
  * The value of @inlen after return is the number of octets consumed
- * The value of @outlen after return is the number of ocetes produced.
+ * The value of @outlen after return is the number of octets produced.
  */
 static int
 ISO8859xToUTF8(unsigned char* out, int *outlen,
diff --git a/src/entities.c b/src/entities.c
index e4a09d6..ea54cc3 100644
--- a/src/entities.c
+++ b/src/entities.c
@@ -71,7 +71,7 @@
 
 /**
  * xmlEntitiesErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -148,7 +148,7 @@
 /*
  * xmlCreateEntity:
  *
- * internal routine doing the entity node strutures allocations
+ * internal routine doing the entity node structures allocations
  */
 static xmlEntityPtr
 xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
@@ -399,7 +399,7 @@
  *
  * Create a new entity, this differs from xmlAddDocEntity() that if
  * the document is NULL or has no internal subset defined, then an
- * unlinked entity structure will be returned, it is then the responsability
+ * unlinked entity structure will be returned, it is then the responsibility
  * of the caller to link it to the document later or free it when not needed
  * anymore.
  *
@@ -549,7 +549,7 @@
  * xmlEncodeEntitiesInternal:
  * @doc:  the document containing the string
  * @input:  A string to convert to XML.
- * @attr: are we handling an atrbute value
+ * @attr: are we handling an attribute value
  *
  * Do a global encoding of a string, replacing the predefined entities
  * and non ASCII values with their entities and CharRef counterparts.
diff --git a/src/error.c b/src/error.c
index 9d39f79..3e41e17 100644
--- a/src/error.c
+++ b/src/error.c
@@ -146,7 +146,7 @@
  * xmlParserPrintFileInfo:
  * @input:  an xmlParserInputPtr input
  *
- * Displays the associated file and line informations for the current input
+ * Displays the associated file and line information for the current input
  */
 
 void
@@ -238,7 +238,7 @@
  * @ctx: the parser context or NULL
  * @str: the formatted error message
  *
- * Report an erro with its context, replace the 4 old error/warning
+ * Report an error with its context, replace the 4 old error/warning
  * routines.
  */
 static void
@@ -643,7 +643,7 @@
  * @domain: where the error comes from
  * @code: the error code
  * @node: the context node
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
diff --git a/src/gentest.py b/src/gentest.py
index b763300..b6cd866 100755
--- a/src/gentest.py
+++ b/src/gentest.py
@@ -120,7 +120,7 @@
 "xmlRegisterInputCallbacks", "xmlReaderForIO",
 "xmlOutputBufferCreateIO", "xmlRegisterOutputCallbacks",
 "xmlSaveToIO", "xmlIOHTTPOpenW",
-# library state cleanup, generate false leak informations and other
+# library state cleanup, generate false leak information and other
 # troubles, heavillyb tested otherwise.
 "xmlCleanupParser", "xmlRelaxNGCleanupTypes", "xmlSetListDoc",
 "xmlSetTreeDoc", "xmlUnlinkNode",
@@ -676,7 +676,7 @@
 
     #
     # check we know how to handle the args and return values
-    # and store the informations for the generation
+    # and store the information for the generation
     #
     try:
 	args = node.xpathEval("arg")
diff --git a/src/globals.c b/src/globals.c
index 20b4308..0c0bdb4 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -107,7 +107,7 @@
  * @size:  the size requested in bytes
  *
  * The variable holding the libxml malloc() implementation for atomic
- * data (i.e. blocks not containings pointers), useful when using a
+ * data (i.e. blocks not containing pointers), useful when using a
  * garbage collecting allocator.
  *
  * Returns a pointer to the newly allocated block or NULL in case of error
@@ -215,7 +215,7 @@
 /**
  * xmlParserDebugEntities:
  *
- * Global setting, asking the parser to print out debugging informations.
+ * Global setting, asking the parser to print out debugging information.
  * while handling entities.
  * Disabled by default
  */
@@ -260,7 +260,7 @@
  * Global setting, indicate that the parser should store the line number
  * in the content field of elements in the DOM tree.
  * Disabled by default since this may not be safe for old classes of
- * applicaton.
+ * application.
  */
 int xmlLineNumbersDefaultValue = 0;
 static int xmlLineNumbersDefaultValueThrDef = 0;
@@ -361,7 +361,7 @@
  * xmlSaveNoEmptyTags:
  *
  * Global setting, asking the serializer to not output empty tags
- * as <empty/> but <empty></empty>. those two forms are undistinguishable
+ * as <empty/> but <empty></empty>. those two forms are indistinguishable
  * once parsed.
  * Disabled by default
  */
diff --git a/src/hash.c b/src/hash.c
index b0b4abc..afa094e 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -11,7 +11,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  * Author: breese@users.sourceforge.net
@@ -33,7 +33,8 @@
  * it seems that having hash randomization might be a good idea
  * when using XML with untrusted data
  */
-#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME) && \
+    !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
 #define HASH_RANDOMIZATION
 #endif
 
@@ -78,6 +79,9 @@
  * xmlHashComputeKey:
  * Calculate the hash key
  */
+#ifdef __clang__
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
+#endif
 static unsigned long
 xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
 	          const xmlChar *name2, const xmlChar *name3) {
@@ -108,6 +112,9 @@
     return (value % table->size);
 }
 
+#ifdef __clang__
+ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
+#endif
 static unsigned long
 xmlHashComputeQKey(xmlHashTablePtr table,
 		   const xmlChar *prefix, const xmlChar *name,
diff --git a/src/include/libxml/c14n.h b/src/include/libxml/c14n.h
index b8971d9..d74847d 100644
--- a/src/include/libxml/c14n.h
+++ b/src/include/libxml/c14n.h
@@ -28,17 +28,17 @@
 #include <libxml/xpath.h>
 
 /*
- * XML Canonicazation
+ * XML Canonicalization
  * http://www.w3.org/TR/xml-c14n
  *
- * Exclusive XML Canonicazation
+ * Exclusive XML Canonicalization
  * http://www.w3.org/TR/xml-exc-c14n
  *
  * Canonical form of an XML document could be created if and only if
  *  a) default attributes (if any) are added to all nodes
  *  b) all character and parsed entity references are resolved
- * In order to achive this in libxml2 the document MUST be loaded with
- * following global setings:
+ * In order to achieve this in libxml2 the document MUST be loaded with
+ * following global settings:
  *
  *    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
  *    xmlSubstituteEntitiesDefault(1);
@@ -59,7 +59,7 @@
  *
  */
 typedef enum {
-    XML_C14N_1_0            = 0,    /* Origianal C14N 1.0 spec */
+    XML_C14N_1_0            = 0,    /* Original C14N 1.0 spec */
     XML_C14N_EXCLUSIVE_1_0  = 1,    /* Exclusive C14N 1.0 spec */
     XML_C14N_1_1            = 2     /* C14N 1.1 spec */
 } xmlC14NMode;
@@ -96,7 +96,7 @@
 /**
  * xmlC14NIsVisibleCallback:
  * @user_data: user data
- * @node: the curent node
+ * @node: the current node
  * @parent: the parent node
  *
  * Signature for a C14N callback on visible nodes
diff --git a/src/include/libxml/catalog.h b/src/include/libxml/catalog.h
index 5a13f51..26b178d 100644
--- a/src/include/libxml/catalog.h
+++ b/src/include/libxml/catalog.h
@@ -39,7 +39,7 @@
 /**
  * XML_CATALOG_PI:
  *
- * The specific XML Catalog Processing Instuction name.
+ * The specific XML Catalog Processing Instruction name.
  */
 #define XML_CATALOG_PI						\
     (const xmlChar *) "oasis-xml-catalog"
diff --git a/src/include/libxml/dict.h b/src/include/libxml/dict.h
index b83db59..cf54af1 100644
--- a/src/include/libxml/dict.h
+++ b/src/include/libxml/dict.h
@@ -11,25 +11,18 @@
 #ifndef __XML_DICT_H__
 #define __XML_DICT_H__
 
+#include <stddef.h>
+#include <libxml/xmlversion.h>
+
 #ifdef __cplusplus
-#define __XML_EXTERNC	extern "C"
-#else
-#define __XML_EXTERNC
+extern "C" {
 #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>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+typedef struct _xmlDict xmlDict;
+typedef xmlDict *xmlDictPtr;
 
 /*
  * Initializer
diff --git a/src/include/libxml/hash.h b/src/include/libxml/hash.h
index 6352874..b682b6b 100644
--- a/src/include/libxml/hash.h
+++ b/src/include/libxml/hash.h
@@ -80,7 +80,7 @@
 /**
  * xmlHashScanner:
  * @payload:  the data in the hash
- * @data:  extra scannner data
+ * @data:  extra scanner data
  * @name:  the name associated
  *
  * Callback when scanning data in a hash with the simple scanner.
@@ -89,7 +89,7 @@
 /**
  * xmlHashScannerFull:
  * @payload:  the data in the hash
- * @data:  extra scannner data
+ * @data:  extra scanner data
  * @name:  the name associated
  * @name2:  the second name associated
  * @name3:  the third name associated
diff --git a/src/include/libxml/parser.h b/src/include/libxml/parser.h
index 47fbec0..3020b20 100644
--- a/src/include/libxml/parser.h
+++ b/src/include/libxml/parser.h
@@ -79,7 +79,7 @@
 /**
  * xmlParserNodeInfo:
  *
- * The parser can be asked to collect Node informations, i.e. at what
+ * The parser can be asked to collect Node information, i.e. at what
  * place in the file they were detected.
  * NOTE: This is off by default and not very well tested.
  */
@@ -283,11 +283,11 @@
     void *            *pushTab;       /* array of data for push */
     xmlHashTablePtr    attsDefault;   /* defaulted attributes if any */
     xmlHashTablePtr    attsSpecial;   /* non-CDATA attributes if any */
-    int                nsWellFormed;  /* is the document XML Nanespace okay */
+    int                nsWellFormed;  /* is the document XML Namespace okay */
     int                options;       /* Extra options */
 
     /*
-     * Those fields are needed only for treaming parsing so far
+     * Those fields are needed only for streaming parsing so far
      */
     int               dictNames;    /* Use dictionary names for the tree */
     int               freeElemsNr;  /* number of freed element nodes */
@@ -296,7 +296,7 @@
     xmlAttrPtr        freeAttrs;    /* List of freed attributes nodes */
 
     /*
-     * the complete error informations for the last error.
+     * the complete error information for the last error.
      */
     xmlError          lastError;
     xmlParserMode     parseMode;    /* the parser mode */
@@ -329,7 +329,7 @@
  * xmlSAXHandler:
  *
  * A SAX handler is bunch of callbacks called by the parser when processing
- * of the input generate data or structure informations.
+ * of the input generate data or structure information.
  */
 
 /**
@@ -685,7 +685,7 @@
  *               attribute values.
  *
  * SAX2 callback when an element start has been detected by the parser.
- * It provides the namespace informations for the element, as well as
+ * It provides the namespace information for the element, as well as
  * the new namespace declarations on the element.
  */
 
@@ -707,7 +707,7 @@
  * @URI:  the element namespace name if available
  *
  * SAX2 callback when an element end has been detected by the parser.
- * It provides the namespace informations for the element.
+ * It provides the namespace information for the element.
  */
 
 typedef void (*endElementNsSAX2Func)   (void *ctx,
@@ -1097,7 +1097,7 @@
     XML_PARSE_PEDANTIC	= 1<<7,	/* pedantic error reporting */
     XML_PARSE_NOBLANKS	= 1<<8,	/* remove blank nodes */
     XML_PARSE_SAX1	= 1<<9,	/* use the SAX1 interface internally */
-    XML_PARSE_XINCLUDE	= 1<<10,/* Implement XInclude substitition  */
+    XML_PARSE_XINCLUDE	= 1<<10,/* Implement XInclude substitution  */
     XML_PARSE_NONET	= 1<<11,/* Forbid network access */
     XML_PARSE_NODICT	= 1<<12,/* Do not reuse the context dictionary */
     XML_PARSE_NSCLEAN	= 1<<13,/* remove redundant namespaces declarations */
@@ -1191,7 +1191,7 @@
 /**
  * xmlFeature:
  *
- * Used to examine the existance of features that can be enabled
+ * Used to examine the existence of features that can be enabled
  * or disabled at compile-time.
  * They used to be called XML_FEATURE_xxx but this clashed with Expat
  */
diff --git a/src/include/libxml/parserInternals.h b/src/include/libxml/parserInternals.h
index f30fc68..1f26ce2 100644
--- a/src/include/libxml/parserInternals.h
+++ b/src/include/libxml/parserInternals.h
@@ -43,7 +43,7 @@
 /**
  * XML_MAX_NAME_LENGTH:
  *
- * Maximum size allowed for a markup identitier
+ * Maximum size allowed for a markup identifier.
  * This is not a limitation of the parser but a safety boundary feature,
  * use XML_PARSE_HUGE option to override it.
  * Note that with the use of parsing dictionaries overriding the limit
diff --git a/src/include/libxml/schemasInternals.h b/src/include/libxml/schemasInternals.h
index 6fb7113..c521d1c 100644
--- a/src/include/libxml/schemasInternals.h
+++ b/src/include/libxml/schemasInternals.h
@@ -321,13 +321,13 @@
 /**
  * XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED:
  *
- * The attribute wildcard has been already builded.
+ * The attribute wildcard has been built.
  */
 #define XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED 1 << 0
 /**
  * XML_SCHEMAS_ATTRGROUP_GLOBAL:
  *
- * The attribute wildcard has been already builded.
+ * The attribute group has been defined.
  */
 #define XML_SCHEMAS_ATTRGROUP_GLOBAL 1 << 1
 /**
@@ -725,7 +725,7 @@
 /**
  * XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION:
  *
- * disallowed substitutions: "substituion"
+ * disallowed substitutions: "substitution"
  */
 #define XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION        1 << 13
 /**
@@ -789,7 +789,7 @@
     xmlRegexpPtr contModel; /* Obsolete for WXS, maybe used for RelaxNG */
     xmlSchemaContentType contentType;
     const xmlChar *refPrefix; /* Deprecated; not used */
-    xmlSchemaValPtr defVal; /* The compiled value contraint. */
+    xmlSchemaValPtr defVal; /* The compiled value constraint. */
     void *idcs; /* The identity-constraint defs */
 };
 
@@ -881,7 +881,7 @@
 /**
  * XML_SCHEMAS_FINAL_DEFAULT_LIST:
  *
- * the cshema has "list" in the set of finalDefault.
+ * the schema has "list" in the set of finalDefault.
  */
 #define XML_SCHEMAS_FINAL_DEFAULT_LIST            1 << 4
 /**
@@ -942,7 +942,7 @@
     xmlDictPtr      dict;
     void *includes;     /* the includes, this is opaque for now */
     int preserve;        /* whether to free the document */
-    int counter; /* used to give ononymous components unique names */
+    int counter; /* used to give anonymous components unique names */
     xmlHashTablePtr idcDef; /* All identity-constraint defs. */
     void *volatiles; /* Obsolete */
 };
diff --git a/src/include/libxml/tree.h b/src/include/libxml/tree.h
index 626ed6a..1e79be9 100644
--- a/src/include/libxml/tree.h
+++ b/src/include/libxml/tree.h
@@ -443,7 +443,7 @@
     struct _xmlDoc  *doc;	/* the containing document */
     xmlNs           *ns;        /* pointer to the associated namespace */
     xmlAttributeType atype;     /* the attribute type if validating */
-    void            *psvi;	/* for type/PSVI informations */
+    void            *psvi;	/* for type/PSVI information */
 };
 
 /**
@@ -502,7 +502,7 @@
     xmlChar         *content;   /* the content */
     struct _xmlAttr *properties;/* properties list */
     xmlNs           *nsDef;     /* namespace definitions on this node */
-    void            *psvi;	/* for type/PSVI informations */
+    void            *psvi;	/* for type/PSVI information */
     unsigned short   line;	/* line number */
     unsigned short   extra;	/* extra data for XPath/XSLT */
 };
@@ -527,7 +527,7 @@
  * xmlDocProperty
  *
  * Set of properties of the document as found by the parser
- * Some of them are linked to similary named xmlParserOption
+ * Some of them are linked to similarly named xmlParserOption
  */
 typedef enum {
     XML_DOC_WELLFORMED		= 1<<0, /* document is XML well formed */
@@ -578,7 +578,7 @@
     int             charset;    /* Internal flag for charset handling,
 				   actually an xmlCharEncoding */
     struct _xmlDict *dict;      /* dict used to allocate names or NULL */
-    void           *psvi;	/* for type/PSVI informations */
+    void           *psvi;	/* for type/PSVI information */
     int             parseFlags;	/* set of xmlParserOption used to parse the
 				   document */
     int             properties;	/* set of xmlDocProperties for this document
diff --git a/src/include/libxml/xlink.h b/src/include/libxml/xlink.h
index a209a99..04e4b32 100644
--- a/src/include/libxml/xlink.h
+++ b/src/include/libxml/xlink.h
@@ -26,7 +26,7 @@
  *       of namespaces. If "foo" is the prefix for "http://foo.com/"
  *       then the link detection layer will expand role="foo:myrole"
  *       to "http://foo.com/:myrole".
- * NOTE: the link detection layer will expand URI-Refences found on
+ * NOTE: the link detection layer will expand URI-References found on
  *       href attributes by using the base mechanism if found.
  */
 typedef xmlChar *xlinkHRef;
diff --git a/src/include/libxml/xmlIO.h b/src/include/libxml/xmlIO.h
index 3e41744..095b2f5 100644
--- a/src/include/libxml/xmlIO.h
+++ b/src/include/libxml/xmlIO.h
@@ -27,7 +27,7 @@
  * @filename: the filename or URI
  *
  * Callback used in the I/O Input API to detect if the current handler
- * can provide input fonctionnalities for this resource.
+ * can provide input functionality for this resource.
  *
  * Returns 1 if yes and 0 if another Input module should be used
  */
@@ -73,7 +73,7 @@
  * @filename: the filename or URI
  *
  * Callback used in the I/O Output API to detect if the current handler
- * can provide output fonctionnalities for this resource.
+ * can provide output functionality for this resource.
  *
  * Returns 1 if yes and 0 if another Output module should be used
  */
@@ -217,6 +217,8 @@
  */
 XMLPUBFUN void XMLCALL
 	xmlCleanupOutputCallbacks		(void);
+XMLPUBFUN int XMLCALL
+	xmlPopOutputCallbacks			(void);
 XMLPUBFUN void XMLCALL
 	xmlRegisterDefaultOutputCallbacks(void);
 XMLPUBFUN xmlOutputBufferPtr XMLCALL
diff --git a/src/include/libxml/xmlerror.h b/src/include/libxml/xmlerror.h
index 037c16d..c101997 100644
--- a/src/include/libxml/xmlerror.h
+++ b/src/include/libxml/xmlerror.h
@@ -837,7 +837,7 @@
  * xmlGenericErrorFunc:
  * @ctx:  a parsing context
  * @msg:  the message
- * @...:  the extra arguments of the varags to format the message
+ * @...:  the extra arguments of the varargs to format the message
  *
  * Signature of the function to use when there is an error and
  * no parsing or validity context available .
diff --git a/src/include/libxml/xmlexports.h b/src/include/libxml/xmlexports.h
index 31ab8a1..f03af0d 100644
--- a/src/include/libxml/xmlexports.h
+++ b/src/include/libxml/xmlexports.h
@@ -73,9 +73,6 @@
     #define XMLCALL __cdecl
   #endif
   #define XMLCDECL __cdecl
-  #if !defined _REENTRANT
-    #define _REENTRANT
-  #endif
 #endif
 
 /* Windows platform with Borland compiler */
@@ -97,9 +94,6 @@
   #endif
   #define XMLCALL __cdecl
   #define XMLCDECL __cdecl
-  #if !defined _REENTRANT
-    #define _REENTRANT
-  #endif
 #endif
 
 /* Windows platform with GNU compiler (Mingw) */
@@ -126,9 +120,6 @@
   #endif
   #define XMLCALL __cdecl
   #define XMLCDECL __cdecl
-  #if !defined _REENTRANT
-    #define _REENTRANT
-  #endif
 #endif
 
 /* Cygwin platform (does not define _WIN32), GNU compiler */
diff --git a/src/include/libxml/xmlschemas.h b/src/include/libxml/xmlschemas.h
index 97930c7..b90e9d1 100644
--- a/src/include/libxml/xmlschemas.h
+++ b/src/include/libxml/xmlschemas.h
@@ -122,7 +122,7 @@
  * @line: returned line information
  *
  * A schemas validation locator, a callback called by the validator.
- * This is used when file or node informations are not available
+ * This is used when file or node information are not available
  * to find out what file and line number are affected
  *
  * Returns: 0 in case of success and -1 in case of error
diff --git a/src/include/libxml/xmlversion.h.in b/src/include/libxml/xmlversion.h.in
index d10f975..c995fe5 100644
--- a/src/include/libxml/xmlversion.h.in
+++ b/src/include/libxml/xmlversion.h.in
@@ -1,6 +1,6 @@
 /*
- * Summary: compile-time version informations
- * Description: compile-time version informations for the XML library
+ * Summary: compile-time version information
+ * Description: compile-time version information for the XML library
  *
  * Copy: See Copyright for the status of this software.
  *
@@ -91,11 +91,8 @@
  * Whether the thread support is configured in
  */
 #if @WITH_THREADS@
-#if defined(_REENTRANT) || defined(__MT__) || \
-    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
 #define LIBXML_THREAD_ENABLED
 #endif
-#endif
 
 /**
  * LIBXML_THREAD_ALLOC_ENABLED:
@@ -353,8 +350,10 @@
  * LIBXML_EXPR_ENABLED:
  *
  * Whether the formal expressions interfaces are compiled in
+ *
+ * This code is unused and disabled unconditionally for now.
  */
-#if @WITH_SCHEMAS@
+#if 0
 #define LIBXML_EXPR_ENABLED
 #endif
 
diff --git a/src/include/libxml/xpath.h b/src/include/libxml/xpath.h
index d96776c..a4303ff 100644
--- a/src/include/libxml/xpath.h
+++ b/src/include/libxml/xpath.h
@@ -70,7 +70,9 @@
     XPATH_INVALID_CHAR_ERROR,
     XPATH_INVALID_CTXT,
     XPATH_STACK_ERROR,
-    XPATH_FORBID_VARIABLE_ERROR
+    XPATH_FORBID_VARIABLE_ERROR,
+    XPATH_OP_LIMIT_EXCEEDED,
+    XPATH_RECURSION_LIMIT_EXCEEDED
 } xmlXPathError;
 
 /*
@@ -82,7 +84,7 @@
     int nodeNr;			/* number of nodes in the set */
     int nodeMax;		/* size of the array as allocated */
     xmlNodePtr *nodeTab;	/* array of nodes in no particular order */
-    /* @@ with_ns to check wether namespace nodes should be looked at @@ */
+    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
 };
 
 /*
@@ -352,6 +354,13 @@
 
     /* Cache for reusal of XPath objects */
     void *cache;
+
+    /* Resource limits */
+    unsigned long opLimit;
+    unsigned long opCount;
+    int depth;
+    int maxDepth;
+    int maxParserDepth;
 };
 
 /*
@@ -364,7 +373,7 @@
 /**
  * xmlXPathParserContext:
  *
- * An XPath parser context. It contains pure parsing informations,
+ * An XPath parser context. It contains pure parsing information,
  * an xmlXPathContext, and the stack of objects.
  */
 struct _xmlXPathParserContext {
diff --git a/src/include/win32config.h b/src/include/win32config.h
index 7fc7403..54392f4 100644
--- a/src/include/win32config.h
+++ b/src/include/win32config.h
@@ -38,7 +38,7 @@
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 /* MS C-runtime has functions which can be used in order to determine if
    a given floating-point variable contains NaN, (+-)INF. These are 
-   preferred, because floating-point technology is considered propriatary
+   preferred, because floating-point technology is considered proprietary
    by MS and we can assume that their functions know more about their 
    oddities than we do. */
 #include <float.h>
diff --git a/src/libxml.h b/src/libxml.h
index 64e30f7..1090729 100644
--- a/src/libxml.h
+++ b/src/libxml.h
@@ -34,7 +34,7 @@
 /*
  * Currently supported platforms use either autoconf or
  * copy to config.h own "preset" configuration file.
- * As result ifdef HAVE_CONFIG_H is omited here.
+ * As result ifdef HAVE_CONFIG_H is omitted here.
  */
 #include "config.h"
 #include <libxml/xmlversion.h>
@@ -53,7 +53,7 @@
 /**
  * TRIO_REPLACE_STDIO:
  *
- * This macro is defined if teh trio string formatting functions are to
+ * This macro is defined if the trio string formatting functions are to
  * be used instead of the default stdio ones.
  */
 #define TRIO_REPLACE_STDIO
@@ -72,6 +72,13 @@
 #define XML_POP_WARNINGS
 #endif
 
+#if defined(__clang__) || \
+    (defined(__GNUC__) && (__GNUC__ >= 8))
+#define ATTRIBUTE_NO_SANITIZE(arg) __attribute__((no_sanitize(arg)))
+#else
+#define ATTRIBUTE_NO_SANITIZE(arg)
+#endif
+
 /*
  * Internal variable indicating if a callback has been registered for
  * node creation/destruction. It avoids spending a lot of time in locking
@@ -79,7 +86,7 @@
  */
 extern int __xmlRegisterCallbacks;
 /*
- * internal error reporting routines, shared but not partof the API.
+ * internal error reporting routines, shared but not part of the API.
  */
 void __xmlIOErr(int domain, int code, const char *extra);
 void __xmlLoaderErr(void *ctx, const char *msg, const char *filename) LIBXML_ATTR_FORMAT(2,0);
diff --git a/src/libxml.m4 b/src/libxml.m4
index 2d7a6f5..b5df915 100644
--- a/src/libxml.m4
+++ b/src/libxml.m4
@@ -128,7 +128,7 @@
         printf("*** being found. The easiest way to fix this is to remove the old version\n");
         printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
         printf("*** correct copy of xml2-config. (In this case, you will have to\n");
-        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf\n");
         printf("*** so that the correct libraries are found at run-time))\n");
     }
   return 1;
diff --git a/src/libxml.spec.in b/src/libxml.spec.in
index d5f5ccb..11c29ea 100644
--- a/src/libxml.spec.in
+++ b/src/libxml.spec.in
@@ -128,7 +128,8 @@
 gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz
 
 %check
-make runtests
+#disabling python tests from rpm build as broken in Fedora 30
+make PYTHON_SUBDIR="" runtests
 
 %clean
 rm -fr %{buildroot}
diff --git a/src/libxml2.spec b/src/libxml2.spec
index e43a371..d2a5ffb 100644
--- a/src/libxml2.spec
+++ b/src/libxml2.spec
@@ -2,7 +2,7 @@
 
 Summary: Library providing XML and HTML support
 Name: libxml2
-Version: 2.9.9
+Version: 2.9.10
 Release: 1%{?dist}%{?extra_release}
 License: MIT
 Group: Development/Libraries
@@ -128,7 +128,8 @@
 gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz
 
 %check
-make runtests
+#disabling python tests from rpm build as broken in Fedora 30
+make PYTHON_SUBDIR="" runtests
 
 %clean
 rm -fr %{buildroot}
@@ -203,6 +204,6 @@
 %endif # with_python3
 
 %changelog
-* Fri Nov  8 2019 Daniel Veillard <veillard@redhat.com>
-- upstream release 2.9.9 see http://xmlsoft.org/news.html
+* Fri Apr 10 2020 Daniel Veillard <veillard@redhat.com>
+- upstream release 2.9.10 see http://xmlsoft.org/news.html
 
diff --git a/src/libxml2.syms b/src/libxml2.syms
index 9889cb2..33bc112 100644
--- a/src/libxml2.syms
+++ b/src/libxml2.syms
@@ -2070,27 +2070,27 @@
   xmlAutomataNewNegTrans;
 
 # xmlregexp
-  emptyExp; # variable
-  forbiddenExp; # variable
-  xmlExpCtxtNbCons;
-  xmlExpCtxtNbNodes;
-  xmlExpDump;
-  xmlExpExpDerive;
-  xmlExpFreeCtxt;
-  xmlExpFree;
-  xmlExpGetLanguage;
-  xmlExpGetStart;
-  xmlExpIsNillable;
-  xmlExpMaxToken;
-  xmlExpNewAtom;
-  xmlExpNewCtxt;
-  xmlExpNewOr;
-  xmlExpNewRange;
-  xmlExpNewSeq;
-  xmlExpParse;
-  xmlExpRef;
-  xmlExpStringDerive;
-  xmlExpSubsume;
+# emptyExp; removed in 2.9.10
+# forbiddenExp; removed in 2.9.10
+# xmlExpCtxtNbCons; removed in 2.9.10
+# xmlExpCtxtNbNodes; removed in 2.9.10
+# xmlExpDump; removed in 2.9.10
+# xmlExpExpDerive; removed in 2.9.10
+# xmlExpFreeCtxt; removed in 2.9.10
+# xmlExpFree; removed in 2.9.10
+# xmlExpGetLanguage; removed in 2.9.10
+# xmlExpGetStart; removed in 2.9.10
+# xmlExpIsNillable; removed in 2.9.10
+# xmlExpMaxToken; removed in 2.9.10
+# xmlExpNewAtom; removed in 2.9.10
+# xmlExpNewCtxt; removed in 2.9.10
+# xmlExpNewOr; removed in 2.9.10
+# xmlExpNewRange; removed in 2.9.10
+# xmlExpNewSeq; removed in 2.9.10
+# xmlExpParse; removed in 2.9.10
+# xmlExpRef; removed in 2.9.10
+# xmlExpStringDerive; removed in 2.9.10
+# xmlExpSubsume; removed in 2.9.10
 
 # parser
   xmlHasFeature;
@@ -2286,3 +2286,10 @@
   xmlHashDefaultDeallocator;
 } LIBXML2_2.9.1;
 
+LIBXML2_2.9.11 {
+    global:
+
+# xmlIO
+  xmlPopOutputCallbacks;
+} LIBXML2_2.9.8;
+
diff --git a/src/list.c b/src/list.c
index 24da6b1..2020715 100644
--- a/src/list.c
+++ b/src/list.c
@@ -9,7 +9,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  * Author: Gary.Pennington@uk.sun.com
diff --git a/src/nanoftp.c b/src/nanoftp.c
index 54fa026..18c1ce4 100644
--- a/src/nanoftp.c
+++ b/src/nanoftp.c
@@ -158,7 +158,7 @@
 
 /**
  * xmlFTPErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -172,7 +172,7 @@
  * xmlNanoFTPInit:
  *
  * Initialize the FTP protocol layer.
- * Currently it just checks for proxy informations,
+ * Currently it just checks for proxy information,
  * and get the hostname
  */
 
@@ -218,7 +218,7 @@
 /**
  * xmlNanoFTPCleanup:
  *
- * Cleanup the FTP protocol layer. This cleanup proxy informations.
+ * Cleanup the FTP protocol layer. This cleanup proxy information.
  */
 
 void
@@ -250,7 +250,7 @@
  * @passwd:  the proxy password
  * @type:  the type of proxy 1 for using SITE, 2 for USER a@b
  *
- * Setup the FTP proxy informations.
+ * Setup the FTP proxy information.
  * This can also be done by using ftp_proxy ftp_proxy_user and
  * ftp_proxy_password environment variables.
  */
@@ -412,7 +412,7 @@
  * (Re)Initialize the FTP Proxy context by parsing the URL and finding
  * the protocol host port it indicates.
  * Should be like ftp://myproxy/ or ftp://myproxy:3128/
- * A NULL URL cleans up proxy informations.
+ * A NULL URL cleans up proxy information.
  */
 
 void
@@ -1251,8 +1251,7 @@
 	xmlNanoFTPFreeCtxt(ctxt);
 	return(NULL);
     }
-    if (port != 0)
-	ctxt->port = port;
+    ctxt->port = port;
     res = xmlNanoFTPConnect(ctxt);
     if (res < 0) {
 	xmlNanoFTPFreeCtxt(ctxt);
@@ -1268,7 +1267,7 @@
  *
  * Tries to change the remote directory
  *
- * Returns -1 incase of error, 1 if CWD worked, 0 if it failed
+ * Returns -1 in case of error, 1 if CWD worked, 0 if it failed
  */
 
 int
@@ -1317,7 +1316,7 @@
  *
  * Tries to delete an item (file or directory) from server
  *
- * Returns -1 incase of error, 1 if DELE worked, 0 if it failed
+ * Returns -1 in case of error, 1 if DELE worked, 0 if it failed
  */
 
 int
@@ -1367,7 +1366,7 @@
  * Try to open a data connection to the server. Currently only
  * passive mode is supported.
  *
- * Returns -1 incase of error, 0 otherwise
+ * Returns -1 in case of error, 0 otherwise
  */
 
 SOCKET
@@ -1540,7 +1539,7 @@
  *
  * Close the data connection from the server
  *
- * Returns -1 incase of error, 0 otherwise
+ * Returns -1 in case of error, 0 otherwise
  */
 
 int
@@ -1591,7 +1590,7 @@
  *
  * Parse at most one entry from the listing.
  *
- * Returns -1 incase of error, the length of data parsed otherwise
+ * Returns -1 in case of error, the length of data parsed otherwise
  */
 
 static int
@@ -1719,7 +1718,7 @@
  * Do a listing on the server. All files info are passed back
  * in the callbacks.
  *
- * Returns -1 incase of error, 0 otherwise
+ * Returns -1 in case of error, 0 otherwise
  */
 
 int
@@ -1894,7 +1893,7 @@
  * Fetch the given file from the server. All data are passed back
  * in the callbacks. The last callback has a size of 0 block.
  *
- * Returns -1 incase of error, 0 otherwise
+ * Returns -1 in case of error, 0 otherwise
  */
 
 int
@@ -2024,7 +2023,7 @@
  *
  * Close the connection and both control and transport
  *
- * Returns -1 incase of error, 0 otherwise
+ * Returns -1 in case of error, 0 otherwise
  */
 
 int
diff --git a/src/nanohttp.c b/src/nanohttp.c
index 2143718..8e840f5 100644
--- a/src/nanohttp.c
+++ b/src/nanohttp.c
@@ -160,7 +160,7 @@
 
 /**
  * xmlHTTPErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -213,7 +213,7 @@
  * xmlNanoHTTPInit:
  *
  * Initialize the HTTP protocol layer.
- * Currently it just checks for proxy informations
+ * Currently it just checks for proxy information
  */
 
 void
@@ -344,7 +344,7 @@
  * (Re)Initialize the HTTP Proxy context by parsing the URL and finding
  * the protocol host port it indicates.
  * Should be like http://myproxy/ or http://myproxy:3128/
- * A NULL URL cleans up proxy informations.
+ * A NULL URL cleans up proxy information.
  */
 
 void
@@ -650,7 +650,7 @@
  * @ctxt:  an HTTP context
  *
  * Read one line in the HTTP server output, usually for extracting
- * the HTTP protocol informations from the answer header.
+ * the HTTP protocol information from the answer header.
  *
  * Returns a newly allocated string with a copy of the line, or NULL
  *         which indicate the end of the input.
@@ -693,7 +693,7 @@
  * @ctxt:  an HTTP context
  * @line:  an HTTP header line
  *
- * Try to extract useful informations from the server answer.
+ * Try to extract useful information from the server answer.
  * We currently parse and process:
  *  - The HTTP revision/ return code
  *  - The Content-Type, Mime-Type and charset used
@@ -1143,12 +1143,12 @@
 
 	    switch (h_errno) {
 		case HOST_NOT_FOUND:
-		    h_err_txt = "Authoritive host not found";
+		    h_err_txt = "Authoritative host not found";
 		    break;
 
 		case TRY_AGAIN:
 		    h_err_txt =
-			"Non-authoritive host not found or server failure.";
+			"Non-authoritative host not found or server failure.";
 		    break;
 
 		case NO_RECOVERY:
@@ -1625,7 +1625,7 @@
  * This function try to fetch the indicated resource via HTTP GET
  * and save it's content in the file.
  *
- * Returns -1 in case of failure, 0 incase of success. The contentType,
+ * Returns -1 in case of failure, 0 in case of success. The contentType,
  *     if provided must be freed by the caller
  */
 int
@@ -1675,7 +1675,7 @@
  * This function saves the output of the HTTP transaction to a file
  * It closes and free the context at the end
  *
- * Returns -1 in case of failure, 0 incase of success.
+ * Returns -1 in case of failure, 0 in case of success.
  */
 int
 xmlNanoHTTPSave(void *ctxt, const char *filename) {
diff --git a/src/parser.c b/src/parser.c
index 3a8a0d7..87d9e61 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -108,7 +108,7 @@
 /*
  * XML_PARSER_NON_LINEAR is the threshold where the ratio of parsed entity
  *    replacement over the size in byte of the input indicates that you have
- *    and eponential behaviour. A value of 10 correspond to at least 3 entity
+ *    and exponential behaviour. A value of 10 correspond to at least 3 entity
  *    replacement per byte of input.
  */
 #define XML_PARSER_NON_LINEAR 10
@@ -141,10 +141,11 @@
         xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
         return (1);
     }
+
     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;
+	unsigned long oldnbent = ctxt->nbentities, diff;
 	xmlChar *rep;
 
         ent->guard = XML_ENTITY_BEING_CHECKED;
@@ -159,7 +160,10 @@
 	    ent->content[0] = 0;
 	}
 
-	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+        diff = ctxt->nbentities - oldnbent + 1;
+        if (diff > INT_MAX / 2)
+            diff = INT_MAX / 2;
+	ent->checked = diff * 2;
 	if (rep != NULL) {
 	    if (xmlStrchr(rep, '<'))
 		ent->checked |= 1;
@@ -1066,7 +1070,7 @@
  * xmlDetectSAX2:
  * @ctxt:  an XML parser context
  *
- * Do the SAX2 detection and specific intialization
+ * Do the SAX2 detection and specific initialization
  */
 static void
 xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
@@ -1398,7 +1402,7 @@
  * [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
  * [38] Subcode ::= ([a-z] | [A-Z])+
  *
- * The current REC reference the sucessors of RFC 1766, currently 5646
+ * The current REC reference the successors of RFC 1766, currently 5646
  *
  * http://www.rfc-editor.org/rfc/rfc5646.txt
  * langtag       = language
@@ -2081,11 +2085,11 @@
 	xmlGROW (ctxt);
 
 static void xmlGROW (xmlParserCtxtPtr ctxt) {
-    unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
-    unsigned long curBase = ctxt->input->cur - ctxt->input->base;
+    ptrdiff_t curEnd = ctxt->input->end - ctxt->input->cur;
+    ptrdiff_t curBase = ctxt->input->cur - ctxt->input->base;
 
-    if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) ||
-         (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) &&
+    if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
+         (curBase > XML_MAX_LOOKUP_LIMIT)) &&
          ((ctxt->input->buf) &&
           (ctxt->input->buf->readcallback != xmlInputReadCallbackNop)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
@@ -2287,9 +2291,8 @@
  */
 int
 xmlParseCharRef(xmlParserCtxtPtr ctxt) {
-    unsigned int val = 0;
+    int val = 0;
     int count = 0;
-    unsigned int outofrange = 0;
 
     /*
      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
@@ -2316,8 +2319,8 @@
 		val = 0;
 		break;
 	    }
-	    if (val > 0x10FFFF)
-	        outofrange = val;
+	    if (val > 0x110000)
+	        val = 0x110000;
 
 	    NEXT;
 	    count++;
@@ -2345,8 +2348,8 @@
 		val = 0;
 		break;
 	    }
-	    if (val > 0x10FFFF)
-	        outofrange = val;
+	    if (val > 0x110000)
+	        val = 0x110000;
 
 	    NEXT;
 	    count++;
@@ -2366,7 +2369,11 @@
      * Characters referred to using character references must match the
      * production for Char.
      */
-    if ((IS_CHAR(val) && (outofrange == 0))) {
+    if (val >= 0x110000) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                "xmlParseCharRef: character reference out of bounds\n",
+	        val);
+    } else if (IS_CHAR(val)) {
         return(val);
     } else {
         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -2398,8 +2405,7 @@
 xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) {
     const xmlChar *ptr;
     xmlChar cur;
-    unsigned int val = 0;
-    unsigned int outofrange = 0;
+    int val = 0;
 
     if ((str == NULL) || (*str == NULL)) return(0);
     ptr = *str;
@@ -2419,8 +2425,8 @@
 		val = 0;
 		break;
 	    }
-	    if (val > 0x10FFFF)
-	        outofrange = val;
+	    if (val > 0x110000)
+	        val = 0x110000;
 
 	    ptr++;
 	    cur = *ptr;
@@ -2438,8 +2444,8 @@
 		val = 0;
 		break;
 	    }
-	    if (val > 0x10FFFF)
-	        outofrange = val;
+	    if (val > 0x110000)
+	        val = 0x110000;
 
 	    ptr++;
 	    cur = *ptr;
@@ -2457,7 +2463,11 @@
      * Characters referred to using character references must match the
      * production for Char.
      */
-    if ((IS_CHAR(val) && (outofrange == 0))) {
+    if (val >= 0x110000) {
+        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                "xmlParseStringCharRef: character reference out of bounds\n",
+                val);
+    } else if (IS_CHAR(val)) {
         return(val);
     } else {
         xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -2632,7 +2642,8 @@
     else
         c = 0;
     while ((c != 0) && (c != end) && /* non input consuming loop */
-	   (c != end2) && (c != end3)) {
+           (c != end2) && (c != end3) &&
+           (ctxt->instate != XML_PARSER_EOF)) {
 
 	if (c == 0) break;
         if ((c == '&') && (str[1] == '#')) {
@@ -2708,7 +2719,7 @@
 		    /*
 		     * Note: external parsed entities will not be loaded,
 		     * it is not required for a non-validating parser to
-		     * complete external PEreferences coming from the
+		     * complete external PEReferences coming from the
 		     * internal subset
 		     */
 		    if (((ctxt->options & XML_PARSE_NOENT) != 0) ||
@@ -3372,7 +3383,7 @@
 	    /*
 	     * 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.
+	     * by current length.
 	     */
 	    ctxt->input->cur -= l;
 	    GROW;
@@ -3841,7 +3852,7 @@
  * xmlParseAttValueComplex:
  * @ctxt:  an XML parser context
  * @len:   the resulting attribute len
- * @normalize:  wether to apply the inner normalization
+ * @normalize:  whether to apply the inner normalization
  *
  * parse a value for an attribute, this is the fallback function
  * of xmlParseAttValue() when the attribute parsing requires handling
@@ -3897,7 +3908,6 @@
                            "AttValue length too long\n");
             goto mem_error;
         }
-	if (c == 0) break;
 	if (c == '&') {
 	    in_space = 0;
 	    if (NXT(1) == '#') {
@@ -3990,14 +4000,17 @@
 		     */
 		    if ((ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
 			(ent->content != NULL) && (ent->checked == 0)) {
-			unsigned long oldnbent = ctxt->nbentities;
+			unsigned long oldnbent = ctxt->nbentities, diff;
 
 			++ctxt->depth;
 			rep = xmlStringDecodeEntities(ctxt, ent->content,
 						  XML_SUBSTITUTE_REF, 0, 0, 0);
 			--ctxt->depth;
 
-			ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+                        diff = ctxt->nbentities - oldnbent + 1;
+                        if (diff > INT_MAX / 2)
+                            diff = INT_MAX / 2;
+                        ent->checked = diff * 2;
 			if (rep != NULL) {
 			    if (xmlStrchr(rep, '<'))
 			        ent->checked |= 1;
@@ -4065,7 +4078,7 @@
 
     /*
      * There we potentially risk an overflow, don't allow attribute value of
-     * length more than INT_MAX it is a very reasonnable assumption !
+     * length more than INT_MAX it is a very reasonable assumption !
      */
     if (len >= INT_MAX) {
         xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -4670,7 +4683,7 @@
  * xmlParseCommentComplex:
  * @ctxt:  an XML parser context
  * @buf:  the already parsed part of the buffer
- * @len:  number of bytes filles in the buffer
+ * @len:  number of bytes in the buffer
  * @size:  allocated size of the buffer
  *
  * Skip an XML (SGML) comment <!-- .... -->
@@ -4961,6 +4974,10 @@
 		} else
 		    xmlFatalErrMsgStr(ctxt, XML_ERR_HYPHEN_IN_COMMENT,
 		                      "Double hyphen within comment\n", NULL);
+                if (ctxt->instate == XML_PARSER_EOF) {
+                    xmlFree(buf);
+                    return;
+                }
 		in++;
 		ctxt->input->col++;
 	    }
@@ -5032,7 +5049,7 @@
  * <?oasis-xml-catalog catalog="http://example.com/catalog.xml"?>
  *
  * Occurs only if allowed by the user and if happening in the Misc
- * part of the document before any doctype informations
+ * part of the document before any doctype information
  * This will add the given catalog to the parsing context in order
  * to be used if there is a resolution need further down in the document
  */
@@ -5091,7 +5108,7 @@
  *
  * [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
  *
- * The processing is transfered to SAX once parsed.
+ * The processing is transferred to SAX once parsed.
  */
 
 void
@@ -5507,7 +5524,7 @@
 				    literal, URI, NULL);
 		    /*
 		     * For expat compatibility in SAX mode.
-		     * assuming the entity repalcement was asked for
+		     * assuming the entity replacement was asked for
 		     */
 		    if ((ctxt->replaceEntities != 0) &&
 			((ctxt->myDoc == NULL) ||
@@ -6617,149 +6634,143 @@
 
 static void
 xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
-    int id = ctxt->input->id;
+    int *inputIds = NULL;
+    size_t inputIdsSize = 0;
+    size_t depth = 0;
 
-    SKIP(3);
-    SKIP_BLANKS;
-    if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
-	SKIP(7);
-	SKIP_BLANKS;
-	if (RAW != '[') {
-	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
-	    xmlHaltParser(ctxt);
-	    return;
-	} else {
-	    if (ctxt->input->id != id) {
-		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-	                       "All markup of the conditional section is not"
+    while (ctxt->instate != XML_PARSER_EOF) {
+        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+            int id = ctxt->input->id;
+
+            SKIP(3);
+            SKIP_BLANKS;
+
+            if (CMP7(CUR_PTR, 'I', 'N', 'C', 'L', 'U', 'D', 'E')) {
+                SKIP(7);
+                SKIP_BLANKS;
+                if (RAW != '[') {
+                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+                    xmlHaltParser(ctxt);
+                    goto error;
+                }
+                if (ctxt->input->id != id) {
+                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                                   "All markup of the conditional section is"
+                                   " not in the same entity\n");
+                }
+                NEXT;
+
+                if (inputIdsSize <= depth) {
+                    int *tmp;
+
+                    inputIdsSize = (inputIdsSize == 0 ? 4 : inputIdsSize * 2);
+                    tmp = (int *) xmlRealloc(inputIds,
+                            inputIdsSize * sizeof(int));
+                    if (tmp == NULL) {
+                        xmlErrMemory(ctxt, NULL);
+                        goto error;
+                    }
+                    inputIds = tmp;
+                }
+                inputIds[depth] = id;
+                depth++;
+            } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
+                int state;
+                xmlParserInputState instate;
+                size_t ignoreDepth = 0;
+
+                SKIP(6);
+                SKIP_BLANKS;
+                if (RAW != '[') {
+                    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+                    xmlHaltParser(ctxt);
+                    goto error;
+                }
+                if (ctxt->input->id != id) {
+                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                                   "All markup of the conditional section is"
+                                   " not in the same entity\n");
+                }
+                NEXT;
+
+                /*
+                 * Parse up to the end of the conditional section but disable
+                 * SAX event generating DTD building in the meantime
+                 */
+                state = ctxt->disableSAX;
+                instate = ctxt->instate;
+                if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+                ctxt->instate = XML_PARSER_IGNORE;
+
+                while (RAW != 0) {
+                    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+                        SKIP(3);
+                        ignoreDepth++;
+                        /* Check for integer overflow */
+                        if (ignoreDepth == 0) {
+                            xmlErrMemory(ctxt, NULL);
+                            goto error;
+                        }
+                    } else if ((RAW == ']') && (NXT(1) == ']') &&
+                               (NXT(2) == '>')) {
+                        if (ignoreDepth == 0)
+                            break;
+                        SKIP(3);
+                        ignoreDepth--;
+                    } else {
+                        NEXT;
+                    }
+                }
+
+                ctxt->disableSAX = state;
+                ctxt->instate = instate;
+
+		if (RAW == 0) {
+		    xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
+                    goto error;
+		}
+                if (ctxt->input->id != id) {
+                    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                                   "All markup of the conditional section is"
+                                   " not in the same entity\n");
+                }
+                SKIP(3);
+            } else {
+                xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+                xmlHaltParser(ctxt);
+                goto error;
+            }
+        } else if ((depth > 0) &&
+                   (RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
+            depth--;
+            if (ctxt->input->id != inputIds[depth]) {
+                xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
+                               "All markup of the conditional section is not"
                                " in the same entity\n");
-	    }
-	    NEXT;
-	}
-	if (xmlParserDebugEntities) {
-	    if ((ctxt->input != NULL) && (ctxt->input->filename))
-		xmlGenericError(xmlGenericErrorContext,
-			"%s(%d): ", ctxt->input->filename,
-			ctxt->input->line);
-	    xmlGenericError(xmlGenericErrorContext,
-		    "Entering INCLUDE Conditional Section\n");
-	}
+            }
+            SKIP(3);
+        } else {
+            const xmlChar *check = CUR_PTR;
+            unsigned int cons = ctxt->input->consumed;
+
+            xmlParseMarkupDecl(ctxt);
+
+            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+                xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+                xmlHaltParser(ctxt);
+                goto error;
+            }
+        }
+
+        if (depth == 0)
+            break;
 
         SKIP_BLANKS;
         GROW;
-	while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
-	        (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
-	    const xmlChar *check = CUR_PTR;
-	    unsigned int cons = ctxt->input->consumed;
-
-	    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-		xmlParseConditionalSections(ctxt);
-	    } else
-		xmlParseMarkupDecl(ctxt);
-
-            SKIP_BLANKS;
-            GROW;
-
-	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
-		xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
-		xmlHaltParser(ctxt);
-		break;
-	    }
-	}
-	if (xmlParserDebugEntities) {
-	    if ((ctxt->input != NULL) && (ctxt->input->filename))
-		xmlGenericError(xmlGenericErrorContext,
-			"%s(%d): ", ctxt->input->filename,
-			ctxt->input->line);
-	    xmlGenericError(xmlGenericErrorContext,
-		    "Leaving INCLUDE Conditional Section\n");
-	}
-
-    } else if (CMP6(CUR_PTR, 'I', 'G', 'N', 'O', 'R', 'E')) {
-	int state;
-	xmlParserInputState instate;
-	int depth = 0;
-
-	SKIP(6);
-	SKIP_BLANKS;
-	if (RAW != '[') {
-	    xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
-	    xmlHaltParser(ctxt);
-	    return;
-	} else {
-	    if (ctxt->input->id != id) {
-		xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-	                       "All markup of the conditional section is not"
-                               " in the same entity\n");
-	    }
-	    NEXT;
-	}
-	if (xmlParserDebugEntities) {
-	    if ((ctxt->input != NULL) && (ctxt->input->filename))
-		xmlGenericError(xmlGenericErrorContext,
-			"%s(%d): ", ctxt->input->filename,
-			ctxt->input->line);
-	    xmlGenericError(xmlGenericErrorContext,
-		    "Entering IGNORE Conditional Section\n");
-	}
-
-	/*
-	 * Parse up to the end of the conditional section
-	 * But disable SAX event generating DTD building in the meantime
-	 */
-	state = ctxt->disableSAX;
-	instate = ctxt->instate;
-	if (ctxt->recovery == 0) ctxt->disableSAX = 1;
-	ctxt->instate = XML_PARSER_IGNORE;
-
-	while (((depth >= 0) && (RAW != 0)) &&
-               (ctxt->instate != XML_PARSER_EOF)) {
-	  if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-	    depth++;
-	    SKIP(3);
-	    continue;
-	  }
-	  if ((RAW == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
-	    if (--depth >= 0) SKIP(3);
-	    continue;
-	  }
-	  NEXT;
-	  continue;
-	}
-
-	ctxt->disableSAX = state;
-	ctxt->instate = instate;
-
-	if (xmlParserDebugEntities) {
-	    if ((ctxt->input != NULL) && (ctxt->input->filename))
-		xmlGenericError(xmlGenericErrorContext,
-			"%s(%d): ", ctxt->input->filename,
-			ctxt->input->line);
-	    xmlGenericError(xmlGenericErrorContext,
-		    "Leaving IGNORE Conditional Section\n");
-	}
-
-    } else {
-	xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
-	xmlHaltParser(ctxt);
-	return;
     }
 
-    if (RAW == 0)
-        SHRINK;
-
-    if (RAW == 0) {
-	xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL);
-    } else {
-	if (ctxt->input->id != id) {
-	    xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
-	                   "All markup of the conditional section is not in"
-                           " the same entity\n");
-	}
-	if ((ctxt-> instate != XML_PARSER_EOF) &&
-	    ((ctxt->input->cur + 3) <= ctxt->input->end))
-	    SKIP(3);
-    }
+error:
+    xmlFree(inputIds);
 }
 
 /**
@@ -6816,21 +6827,11 @@
 
     /*
      * detect requirement to exit there and act accordingly
-     * and avoid having instate overriden later on
+     * and avoid having instate overridden later on
      */
     if (ctxt->instate == XML_PARSER_EOF)
         return;
 
-    /*
-     * Conditional sections are allowed from entities included
-     * by PE References in the internal subset.
-     */
-    if ((ctxt->external == 0) && (ctxt->inputNr > 1)) {
-        if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
-	    xmlParseConditionalSections(ctxt);
-	}
-    }
-
     ctxt->instate = XML_PARSER_DTD;
 }
 
@@ -7092,7 +7093,7 @@
          ((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;
+	unsigned long oldnbent = ctxt->nbentities, diff;
 
 	/*
 	 * This is a bit hackish but this seems the best
@@ -7138,7 +7139,10 @@
 	 * Store the number of entities needing parsing for this entity
 	 * content and do checkings
 	 */
-	ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+        diff = ctxt->nbentities - oldnbent + 1;
+        if (diff > INT_MAX / 2)
+            diff = INT_MAX / 2;
+        ent->checked = diff * 2;
 	if ((ent->content != NULL) && (xmlStrchr(ent->content, '<')))
 	    ent->checked |= 1;
 	if (ret == XML_ERR_ENTITY_LOOP) {
@@ -7156,42 +7160,38 @@
 	     (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY))&&
 		(ent->children == NULL)) {
 		ent->children = list;
-		if (ctxt->replaceEntities) {
-		    /*
-		     * Prune it directly in the generated document
-		     * except for single text nodes.
-		     */
-		    if (((list->type == XML_TEXT_NODE) &&
-			 (list->next == NULL)) ||
-			(ctxt->parseMode == XML_PARSE_READER)) {
-			list->parent = (xmlNodePtr) ent;
-			list = NULL;
-			ent->owner = 1;
-		    } else {
-			ent->owner = 0;
-			while (list != NULL) {
-			    list->parent = (xmlNodePtr) ctxt->node;
-			    list->doc = ctxt->myDoc;
-			    if (list->next == NULL)
-				ent->last = list;
-			    list = list->next;
-			}
-			list = ent->children;
+                /*
+                 * Prune it directly in the generated document
+                 * except for single text nodes.
+                 */
+                if ((ctxt->replaceEntities == 0) ||
+                    (ctxt->parseMode == XML_PARSE_READER) ||
+                    ((list->type == XML_TEXT_NODE) &&
+                     (list->next == NULL))) {
+                    ent->owner = 1;
+                    while (list != NULL) {
+                        list->parent = (xmlNodePtr) ent;
+                        xmlSetTreeDoc(list, ent->doc);
+                        if (list->next == NULL)
+                            ent->last = list;
+                        list = list->next;
+                    }
+                    list = NULL;
+                } else {
+                    ent->owner = 0;
+                    while (list != NULL) {
+                        list->parent = (xmlNodePtr) ctxt->node;
+                        list->doc = ctxt->myDoc;
+                        if (list->next == NULL)
+                            ent->last = list;
+                        list = list->next;
+                    }
+                    list = ent->children;
 #ifdef LIBXML_LEGACY_ENABLED
-			if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
-			  xmlAddEntityReference(ent, list, NULL);
+                    if (ent->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)
+                        xmlAddEntityReference(ent, list, NULL);
 #endif /* LIBXML_LEGACY_ENABLED */
-		    }
-		} else {
-		    ent->owner = 1;
-		    while (list != NULL) {
-			list->parent = (xmlNodePtr) ent;
-			xmlSetTreeDoc(list, ent->doc);
-			if (list->next == NULL)
-			    ent->last = list;
-			list = list->next;
-		    }
-		}
+                }
 	    } else {
 		xmlFreeNodeList(list);
 		list = NULL;
@@ -7692,7 +7692,7 @@
     }
 
     /*
-     * Increate the number of entity references parsed
+     * Increase the number of entity references parsed
      */
     ctxt->nbentities++;
 
@@ -7868,7 +7868,7 @@
     NEXT;
 
     /*
-     * Increate the number of entity references parsed
+     * Increase the number of entity references parsed
      */
     ctxt->nbentities++;
 
@@ -8134,7 +8134,7 @@
     ptr++;
 
     /*
-     * Increate the number of entity references parsed
+     * Increase the number of entity references parsed
      */
     ctxt->nbentities++;
 
@@ -8302,6 +8302,15 @@
 	    xmlParseMarkupDecl(ctxt);
 	    xmlParsePEReference(ctxt);
 
+            /*
+             * Conditional sections are allowed from external entities included
+             * by PE References in the internal subset.
+             */
+            if ((ctxt->inputNr > 1) && (ctxt->input->filename != NULL) &&
+                (RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+                xmlParseConditionalSections(ctxt);
+            }
+
 	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 		xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
 	     "xmlParseInternalSubset: error detected in Markup declaration\n");
@@ -8623,7 +8632,7 @@
      *
      */
     if (name != (xmlChar*)1) {
-        if (name == NULL) name = BAD_CAST "unparseable";
+        if (name == NULL) name = BAD_CAST "unparsable";
         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
 		     "Opening and ending tag mismatch: %s line %d and %s\n",
 		                ctxt->name, line, name);
@@ -8730,12 +8739,16 @@
 	if (l == NULL) {
 	    xmlChar *tmp;
 
+            if (ctxt->instate == XML_PARSER_EOF)
+                return(NULL);
             xmlNsErr(ctxt, XML_NS_ERR_QNAME,
 	             "Failed to parse QName '%s:'\n", p, NULL, NULL);
 	    l = xmlParseNmtoken(ctxt);
-	    if (l == NULL)
+	    if (l == NULL) {
+                if (ctxt->instate == XML_PARSER_EOF)
+                    return(NULL);
 		tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
-	    else {
+            } else {
 		tmp = xmlBuildQName(l, p, NULL, 0);
 		xmlFree((char *)l);
 	    }
@@ -8758,6 +8771,8 @@
 		*prefix = p;
 		return(l);
 	    }
+            if (ctxt->instate == XML_PARSER_EOF)
+                return(NULL);
 	    tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
 	    l = xmlDictLookup(ctxt->dict, tmp, -1);
 	    if (tmp != NULL) xmlFree(tmp);
@@ -8857,6 +8872,18 @@
  *     caller if it was copied, this can be detected by val[*len] == 0.
  */
 
+#define GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) \
+    const xmlChar *oldbase = ctxt->input->base;\
+    GROW;\
+    if (ctxt->instate == XML_PARSER_EOF)\
+        return(NULL);\
+    if (oldbase != ctxt->input->base) {\
+        ptrdiff_t delta = ctxt->input->base - oldbase;\
+        start = start + delta;\
+        in = in + delta;\
+    }\
+    end = ctxt->input->end;
+
 static xmlChar *
 xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
                          int normalize)
@@ -8886,14 +8913,7 @@
     end = ctxt->input->end;
     start = in;
     if (in >= end) {
-        const xmlChar *oldbase = ctxt->input->base;
-	GROW;
-	if (oldbase != ctxt->input->base) {
-	    long delta = ctxt->input->base - oldbase;
-	    start = start + delta;
-	    in = in + delta;
-	}
-	end = ctxt->input->end;
+        GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
     }
     if (normalize) {
         /*
@@ -8910,16 +8930,7 @@
 	    in++;
 	    start = in;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -8933,16 +8944,7 @@
 	    col++;
 	    if ((*in++ == 0x20) && (*in == 0x20)) break;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -8971,7 +8973,7 @@
                 if (ctxt->instate == XML_PARSER_EOF)
                     return(NULL);
 		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
+		    ptrdiff_t delta = ctxt->input->base - oldbase;
 		    start = start + delta;
 		    in = in + delta;
 		    last = last + delta;
@@ -8998,16 +9000,7 @@
 	    in++;
 	    col++;
 	    if (in >= end) {
-		const xmlChar *oldbase = ctxt->input->base;
-		GROW;
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-		if (oldbase != ctxt->input->base) {
-		    long delta = ctxt->input->base - oldbase;
-		    start = start + delta;
-		    in = in + delta;
-		}
-		end = ctxt->input->end;
+                GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
                 if (((in - start) > XML_MAX_TEXT_LENGTH) &&
                     ((ctxt->options & XML_PARSE_HUGE) == 0)) {
                     xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
@@ -9101,7 +9094,7 @@
 	if (normalize) {
 	    /*
 	     * Sometimes a second normalisation pass for spaces is needed
-	     * but that only happens if charrefs or entities refernces
+	     * but that only happens if charrefs or entities references
 	     * have been used in the attribute value, i.e. the attribute
 	     * value have been extracted in an allocated string already.
 	     */
@@ -9682,7 +9675,7 @@
      *
      */
     if (name != (xmlChar*)1) {
-        if (name == NULL) name = BAD_CAST "unparseable";
+        if (name == NULL) name = BAD_CAST "unparsable";
         if ((line == 0) && (ctxt->node != NULL))
             line = ctxt->node->line;
         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
@@ -10300,7 +10293,7 @@
 	}
 
 	/*
-	 * UTF-16 encoding stwich has already taken place at this stage,
+	 * UTF-16 encoding switch has already taken place at this stage,
 	 * more over the little-endian/big-endian selection is already done
 	 */
         if ((encoding != NULL) &&
@@ -11183,7 +11176,7 @@
 	else {
 	    /*
 	     * If we are operating on converted input, try to flush
-	     * remainng chars to avoid them stalling in the non-converted
+	     * remaining chars to avoid them stalling in the non-converted
 	     * buffer. But do not do this in document start where
 	     * encoding="..." may not have been read and we work on a
 	     * guessed encoding.
@@ -12885,196 +12878,28 @@
 int
 xmlParseCtxtExternalEntity(xmlParserCtxtPtr ctx, const xmlChar *URL,
 	               const xmlChar *ID, xmlNodePtr *lst) {
-    xmlParserCtxtPtr ctxt;
-    xmlDocPtr newDoc;
-    xmlNodePtr newRoot;
-    xmlSAXHandlerPtr oldsax = NULL;
-    int ret = 0;
-    xmlChar start[4];
-    xmlCharEncoding enc;
+    void *userData;
 
     if (ctx == NULL) return(-1);
-
-    if (((ctx->depth > 40) && ((ctx->options & XML_PARSE_HUGE) == 0)) ||
-        (ctx->depth > 1024)) {
-	return(XML_ERR_ENTITY_LOOP);
-    }
-
-    if (lst != NULL)
-        *lst = NULL;
-    if ((URL == NULL) && (ID == NULL))
-	return(-1);
-    if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
-	return(-1);
-
-    ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
-    if (ctxt == NULL) {
-	return(-1);
-    }
-
-    oldsax = ctxt->sax;
-    ctxt->sax = ctx->sax;
-    xmlDetectSAX2(ctxt);
-    newDoc = xmlNewDoc(BAD_CAST "1.0");
-    if (newDoc == NULL) {
-	xmlFreeParserCtxt(ctxt);
-	return(-1);
-    }
-    newDoc->properties = XML_DOC_INTERNAL;
-    if (ctx->myDoc->dict) {
-	newDoc->dict = ctx->myDoc->dict;
-	xmlDictReference(newDoc->dict);
-    }
-    if (ctx->myDoc != NULL) {
-	newDoc->intSubset = ctx->myDoc->intSubset;
-	newDoc->extSubset = ctx->myDoc->extSubset;
-    }
-    if (ctx->myDoc->URL != NULL) {
-	newDoc->URL = xmlStrdup(ctx->myDoc->URL);
-    }
-    newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
-    if (newRoot == NULL) {
-	ctxt->sax = oldsax;
-	xmlFreeParserCtxt(ctxt);
-	newDoc->intSubset = NULL;
-	newDoc->extSubset = NULL;
-        xmlFreeDoc(newDoc);
-	return(-1);
-    }
-    xmlAddChild((xmlNodePtr) newDoc, newRoot);
-    nodePush(ctxt, newDoc->children);
-    if (ctx->myDoc == NULL) {
-	ctxt->myDoc = newDoc;
-    } else {
-	ctxt->myDoc = ctx->myDoc;
-	newDoc->children->doc = ctx->myDoc;
-    }
-
     /*
-     * Get the 4 first bytes and decode the charset
-     * if enc != XML_CHAR_ENCODING_NONE
-     * plug some encoding conversion routines.
-     */
-    GROW
-    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
-	start[0] = RAW;
-	start[1] = NXT(1);
-	start[2] = NXT(2);
-	start[3] = NXT(3);
-	enc = xmlDetectCharEncoding(start, 4);
-	if (enc != XML_CHAR_ENCODING_NONE) {
-	    xmlSwitchEncoding(ctxt, enc);
-	}
-    }
-
-    /*
-     * Parse a possible text declaration first
-     */
-    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
-	xmlParseTextDecl(ctxt);
-	/*
-	 * An XML-1.0 document can't reference an entity not XML-1.0
-	 */
-	if ((xmlStrEqual(ctx->version, BAD_CAST "1.0")) &&
-	    (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
-	    xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
-	                   "Version mismatch between document and entity\n");
-	}
-    }
-
-    /*
-     * If the user provided its own SAX callbacks then reuse the
-     * useData callback field, otherwise the expected setup in a
+     * If the user provided their own SAX callbacks, then reuse the
+     * userData callback field, otherwise the expected setup in a
      * DOM builder is to have userData == ctxt
      */
     if (ctx->userData == ctx)
-        ctxt->userData = ctxt;
+        userData = NULL;
     else
-        ctxt->userData = ctx->userData;
-
-    /*
-     * Doing validity checking on chunk doesn't make sense
-     */
-    ctxt->instate = XML_PARSER_CONTENT;
-    ctxt->validate = ctx->validate;
-    ctxt->valid = ctx->valid;
-    ctxt->loadsubset = ctx->loadsubset;
-    ctxt->depth = ctx->depth + 1;
-    ctxt->replaceEntities = ctx->replaceEntities;
-    if (ctxt->validate) {
-	ctxt->vctxt.error = ctx->vctxt.error;
-	ctxt->vctxt.warning = ctx->vctxt.warning;
-    } else {
-	ctxt->vctxt.error = NULL;
-	ctxt->vctxt.warning = NULL;
-    }
-    ctxt->vctxt.nodeTab = NULL;
-    ctxt->vctxt.nodeNr = 0;
-    ctxt->vctxt.nodeMax = 0;
-    ctxt->vctxt.node = NULL;
-    if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
-    ctxt->dict = ctx->dict;
-    ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
-    ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
-    ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
-    ctxt->dictNames = ctx->dictNames;
-    ctxt->attsDefault = ctx->attsDefault;
-    ctxt->attsSpecial = ctx->attsSpecial;
-    ctxt->linenumbers = ctx->linenumbers;
-
-    xmlParseContent(ctxt);
-
-    ctx->validate = ctxt->validate;
-    ctx->valid = ctxt->valid;
-    if ((RAW == '<') && (NXT(1) == '/')) {
-	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
-    } else if (RAW != 0) {
-	xmlFatalErr(ctxt, XML_ERR_EXTRA_CONTENT, NULL);
-    }
-    if (ctxt->node != newDoc->children) {
-	xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
-    }
-
-    if (!ctxt->wellFormed) {
-        if (ctxt->errNo == 0)
-	    ret = 1;
-	else
-	    ret = ctxt->errNo;
-    } else {
-	if (lst != NULL) {
-	    xmlNodePtr cur;
-
-	    /*
-	     * Return the newly created nodeset after unlinking it from
-	     * they pseudo parent.
-	     */
-	    cur = newDoc->children->children;
-	    *lst = cur;
-	    while (cur != NULL) {
-		cur->parent = NULL;
-		cur = cur->next;
-	    }
-            newDoc->children->children = NULL;
-	}
-	ret = 0;
-    }
-    ctxt->sax = oldsax;
-    ctxt->dict = NULL;
-    ctxt->attsDefault = NULL;
-    ctxt->attsSpecial = NULL;
-    xmlFreeParserCtxt(ctxt);
-    newDoc->intSubset = NULL;
-    newDoc->extSubset = NULL;
-    xmlFreeDoc(newDoc);
-
-    return(ret);
+        userData = ctx->userData;
+    return xmlParseExternalEntityPrivate(ctx->myDoc, ctx, ctx->sax,
+                                         userData, ctx->depth + 1,
+                                         URL, ID, lst);
 }
 
 /**
  * xmlParseExternalEntityPrivate:
  * @doc:  the document the chunk pertains to
  * @oldctxt:  the previous parser context if available
- * @sax:  the SAX handler bloc (possibly NULL)
+ * @sax:  the SAX handler block (possibly NULL)
  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
  * @depth:  Used for loop detection, use 0
  * @URL:  the URL for the entity to load
@@ -13117,25 +12942,6 @@
     ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
     ctxt->userData = ctxt;
-    if (oldctxt != NULL) {
-	ctxt->_private = oldctxt->_private;
-	ctxt->loadsubset = oldctxt->loadsubset;
-	ctxt->validate = oldctxt->validate;
-	ctxt->external = oldctxt->external;
-	ctxt->record_info = oldctxt->record_info;
-	ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
-	ctxt->node_seq.length = oldctxt->node_seq.length;
-	ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
-    } else {
-	/*
-	 * Doing validity checking on chunk without context
-	 * doesn't make sense
-	 */
-	ctxt->_private = NULL;
-	ctxt->validate = 0;
-	ctxt->external = 2;
-	ctxt->loadsubset = 0;
-    }
     if (sax != NULL) {
 	oldsax = ctxt->sax;
         ctxt->sax = sax;
@@ -13145,28 +12951,25 @@
     xmlDetectSAX2(ctxt);
     newDoc = xmlNewDoc(BAD_CAST "1.0");
     if (newDoc == NULL) {
-	ctxt->node_seq.maximum = 0;
-	ctxt->node_seq.length = 0;
-	ctxt->node_seq.buffer = NULL;
 	xmlFreeParserCtxt(ctxt);
 	return(XML_ERR_INTERNAL_ERROR);
     }
     newDoc->properties = XML_DOC_INTERNAL;
-    newDoc->intSubset = doc->intSubset;
-    newDoc->extSubset = doc->extSubset;
-    newDoc->dict = doc->dict;
-    xmlDictReference(newDoc->dict);
-
-    if (doc->URL != NULL) {
-	newDoc->URL = xmlStrdup(doc->URL);
+    if (doc) {
+        newDoc->intSubset = doc->intSubset;
+        newDoc->extSubset = doc->extSubset;
+        if (doc->dict) {
+            newDoc->dict = doc->dict;
+            xmlDictReference(newDoc->dict);
+        }
+        if (doc->URL != NULL) {
+            newDoc->URL = xmlStrdup(doc->URL);
+        }
     }
     newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL);
     if (newRoot == NULL) {
 	if (sax != NULL)
 	    ctxt->sax = oldsax;
-	ctxt->node_seq.maximum = 0;
-	ctxt->node_seq.length = 0;
-	ctxt->node_seq.buffer = NULL;
 	xmlFreeParserCtxt(ctxt);
 	newDoc->intSubset = NULL;
 	newDoc->extSubset = NULL;
@@ -13175,8 +12978,12 @@
     }
     xmlAddChild((xmlNodePtr) newDoc, newRoot);
     nodePush(ctxt, newDoc->children);
-    ctxt->myDoc = doc;
-    newRoot->doc = doc;
+    if (doc == NULL) {
+        ctxt->myDoc = newDoc;
+    } else {
+        ctxt->myDoc = doc;
+        newRoot->doc = doc;
+    }
 
     /*
      * Get the 4 first bytes and decode the charset
@@ -13200,10 +13007,53 @@
      */
     if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
 	xmlParseTextDecl(ctxt);
+        /*
+         * An XML-1.0 document can't reference an entity not XML-1.0
+         */
+        if ((xmlStrEqual(oldctxt->version, BAD_CAST "1.0")) &&
+            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
+            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
+                           "Version mismatch between document and entity\n");
+        }
     }
 
     ctxt->instate = XML_PARSER_CONTENT;
     ctxt->depth = depth;
+    if (oldctxt != NULL) {
+	ctxt->_private = oldctxt->_private;
+	ctxt->loadsubset = oldctxt->loadsubset;
+	ctxt->validate = oldctxt->validate;
+	ctxt->valid = oldctxt->valid;
+	ctxt->replaceEntities = oldctxt->replaceEntities;
+        if (oldctxt->validate) {
+            ctxt->vctxt.error = oldctxt->vctxt.error;
+            ctxt->vctxt.warning = oldctxt->vctxt.warning;
+            ctxt->vctxt.userData = oldctxt->vctxt.userData;
+        }
+	ctxt->external = oldctxt->external;
+        if (ctxt->dict) xmlDictFree(ctxt->dict);
+        ctxt->dict = oldctxt->dict;
+        ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3);
+        ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
+        ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
+        ctxt->dictNames = oldctxt->dictNames;
+        ctxt->attsDefault = oldctxt->attsDefault;
+        ctxt->attsSpecial = oldctxt->attsSpecial;
+        ctxt->linenumbers = oldctxt->linenumbers;
+	ctxt->record_info = oldctxt->record_info;
+	ctxt->node_seq.maximum = oldctxt->node_seq.maximum;
+	ctxt->node_seq.length = oldctxt->node_seq.length;
+	ctxt->node_seq.buffer = oldctxt->node_seq.buffer;
+    } else {
+	/*
+	 * Doing validity checking on chunk without context
+	 * doesn't make sense
+	 */
+	ctxt->_private = NULL;
+	ctxt->validate = 0;
+	ctxt->external = 2;
+	ctxt->loadsubset = 0;
+    }
 
     xmlParseContent(ctxt);
 
@@ -13263,6 +13113,11 @@
     if (sax != NULL)
 	ctxt->sax = oldsax;
     if (oldctxt != NULL) {
+        ctxt->dict = NULL;
+        ctxt->attsDefault = NULL;
+        ctxt->attsSpecial = NULL;
+        oldctxt->validate = ctxt->validate;
+        oldctxt->valid = ctxt->valid;
         oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
         oldctxt->node_seq.length = ctxt->node_seq.length;
         oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
@@ -13282,7 +13137,7 @@
 /**
  * xmlParseExternalEntity:
  * @doc:  the document the chunk pertains to
- * @sax:  the SAX handler bloc (possibly NULL)
+ * @sax:  the SAX handler block (possibly NULL)
  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
  * @depth:  Used for loop detection, use 0
  * @URL:  the URL for the entity to load
@@ -13309,7 +13164,7 @@
 /**
  * xmlParseBalancedChunkMemory:
  * @doc:  the document the chunk pertains to
- * @sax:  the SAX handler bloc (possibly NULL)
+ * @sax:  the SAX handler block (possibly NULL)
  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
  * @depth:  Used for loop detection, use 0
  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
@@ -13761,7 +13616,7 @@
 /**
  * xmlParseBalancedChunkMemoryRecover:
  * @doc:  the document the chunk pertains to
- * @sax:  the SAX handler bloc (possibly NULL)
+ * @sax:  the SAX handler block (possibly NULL)
  * @user_data:  The user data returned on SAX callbacks (possibly NULL)
  * @depth:  Used for loop detection, use 0
  * @string:  the input string in UTF8 or ISO-Latin (zero terminated)
@@ -13917,7 +13772,8 @@
     xmlFreeParserCtxt(ctxt);
     newDoc->intSubset = NULL;
     newDoc->extSubset = NULL;
-    newDoc->oldNs = NULL;
+    if(doc != NULL)
+	newDoc->oldNs = NULL;
     xmlFreeDoc(newDoc);
 
     return(ret);
@@ -14026,6 +13882,10 @@
 	ctxt->input_id = pctx->input_id + 1;
     }
 
+    /* Don't read from stdin. */
+    if (xmlStrcmp(URL, BAD_CAST "-") == 0)
+        URL = BAD_CAST "./-";
+
     uri = xmlBuildURI(URL, base);
 
     if (uri == NULL) {
@@ -14726,6 +14586,10 @@
     if (xmlParserInitialized != 0)
 	return;
 
+#if defined(WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+	atexit(xmlCleanupParser);
+#endif
+
 #ifdef LIBXML_THREAD_ENABLED
     __xmlGlobalInitMutexLock();
     if (xmlParserInitialized == 0) {
diff --git a/src/parserInternals.c b/src/parserInternals.c
index 265223b..71b899c 100644
--- a/src/parserInternals.c
+++ b/src/parserInternals.c
@@ -105,7 +105,7 @@
 /**
  * xmlErrMemory:
  * @ctxt:  an XML parser context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a redefinition of attribute error
  */
@@ -165,7 +165,7 @@
  * xmlErrInternal:
  * @ctxt:  an XML parser context
  * @msg:  the error message
- * @str:  error informations
+ * @str:  error information
  *
  * Handle an internal error
  */
@@ -703,7 +703,7 @@
     /*
      * An encoding problem may arise from a truncated input buffer
      * splitting a character in the middle. In that case do not raise
-     * an error but return 0 to endicate an end of stream problem
+     * an error but return 0 to indicate an end of stream problem
      */
     if (ctxt->input->end - ctxt->input->cur < 4) {
 	*len = 0;
@@ -816,7 +816,7 @@
     /*
      * An encoding problem may arise from a truncated input buffer
      * splitting a character in the middle. In that case do not raise
-     * an error but return 0 to endicate an end of stream problem
+     * an error but return 0 to indicate an end of stream problem
      */
     if ((ctxt == NULL) || (ctxt->input == NULL) ||
         (ctxt->input->end - ctxt->input->cur < 4)) {
@@ -1093,7 +1093,7 @@
 	}
     }
     /*
-     * TODO: We could recover from errors in external entites if we
+     * TODO: We could recover from errors in external entities if we
      * didn't stop the parser. But most callers of this function don't
      * check the return value.
      */
@@ -1138,7 +1138,7 @@
     if (input->buf != NULL) {
         if (input->buf->encoder != NULL) {
             /*
-             * Check in case the auto encoding detetection triggered
+             * Check in case the auto encoding detection triggered
              * in already.
              */
             if (input->buf->encoder == handler)
@@ -1882,7 +1882,7 @@
 
 /************************************************************************
  *									*
- *		Handling of node informations				*
+ *		Handling of node information				*
  *									*
  ************************************************************************/
 
diff --git a/src/pattern.c b/src/pattern.c
index 0eb8d81..27e9694 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -1,5 +1,5 @@
 /*
- * pattern.c: Implemetation of selectors for nodes
+ * pattern.c: Implementation of selectors for nodes
  *
  * Reference:
  *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
@@ -55,7 +55,7 @@
 /*
 * NOTE: Those private flags (XML_STREAM_xxx) are used
 *   in _xmlStreamCtxt->flag. They extend the public
-*   xmlPatternFlags, so be carefull not to interfere with the
+*   xmlPatternFlags, so be careful not to interfere with the
 *   reserved values for xmlPatternFlags.
 */
 #define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
@@ -229,13 +229,16 @@
  */
 void
 xmlFreePattern(xmlPatternPtr comp) {
+    xmlFreePatternList(comp);
+}
+
+static void
+xmlFreePatternInternal(xmlPatternPtr comp) {
     xmlStepOpPtr op;
     int i;
 
     if (comp == NULL)
 	return;
-    if (comp->next != NULL)
-        xmlFreePattern(comp->next);
     if (comp->stream != NULL)
         xmlFreeStreamComp(comp->stream);
     if (comp->pattern != NULL)
@@ -273,7 +276,7 @@
 	cur = comp;
 	comp = comp->next;
 	cur->next = NULL;
-	xmlFreePattern(cur);
+	xmlFreePatternInternal(cur);
     }
 }
 
@@ -742,7 +745,7 @@
  * xmlPatScanLiteral:
  * @ctxt:  the XPath Parser context
  *
- * Parse an XPath Litteral:
+ * Parse an XPath Literal:
  *
  * [29] Literal ::= '"' [^"]* '"'
  *                | "'" [^']* "'"
@@ -1973,7 +1976,7 @@
 	    } else {
 		/*
 		* If there are "//", then we need to process every "//"
-		* occuring in the states, plus any other state for this
+		* occurring in the states, plus any other state for this
 		* level.
 		*/
 		stepNr = stream->states[2 * i];
diff --git a/src/runsuite.c b/src/runsuite.c
index 767455b..d24b5ec 100644
--- a/src/runsuite.c
+++ b/src/runsuite.c
@@ -1,5 +1,5 @@
 /*
- * runsuite.c: C program to run libxml2 againts published testsuites
+ * runsuite.c: C program to run libxml2 against published testsuites
  *
  * See Copyright for the status of this software.
  *
@@ -217,13 +217,13 @@
     * Deactivate the cache if created; otherwise we have to create/free it
     * for every test, since it will confuse the memory leak detection.
     * Note that normally this need not be done, since the cache is not
-    * created until set explicitely with xmlXPathContextSetCache();
-    * but for test purposes it is sometimes usefull to activate the
+    * created until set explicitly with xmlXPathContextSetCache();
+    * but for test purposes it is sometimes useful to activate the
     * cache by default for the whole library.
     */
     if (ctxtXPath->cache != NULL)
 	xmlXPathContextSetCache(ctxtXPath, 0, -1, 0);
-    /* used as default nanemspace in xstc tests */
+    /* used as default namespace in xstc tests */
     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "ts", BAD_CAST "TestSuite");
     xmlXPathRegisterNs(ctxtXPath, BAD_CAST "xlink",
                        BAD_CAST "http://www.w3.org/1999/xlink");
@@ -296,7 +296,7 @@
  ************************************************************************/
 
 static int
-xsdIncorectTestCase(xmlNodePtr cur) {
+xsdIncorrectTestCase(xmlNodePtr cur) {
     xmlNodePtr test;
     xmlBufferPtr buf;
     xmlRelaxNGParserCtxtPtr pctxt;
@@ -332,7 +332,7 @@
     rng = xmlRelaxNGParse(pctxt);
     xmlRelaxNGFreeParserCtxt(pctxt);
     if (rng != NULL) {
-	test_log("Failed to detect incorect RNG line %ld\n",
+	test_log("Failed to detect incorrect RNG line %ld\n",
 		    xmlGetLineNo(test));
         ret = 1;
 	goto done;
@@ -438,7 +438,7 @@
 
     cur = getNext(tst, "./correct[1]");
     if (cur == NULL) {
-        return(xsdIncorectTestCase(tst));
+        return(xsdIncorrectTestCase(tst));
     }
 
     test = getNext(cur, "./*");
diff --git a/src/runtest.c b/src/runtest.c
index b1c30d8..dc5e09a 100644
--- a/src/runtest.c
+++ b/src/runtest.c
@@ -1,6 +1,6 @@
 /*
  * runtest.c: C program to run libxml2 regression tests without
- *            requiring make or Python, and reducing platform dependancies
+ *            requiring make or Python, and reducing platform dependencies
  *            to a strict minimum.
  *
  * To compile on Unixes:
@@ -95,7 +95,7 @@
 typedef struct testDesc testDesc;
 typedef testDesc *testDescPtr;
 struct testDesc {
-    const char *desc; /* descripton of the test */
+    const char *desc; /* description of the test */
     functest    func; /* function implementing the test */
     const char *in;   /* glob to path for input files */
     const char *out;  /* output directory */
@@ -880,6 +880,8 @@
     callbacks++;
     if (quiet)
 	return;
+    if (name == NULL)
+        name = BAD_CAST "(null)";
     fprintf(SAXdebug, "SAX.internalSubset(%s,", name);
     if (ExternalID == NULL)
 	fprintf(SAXdebug, " ,");
@@ -3391,7 +3393,7 @@
 	}
 	reader = xmlReaderForFile(instance, NULL, options);
 	if (reader == NULL) {
-	    fprintf(stderr, "Failed to build reder for %s\n", instance);
+	    fprintf(stderr, "Failed to build reader for %s\n", instance);
 	}
 	if (disable_err == 1)
 	    ret = streamProcessTest(instance, result, NULL, reader, filename,
@@ -4246,6 +4248,9 @@
     { "Error cases regression tests",
       errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
       0 },
+    { "Error cases regression tests with entity substitution",
+      errParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".ent",
+      XML_PARSE_NOENT },
     { "Error cases regression tests (old 1.0)",
       errParseTest, "./test/errors10/*.xml", "result/errors10/", "", ".err",
       XML_PARSE_OLD10 },
@@ -4547,6 +4552,10 @@
     setvbuf(stderr, NULL, _IONBF, 0);
 #endif
 
+#if defined(_MSC_VER) && _MSC_VER >= 1400 && _MSC_VER < 1900
+    _set_output_format(_TWO_DIGIT_EXPONENT);
+#endif
+
     initializeLibxml2();
 
     for (a = 1; a < argc;a++) {
diff --git a/src/runxmlconf.c b/src/runxmlconf.c
index cef20f4..8a37aa8 100644
--- a/src/runxmlconf.c
+++ b/src/runxmlconf.c
@@ -1,5 +1,5 @@
 /*
- * runsuite.c: C program to run libxml2 againts published testsuites
+ * runxmlconf.c: C program to run XML W3C conformance testsuites
  *
  * See Copyright for the status of this software.
  *
@@ -164,8 +164,8 @@
     * Deactivate the cache if created; otherwise we have to create/free it
     * for every test, since it will confuse the memory leak detection.
     * Note that normally this need not be done, since the cache is not
-    * created until set explicitely with xmlXPathContextSetCache();
-    * but for test purposes it is sometimes usefull to activate the
+    * created until set explicitly with xmlXPathContextSetCache();
+    * but for test purposes it is sometimes useful to activate the
     * cache by default for the whole library.
     */
     if (ctxtXPath->cache != NULL)
@@ -248,7 +248,7 @@
 
     /*
      * In case of Namespace errors, libxml2 will still parse the document
-     * but log a Namesapce error.
+     * but log a Namespace error.
      */
     doc = xmlReadFile(filename, NULL, options);
     if (doc == NULL) {
@@ -507,7 +507,7 @@
     fprintf(stderr, "  you need to fetch and extract the\n");
     fprintf(stderr, "  latest XML Conformance Test Suites\n");
     fprintf(stderr, "  http://www.w3.org/XML/Test/xmlts20080827.tar.gz\n");
-    fprintf(stderr, "  see http://www.w3.org/XML/Test/ for informations\n");
+    fprintf(stderr, "  see http://www.w3.org/XML/Test/ for information\n");
 }
 
 static int
diff --git a/src/save.h b/src/save.h
index 2c32a10..192b674 100644
--- a/src/save.h
+++ b/src/save.h
@@ -1,7 +1,7 @@
 /*
  * Summary: Internal Interfaces for saving in libxml2
  * Description: this module describes a few interfaces which were
- *              addded along with the API changes in 2.9.0
+ *              added along with the API changes in 2.9.0
  *              those are private routines at this point
  *
  * Copy: See Copyright for the status of this software.
@@ -25,9 +25,10 @@
 void xmlBufDumpElementDecl(xmlBufPtr buf, xmlElementPtr elem);
 void xmlBufDumpAttributeDecl(xmlBufPtr buf, xmlAttributePtr attr);
 void xmlBufDumpEntityDecl(xmlBufPtr buf, xmlEntityPtr ent);
-xmlChar *xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
 #endif
 
+xmlChar *xmlEncodeAttributeEntities(xmlDocPtr doc, const xmlChar *input);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/testAutomata.c b/src/testAutomata.c
index 6c4de90..13213c6 100644
--- a/src/testAutomata.c
+++ b/src/testAutomata.c
@@ -1,5 +1,5 @@
 /*
- * testRegexp.c: simple module for testing regular expressions
+ * testAutomata.c: simple module for testing regexp automata
  *
  * See Copyright for the status of this software.
  *
diff --git a/src/testReader.c b/src/testReader.c
index 8f8e26d..da2f1b0 100644
--- a/src/testReader.c
+++ b/src/testReader.c
@@ -1,5 +1,5 @@
 /*
- * testSAX.c : a small tester program for parsing using the SAX API.
+ * testReader.c : a small tester program for parsing using the xmlReader
  *
  * See Copyright for the status of this software.
  *
diff --git a/src/testRegexp.c b/src/testRegexp.c
index 21dac94..2181741 100644
--- a/src/testRegexp.c
+++ b/src/testRegexp.c
@@ -185,20 +185,19 @@
 testReduce(xmlExpCtxtPtr ctxt, xmlExpNodePtr expr, const char *tst) {
     xmlBufferPtr xmlExpBuf;
     xmlExpNodePtr sub, deriv;
-    xmlExpBuf = xmlBufferCreate();
 
     sub = xmlExpParse(ctxt, tst);
     if (sub == NULL) {
         printf("Subset %s failed to parse\n", tst);
 	return;
     }
+    xmlExpBuf = xmlBufferCreate();
     xmlExpDump(xmlExpBuf, sub);
     printf("Subset parsed as: %s\n",
            (const char *) xmlBufferContent(xmlExpBuf));
     deriv = xmlExpExpDerive(ctxt, expr, sub);
     if (deriv == NULL) {
         printf("Derivation led to an internal error, report this !\n");
-	return;
     } else {
         xmlBufferEmpty(xmlExpBuf);
 	xmlExpDump(xmlExpBuf, deriv);
@@ -210,6 +209,7 @@
 	           (const char *) xmlBufferContent(xmlExpBuf));
 	xmlExpFree(ctxt, deriv);
     }
+    xmlBufferFree(xmlExpBuf);
     xmlExpFree(ctxt, sub);
 }
 
diff --git a/src/testapi.c b/src/testapi.c
index 980d7fb..8a4e23e 100644
--- a/src/testapi.c
+++ b/src/testapi.c
@@ -5450,7 +5450,7 @@
     int n_with_comments;
     const char * filename; /* the filename to store canonical XML image */
     int n_filename;
-    int compression; /* the compression level (zlib requred): -1 - libxml default, 0 - uncompressed, >0 - compression level */
+    int compression; /* the compression level (zlib required): -1 - libxml default, 0 - uncompressed, >0 - compression level */
     int n_compression;
 
     for (n_doc = 0;n_doc < gen_nb_xmlDocPtr;n_doc++) {
@@ -8693,7 +8693,7 @@
 
     int mem_base;
     int ret_val;
-    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    xmlCharEncodingHandler * handler; /* char encoding transformation data structure */
     int n_handler;
 
     for (n_handler = 0;n_handler < gen_nb_xmlCharEncodingHandler_ptr;n_handler++) {
@@ -8725,7 +8725,7 @@
 
     int mem_base;
     int ret_val;
-    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    xmlCharEncodingHandler * handler; /* char encoding transformation data structure */
     int n_handler;
     xmlBufferPtr out; /* an xmlBuffer for the output. */
     int n_out;
@@ -8817,7 +8817,7 @@
 
     int mem_base;
     int ret_val;
-    xmlCharEncodingHandler * handler; /* char enconding transformation data structure */
+    xmlCharEncodingHandler * handler; /* char encoding transformation data structure */
     int n_handler;
     xmlBufferPtr out; /* an xmlBuffer for the output. */
     int n_out;
@@ -13613,7 +13613,7 @@
     int ret_val;
     xmlDocPtr doc; /* the document the chunk pertains to */
     int n_doc;
-    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    xmlSAXHandlerPtr sax; /* the SAX handler block (possibly NULL) */
     int n_sax;
     void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
     int n_user_data;
@@ -13689,7 +13689,7 @@
     int ret_val;
     xmlDocPtr doc; /* the document the chunk pertains to */
     int n_doc;
-    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    xmlSAXHandlerPtr sax; /* the SAX handler block (possibly NULL) */
     int n_sax;
     void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
     int n_user_data;
@@ -14065,7 +14065,7 @@
     int ret_val;
     xmlDocPtr doc; /* the document the chunk pertains to */
     int n_doc;
-    xmlSAXHandlerPtr sax; /* the SAX handler bloc (possibly NULL) */
+    xmlSAXHandlerPtr sax; /* the SAX handler block (possibly NULL) */
     int n_sax;
     void * user_data; /* The user data returned on SAX callbacks (possibly NULL) */
     int n_user_data;
@@ -16158,7 +16158,7 @@
     int mem_base;
     xmlParserCtxtPtr ctxt; /* an XML parser context */
     int n_ctxt;
-    char * extra; /* extra informations */
+    char * extra; /* extra information */
     int n_extra;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
@@ -18195,7 +18195,7 @@
     int ret_val;
     xmlSchematronValidCtxtPtr ctxt; /* the schema validation context */
     int n_ctxt;
-    xmlDocPtr instance; /* the document instace tree */
+    xmlDocPtr instance; /* the document instance tree */
     int n_instance;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_xmlSchematronValidCtxtPtr;n_ctxt++) {
@@ -23268,7 +23268,7 @@
     int n_buf;
     xmlDocPtr cur; /* the document */
     int n_cur;
-    char * encoding; /* the encoding if any assuming the I/O layer handles the trancoding */
+    char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
     int n_encoding;
 
     for (n_buf = 0;n_buf < gen_nb_xmlOutputBufferPtr;n_buf++) {
@@ -23420,7 +23420,7 @@
     int n_buf;
     xmlDocPtr cur; /* the document */
     int n_cur;
-    char * encoding; /* the encoding if any assuming the I/O layer handles the trancoding */
+    char * encoding; /* the encoding if any assuming the I/O layer handles the transcoding */
     int n_encoding;
     int format; /* should formatting spaces been added */
     int n_format;
@@ -46663,7 +46663,7 @@
     int n_ctxt;
     int active; /* enables/disables (creates/frees) the cache */
     int n_active;
-    int value; /* a value with semantics dependant on @options */
+    int value; /* a value with semantics dependent on @options */
     int n_value;
     int options; /* options (currently only the value 0 is used) */
     int n_options;
diff --git a/src/testchar.c b/src/testchar.c
index 0d08792..6866a17 100644
--- a/src/testchar.c
+++ b/src/testchar.c
@@ -120,7 +120,7 @@
 	}
 
 	/*
-	 * We should see no error in remaning cases
+	 * We should see no error in remaining cases
 	 */
 	else if ((lastError != 0) || (res == NULL)) {
 	    fprintf(stderr,
@@ -324,7 +324,7 @@
 	    }
 
             /*
-	     * We should see no error in remaning cases
+	     * We should see no error in remaining cases
 	     */
 	    else if ((lastError != 0) || (len != 2)) {
 		fprintf(stderr,
diff --git a/src/testlimits.c b/src/testlimits.c
index 68c94db..059116a 100644
--- a/src/testlimits.c
+++ b/src/testlimits.c
@@ -1403,7 +1403,7 @@
 typedef struct testDesc testDesc;
 typedef testDesc *testDescPtr;
 struct testDesc {
-    const char *desc; /* descripton of the test */
+    const char *desc; /* description of the test */
     functest    func; /* function implementing the test */
 };
 
diff --git a/src/testrecurse.c b/src/testrecurse.c
index 64b9cd0..0cbe25a 100644
--- a/src/testrecurse.c
+++ b/src/testrecurse.c
@@ -44,7 +44,7 @@
 typedef struct testDesc testDesc;
 typedef testDesc *testDescPtr;
 struct testDesc {
-    const char *desc; /* descripton of the test */
+    const char *desc; /* description of the test */
     functest    func; /* function implementing the test */
     const char *in;   /* glob to path for input files */
     const char *out;  /* output directory */
diff --git a/src/threads.c b/src/threads.c
index 0433ac0..503d2bf 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -82,7 +82,7 @@
 
 /*
  * TODO: this module still uses malloc/free and not xmlMalloc/xmlFree
- *       to avoid some crazyness since xmlMalloc/xmlFree may actually
+ *       to avoid some craziness since xmlMalloc/xmlFree may actually
  *       be hosted on allocated blocks needing them for the allocation ...
  */
 
@@ -239,7 +239,7 @@
     if (acquire_sem(tok->sem) != B_NO_ERROR) {
 #ifdef DEBUG_THREADS
         xmlGenericError(xmlGenericErrorContext,
-                        "xmlMutexLock():BeOS:Couldn't aquire semaphore\n");
+                        "xmlMutexLock():BeOS:Couldn't acquire semaphore\n");
 #endif
     }
     tok->tid = find_thread(NULL);
@@ -885,8 +885,6 @@
         }
     }
 #endif /* XML_PTHREAD_WEAK */
-#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
-    InitializeCriticalSection(&cleanup_helpers_cs);
 #endif
 }
 
@@ -958,6 +956,9 @@
     if (!run_once.done) {
         if (InterlockedIncrement(&run_once.control) == 1) {
 #if !defined(HAVE_COMPILER_TLS)
+#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
+            InitializeCriticalSection(&cleanup_helpers_cs);
+#endif
             globalkey = TlsAlloc();
 #endif
             mainthread = GetCurrentThreadId();
diff --git a/src/timsort.h b/src/timsort.h
index 0c6346b..383584f 100644
--- a/src/timsort.h
+++ b/src/timsort.h
@@ -59,7 +59,7 @@
 #define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;}
 
 
-/* Common, type-agnosting functions and constants that we don't want to declare twice. */
+/* Common, type-agnostic functions and constants that we don't want to declare twice. */
 #ifndef SORT_COMMON_H
 #define SORT_COMMON_H
 
@@ -74,7 +74,7 @@
 static int compute_minrun(const uint64_t);
 
 #ifndef CLZ
-#ifdef __GNUC__
+#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 3))
 #define CLZ __builtin_clzll
 #else
 
@@ -404,7 +404,8 @@
     j = curr + A;
     k = curr + A + B;
 
-    while (k-- > curr) {
+    while (k > curr) {
+      k--;
       if ((i > 0) && (j > curr)) {
         if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) {
           dst[k] = dst[--j];
diff --git a/src/tree.c b/src/tree.c
index 959421b..64572d9 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -59,7 +59,7 @@
  ************************************************************************/
 
 static xmlNsPtr
-xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
+xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
 
 static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
 
@@ -70,7 +70,7 @@
  ************************************************************************/
 /**
  * xmlTreeErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -83,7 +83,7 @@
 /**
  * xmlTreeErr:
  * @code:  the error number
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -181,7 +181,7 @@
  * @dtd:  A pointer to the DTD to search
  * @name:  The entity name
  *
- * Do an entity lookup in the DTD pararmeter entity hash table and
+ * Do an entity lookup in the DTD parameter entity hash table and
  * return the corresponding entity, if found.
  *
  * Returns A pointer to the entity structure or NULL if not found.
@@ -1064,7 +1064,7 @@
  * @str:  a string
  *
  * Copy a string using a "dict" dictionary in the current scope,
- * if availabe.
+ * if available.
  */
 #define DICT_COPY(str, cpy) \
     if (str) { \
@@ -1081,7 +1081,7 @@
  * @str:  a string
  *
  * Copy a string using a "dict" dictionary in the current scope,
- * if availabe.
+ * if available.
  */
 #define DICT_CONST_COPY(str, cpy) \
     if (str) { \
@@ -1276,12 +1276,14 @@
     xmlNodePtr ret = NULL, last = NULL;
     xmlNodePtr node;
     xmlChar *val;
-    const xmlChar *cur = value, *end = cur + len;
+    const xmlChar *cur, *end;
     const xmlChar *q;
     xmlEntityPtr ent;
     xmlBufPtr buf;
 
     if (value == NULL) return(NULL);
+    cur = value;
+    end = cur + len;
 
     buf = xmlBufCreateSize(0);
     if (buf == NULL) return(NULL);
@@ -2950,7 +2952,7 @@
  * Add a new attribute after @prev using @cur as base attribute.
  * When inserting before @cur, @prev is passed as @cur->prev.
  * When inserting after @cur, @prev is passed as @cur.
- * If an existing attribute is found it is detroyed prior to adding @prop.
+ * If an existing attribute is found it is destroyed prior to adding @prop.
  *
  * Returns the attribute being inserted or NULL in case of error.
  */
@@ -3664,7 +3666,9 @@
 void
 xmlFreeNodeList(xmlNodePtr cur) {
     xmlNodePtr next;
+    xmlNodePtr parent;
     xmlDictPtr dict = NULL;
+    size_t depth = 0;
 
     if (cur == NULL) return;
     if (cur->type == XML_NAMESPACE_DECL) {
@@ -3680,16 +3684,21 @@
 	return;
     }
     if (cur->doc != NULL) dict = cur->doc->dict;
-    while (cur != NULL) {
+    while (1) {
+        while ((cur->children != NULL) &&
+               (cur->type != XML_DTD_NODE) &&
+               (cur->type != XML_ENTITY_REF_NODE)) {
+            cur = cur->children;
+            depth += 1;
+        }
+
         next = cur->next;
+        parent = cur->parent;
 	if (cur->type != XML_DTD_NODE) {
 
 	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 		xmlDeregisterNodeDefaultValue(cur);
 
-	    if ((cur->children != NULL) &&
-		(cur->type != XML_ENTITY_REF_NODE))
-		xmlFreeNodeList(cur->children);
 	    if (((cur->type == XML_ELEMENT_NODE) ||
 		 (cur->type == XML_XINCLUDE_START) ||
 		 (cur->type == XML_XINCLUDE_END)) &&
@@ -3699,6 +3708,11 @@
 		(cur->type != XML_XINCLUDE_START) &&
 		(cur->type != XML_XINCLUDE_END) &&
 		(cur->type != XML_ENTITY_REF_NODE) &&
+		(cur->type != XML_DOCUMENT_NODE) &&
+#ifdef LIBXML_DOCB_ENABLED
+		(cur->type != XML_DOCB_DOCUMENT_NODE) &&
+#endif
+		(cur->type != XML_HTML_DOCUMENT_NODE) &&
 		(cur->content != (xmlChar *) &(cur->properties))) {
 		DICT_FREE(cur->content)
 	    }
@@ -3720,7 +3734,16 @@
 		DICT_FREE(cur->name)
 	    xmlFree(cur);
 	}
-	cur = next;
+
+        if (next != NULL) {
+	    cur = next;
+        } else {
+            if ((depth == 0) || (parent == NULL))
+                break;
+            depth -= 1;
+            cur = parent;
+            cur->children = NULL;
+        }
     }
 }
 
@@ -4050,7 +4073,7 @@
       } else {
         /*
          * we have to find something appropriate here since
-         * we cant be sure, that the namespce we found is identified
+         * we can't be sure, that the namespace we found is identified
          * by the prefix
          */
         if (xmlStrEqual(ns->href, cur->ns->href)) {
@@ -4058,10 +4081,10 @@
           ret->ns = ns;
         } else {
           /*
-           * we are in trouble: we need a new reconcilied namespace.
+           * we are in trouble: we need a new reconciled namespace.
            * This is expensive
            */
-          ret->ns = xmlNewReconciliedNs(target->doc, target, cur->ns);
+          ret->ns = xmlNewReconciledNs(target->doc, target, cur->ns);
         }
       }
 
@@ -4154,8 +4177,8 @@
  * say RPM:Copyright without changing the namespace pointer to
  * something else can produce stale links. One way to do it is
  * to keep a reference counter but this doesn't work as soon
- * as one move the element or the subtree out of the scope of
- * the existing namespace. The actual solution seems to add
+ * as one moves the element or the subtree out of the scope of
+ * the existing namespace. The actual solution seems to be to add
  * a copy of the namespace at the top of the copied tree if
  * not available in the subtree.
  * Hence two functions, the public front-end call the inner ones
@@ -4280,7 +4303,7 @@
 		while (root->parent != NULL) root = root->parent;
 		ret->ns = xmlNewNs(root, ns->href, ns->prefix);
 		} else {
-			ret->ns = xmlNewReconciliedNs(doc, ret, node->ns);
+			ret->ns = xmlNewReconciledNs(doc, ret, node->ns);
 	    }
 	} else {
 	    /*
@@ -4719,7 +4742,7 @@
 
             /*
              * Thumbler index computation
-	     * TODO: the ocurence test seems bogus for namespaced names
+	     * TODO: the occurrence test seems bogus for namespaced names
              */
             tmp = cur->prev;
             while (tmp != NULL) {
@@ -6214,7 +6237,7 @@
 }
 
 /**
- * xmlNewReconciliedNs:
+ * xmlNewReconciledNs:
  * @doc:  the document
  * @tree:  a node expected to hold the new namespace
  * @ns:  the original namespace
@@ -6227,7 +6250,7 @@
  * Returns the (new) namespace definition or NULL in case of error
  */
 static xmlNsPtr
-xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
+xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
     xmlNsPtr def;
     xmlChar prefix[50];
     int counter = 1;
@@ -6235,14 +6258,14 @@
     if ((tree == NULL) || (tree->type != XML_ELEMENT_NODE)) {
 #ifdef DEBUG_TREE
         xmlGenericError(xmlGenericErrorContext,
-		"xmlNewReconciliedNs : tree == NULL\n");
+		"xmlNewReconciledNs : tree == NULL\n");
 #endif
 	return(NULL);
     }
     if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
 #ifdef DEBUG_TREE
         xmlGenericError(xmlGenericErrorContext,
-		"xmlNewReconciliedNs : ns == NULL\n");
+		"xmlNewReconciledNs : ns == NULL\n");
 #endif
 	return(NULL);
     }
@@ -6344,7 +6367,7 @@
 	        /*
 		 * OK we need to recreate a new namespace definition
 		 */
-		n = xmlNewReconciliedNs(doc, tree, node->ns);
+		n = xmlNewReconciledNs(doc, tree, node->ns);
 		if (n != NULL) { /* :-( what if else ??? */
 		    /*
 		     * check if we need to grow the cache buffers.
@@ -6373,7 +6396,7 @@
 	    }
 	}
 	/*
-	 * now check for namespace hold by attributes on the node.
+	 * now check for namespace held by attributes on the node.
 	 */
 	if (node->type == XML_ELEMENT_NODE) {
 	    attr = node->properties;
@@ -6408,7 +6431,7 @@
 			/*
 			 * OK we need to recreate a new namespace definition
 			 */
-			n = xmlNewReconciliedNs(doc, tree, attr->ns);
+			n = xmlNewReconciledNs(doc, tree, attr->ns);
 			if (n != NULL) { /* :-( what if else ??? */
 			    /*
 			     * check if we need to grow the cache buffers.
@@ -7227,7 +7250,7 @@
         ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
 	/*
 	 * we just move the content pointer, but also make sure
-	 * the perceived buffer size has shrinked accordingly
+	 * the perceived buffer size has shrunk accordingly
 	 */
         buf->content += len;
 	buf->size -= len;
@@ -7401,12 +7424,17 @@
     if (size < buf->size)
         return 1;
 
+    if (size > UINT_MAX - 10) {
+        xmlTreeErrMemory("growing buffer");
+        return 0;
+    }
+
     /* figure out new size */
     switch (buf->alloc){
 	case XML_BUFFER_ALLOC_IO:
 	case XML_BUFFER_ALLOC_DOUBLEIT:
 	    /*take care of empty case*/
-	    newSize = (buf->size ? buf->size*2 : size + 10);
+	    newSize = (buf->size ? buf->size : size + 10);
 	    while (size > newSize) {
 	        if (newSize > UINT_MAX / 2) {
 	            xmlTreeErrMemory("growing buffer");
@@ -7422,7 +7450,7 @@
             if (buf->use < BASE_BUFFER_SIZE)
                 newSize = size;
             else {
-                newSize = buf->size * 2;
+                newSize = buf->size;
                 while (size > newSize) {
                     if (newSize > UINT_MAX / 2) {
                         xmlTreeErrMemory("growing buffer");
@@ -7579,7 +7607,7 @@
 
 	if (start_buf > (unsigned int) len) {
 	    /*
-	     * We can add it in the space previously shrinked
+	     * We can add it in the space previously shrunk
 	     */
 	    buf->content -= len;
             memmove(&buf->content[0], str, len);
@@ -7961,7 +7989,7 @@
 * Creates or reuses an xmlNs struct on doc->oldNs with
 * the given prefix and namespace name.
 *
-* Returns the aquired ns struct or NULL in case of an API
+* Returns the acquired ns struct or NULL in case of an API
 *         or internal error.
 */
 static xmlNsPtr
@@ -8575,7 +8603,7 @@
 }
 
 /*
-* xmlDOMWrapNSNormAquireNormalizedNs:
+* xmlDOMWrapNSNormAcquireNormalizedNs:
 * @doc: the doc
 * @elem: the element-node to declare namespaces on
 * @ns: the ns-struct to use for the search
@@ -8594,7 +8622,7 @@
 * Returns 0 if succeeded, -1 otherwise and on API/internal errors.
 */
 static int
-xmlDOMWrapNSNormAquireNormalizedNs(xmlDocPtr doc,
+xmlDOMWrapNSNormAcquireNormalizedNs(xmlDocPtr doc,
 				   xmlNodePtr elem,
 				   xmlNsPtr ns,
 				   xmlNsPtr *retNs,
@@ -8893,9 +8921,9 @@
 		    }
 		}
 		/*
-		* Aquire a normalized ns-decl and add it to the map.
+		* Acquire a normalized ns-decl and add it to the map.
 		*/
-		if (xmlDOMWrapNSNormAquireNormalizedNs(doc, curElem,
+		if (xmlDOMWrapNSNormAcquireNormalizedNs(doc, curElem,
 			cur->ns, &ns,
 			&nsMap, depth,
 			ancestorsOnly,
@@ -9033,7 +9061,7 @@
 	nsMap = (xmlNsMapPtr) ctxt->namespaceMap;
     /*
     * Disable search for ns-decls in the parent-axis of the
-    * desination element, if:
+    * destination element, if:
     * 1) there's no destination parent
     * 2) custom ns-reference handling is used
     */
@@ -9178,9 +9206,9 @@
 		    cur->ns = ns;
 		} else {
 		    /*
-		    * Aquire a normalized ns-decl and add it to the map.
+		    * Acquire a normalized ns-decl and add it to the map.
 		    */
-		    if (xmlDOMWrapNSNormAquireNormalizedNs(destDoc,
+		    if (xmlDOMWrapNSNormAcquireNormalizedNs(destDoc,
 			/* ns-decls on curElem or on destDoc->oldNs */
 			destParent ? curElem : NULL,
 			cur->ns, &ns,
@@ -9234,7 +9262,7 @@
 		goto leave_node;
 	    case XML_ENTITY_REF_NODE:
 		/*
-		* Remove reference to the entitity-node.
+		* Remove reference to the entity-node.
 		*/
 		cur->content = NULL;
 		cur->children = NULL;
@@ -9468,7 +9496,7 @@
 		}
 		memset(clone, 0, sizeof(xmlNode));
 		/*
-		* Set hierachical links.
+		* Set hierarchical links.
 		*/
 		if (resultClone != NULL) {
 		    clone->parent = parentClone;
@@ -9492,7 +9520,7 @@
 		}
 		memset(clone, 0, sizeof(xmlAttr));
 		/*
-		* Set hierachical links.
+		* Set hierarchical links.
 		* TODO: Change this to add to the end of attributes.
 		*/
 		if (resultClone != NULL) {
@@ -9720,9 +9748,9 @@
 	    clone->ns = ns;
 	} else {
 	    /*
-	    * Aquire a normalized ns-decl and add it to the map.
+	    * Acquire a normalized ns-decl and add it to the map.
 	    */
-	    if (xmlDOMWrapNSNormAquireNormalizedNs(destDoc,
+	    if (xmlDOMWrapNSNormAcquireNormalizedNs(destDoc,
 		/* ns-decls on curElem or on destDoc->oldNs */
 		destParent ? curElem : NULL,
 		cur->ns, &ns,
@@ -9959,7 +9987,7 @@
 		break;
 	    case XML_ENTITY_REF_NODE:
 		/*
-		* Remove reference to the entitity-node.
+		* Remove reference to the entity-node.
 		*/
 		cur->content = NULL;
 		cur->children = NULL;
@@ -10097,7 +10125,7 @@
 		    break;
 	    case XML_ENTITY_REF_NODE:
 		/*
-		* Remove reference to the entitity-node.
+		* Remove reference to the entity-node.
 		*/
 		node->content = NULL;
 		node->children = NULL;
diff --git a/src/triodef.h b/src/triodef.h
index 46772ee..e101f6d 100644
--- a/src/triodef.h
+++ b/src/triodef.h
@@ -10,7 +10,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  ************************************************************************/
diff --git a/src/trionan.c b/src/trionan.c
index 6fbabb5..8767a9f 100644
--- a/src/trionan.c
+++ b/src/trionan.c
@@ -10,7 +10,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  ************************************************************************
@@ -92,7 +92,7 @@
 
 /*
  * In ANSI/IEEE 754-1985 64-bits double format numbers have the
- * following properties (amoungst others)
+ * following properties (amongst others)
  *
  *   o FLT_RADIX == 2: binary encoding
  *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
@@ -123,8 +123,8 @@
  * integer, becomes 0x0706050403020100 (we could have used a 64-bit
  * integer value instead of a double, but not all platforms supports
  * that type). The value is automatically encoded with the correct
- * endianess by the compiler, which means that we can support any
- * kind of endianess. The individual bytes are then used as an index
+ * endianness by the compiler, which means that we can support any
+ * kind of endianness. The individual bytes are then used as an index
  * for the IEEE 754 bit-patterns and masks.
  */
 #define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
diff --git a/src/trionan.h b/src/trionan.h
index be6e718..eac0e6f 100644
--- a/src/trionan.h
+++ b/src/trionan.h
@@ -10,7 +10,7 @@
  *
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
  *
  ************************************************************************/
diff --git a/src/uri.c b/src/uri.c
index d4f0f5e..91c4619 100644
--- a/src/uri.c
+++ b/src/uri.c
@@ -22,7 +22,7 @@
  * MAX_URI_LENGTH:
  *
  * The definition of the URI regexp in the above RFC has no size limit
- * In practice they are usually relativey short except for the
+ * In practice they are usually relatively short except for the
  * data URI scheme as defined in RFC 2397. Even for data URI the usual
  * maximum size before hitting random practical limits is around 64 KB
  * and 4KB is usually a maximum admitted limit for proper operations.
@@ -325,16 +325,18 @@
 xmlParse3986Port(xmlURIPtr uri, const char **str)
 {
     const char *cur = *str;
-    unsigned port = 0; /* unsigned for defined overflow behavior */
+    int port = 0;
 
     if (ISA_DIGIT(cur)) {
 	while (ISA_DIGIT(cur)) {
 	    port = port * 10 + (*cur - '0');
+            if (port > 99999999)
+                port = 99999999;
 
 	    cur++;
 	}
 	if (uri != NULL)
-	    uri->port = port & USHRT_MAX; /* port value modulo USHRT_MAX+1 */
+	    uri->port = port;
 	*str = cur;
 	return(0);
     }
@@ -346,7 +348,7 @@
  * @uri:  pointer to an URI structure
  * @str:  the string to analyze
  *
- * Parse an user informations part and fills in the appropriate fields
+ * Parse an user information part and fills in the appropriate fields
  * of the @uri structure
  *
  * userinfo      = *( unreserved / pct-encoded / sub-delims / ":" )
@@ -436,7 +438,7 @@
 
     host = cur;
     /*
-     * IPv6 and future adressing scheme are enclosed between brackets
+     * IPv6 and future addressing scheme are enclosed between brackets
      */
     if (*cur == '[') {
         cur++;
@@ -1456,7 +1458,7 @@
               goto done_cd;
 	    (out++)[0] = (cur++)[0];
 	}
-	/* nomalize // */
+	/* normalize // */
 	while ((cur[0] == '/') && (cur[1] == '/'))
 	    cur++;
 
@@ -2150,7 +2152,7 @@
  *     http://site1.com/docs/pic1.gif   http://site1.com/docs/pic1.gif
  *
  *
- * Note: if the URI reference is really wierd or complicated, it may be
+ * Note: if the URI reference is really weird or complicated, it may be
  *       worthwhile to first convert it into a "nice" one by calling
  *       xmlBuildURI (using 'base') before calling this routine,
  *       since this routine (for reasonable efficiency) assumes URI has
@@ -2461,7 +2463,7 @@
 	/* allocate space for leading '/' + path + string terminator */
 	uri->path = xmlMallocAtomic(len + 2);
 	if (uri->path == NULL) {
-	    xmlFreeURI(uri);	/* Guard agains 'out of memory' */
+	    xmlFreeURI(uri);	/* Guard against 'out of memory' */
 	    return(NULL);
 	}
 	/* Put in leading '/' plus path */
@@ -2476,7 +2478,7 @@
 	}
 	p = uri->path;
     }
-    /* Now change all occurences of '\' to '/' */
+    /* Now change all occurrences of '\' to '/' */
     while (*p != '\0') {
 	if (*p == '\\')
 	    *p = '/';
@@ -2526,7 +2528,7 @@
         return(NULL);
 #if defined(_WIN32) && !defined(__CYGWIN__)
     /* xmlCanonicPath can return an URI on Windows (is that the intended behaviour?)
-       If 'cal' is a valid URI allready then we are done here, as continuing would make
+       If 'cal' is a valid URI already then we are done here, as continuing would make
        it invalid. */
     if ((uri = xmlParseURI((const char *) cal)) != NULL) {
 	xmlFreeURI(uri);
diff --git a/src/valid.c b/src/valid.c
index b1cfede..5ee391c 100644
--- a/src/valid.c
+++ b/src/valid.c
@@ -50,7 +50,7 @@
 /**
  * xmlVErrMemory:
  * @ctxt:  an XML validation parser context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory error
  */
@@ -89,7 +89,7 @@
  * xmlErrValid:
  * @ctxt:  an XML validation parser context
  * @error:  the error number
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a validation error
  */
@@ -131,11 +131,11 @@
  * @ctxt:  an XML validation parser context
  * @node:  the node raising the error
  * @error:  the error number
- * @str1:  extra informations
- * @str2:  extra informations
- * @str3:  extra informations
+ * @str1:  extra information
+ * @str2:  extra information
+ * @str3:  extra information
  *
- * Handle a validation error, provide contextual informations
+ * Handle a validation error, provide contextual information
  */
 static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNode(xmlValidCtxtPtr ctxt,
@@ -174,11 +174,11 @@
  * @ctxt:  an XML validation parser context
  * @node:  the node raising the error
  * @error:  the error number
- * @str1:  extra informations
- * @int2:  extra informations
- * @str3:  extra informations
+ * @str1:  extra information
+ * @int2:  extra information
+ * @str3:  extra information
  *
- * Handle a validation error, provide contextual informations
+ * Handle a validation error, provide contextual information
  */
 static void LIBXML_ATTR_FORMAT(4,0)
 xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
@@ -1099,14 +1099,22 @@
  */
 void
 xmlFreeDocElementContent(xmlDocPtr doc, xmlElementContentPtr cur) {
-    xmlElementContentPtr next;
     xmlDictPtr dict = NULL;
+    size_t depth = 0;
 
+    if (cur == NULL)
+        return;
     if (doc != NULL)
         dict = doc->dict;
 
-    while (cur != NULL) {
-        next = cur->c2;
+    while (1) {
+        xmlElementContentPtr parent;
+
+        while ((cur->c1 != NULL) || (cur->c2 != NULL)) {
+            cur = (cur->c1 != NULL) ? cur->c1 : cur->c2;
+            depth += 1;
+        }
+
 	switch (cur->type) {
 	    case XML_ELEMENT_CONTENT_PCDATA:
 	    case XML_ELEMENT_CONTENT_ELEMENT:
@@ -1119,7 +1127,6 @@
 			NULL);
 		return;
 	}
-	if (cur->c1 != NULL) xmlFreeDocElementContent(doc, cur->c1);
 	if (dict) {
 	    if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
 	        xmlFree((xmlChar *) cur->name);
@@ -1129,8 +1136,23 @@
 	    if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
 	    if (cur->prefix != NULL) xmlFree((xmlChar *) cur->prefix);
 	}
+        parent = cur->parent;
+        if ((depth == 0) || (parent == NULL)) {
+            xmlFree(cur);
+            break;
+        }
+        if (cur == parent->c1)
+            parent->c1 = NULL;
+        else
+            parent->c2 = NULL;
 	xmlFree(cur);
-	cur = next;
+
+        if (parent->c2 != NULL) {
+	    cur = parent->c2;
+        } else {
+            depth -= 1;
+            cur = parent;
+        }
     }
 }
 
@@ -1148,81 +1170,102 @@
 
 #ifdef LIBXML_OUTPUT_ENABLED
 /**
+ * xmlDumpElementOccur:
+ * @buf:  An XML buffer
+ * @cur:  An element table
+ *
+ * Dump the occurrence operator of an element.
+ */
+static void
+xmlDumpElementOccur(xmlBufferPtr buf, xmlElementContentPtr cur) {
+    switch (cur->ocur) {
+        case XML_ELEMENT_CONTENT_ONCE:
+            break;
+        case XML_ELEMENT_CONTENT_OPT:
+            xmlBufferWriteChar(buf, "?");
+            break;
+        case XML_ELEMENT_CONTENT_MULT:
+            xmlBufferWriteChar(buf, "*");
+            break;
+        case XML_ELEMENT_CONTENT_PLUS:
+            xmlBufferWriteChar(buf, "+");
+            break;
+    }
+}
+
+/**
  * xmlDumpElementContent:
  * @buf:  An XML buffer
  * @content:  An element table
- * @glob: 1 if one must print the englobing parenthesis, 0 otherwise
  *
  * This will dump the content of the element table as an XML DTD definition
  */
 static void
-xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) {
+xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content) {
+    xmlElementContentPtr cur;
+
     if (content == NULL) return;
 
-    if (glob) xmlBufferWriteChar(buf, "(");
-    switch (content->type) {
-        case XML_ELEMENT_CONTENT_PCDATA:
-            xmlBufferWriteChar(buf, "#PCDATA");
-	    break;
-	case XML_ELEMENT_CONTENT_ELEMENT:
-	    if (content->prefix != NULL) {
-		xmlBufferWriteCHAR(buf, content->prefix);
-		xmlBufferWriteChar(buf, ":");
-	    }
-	    xmlBufferWriteCHAR(buf, content->name);
-	    break;
-	case XML_ELEMENT_CONTENT_SEQ:
-	    if ((content->c1 != NULL) &&
-	        ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-	         (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
-		xmlDumpElementContent(buf, content->c1, 1);
-	    else
-		xmlDumpElementContent(buf, content->c1, 0);
-            xmlBufferWriteChar(buf, " , ");
-	    if ((content->c2 != NULL) &&
-	        ((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
-	         ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) &&
-		  (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
-		xmlDumpElementContent(buf, content->c2, 1);
-	    else
-		xmlDumpElementContent(buf, content->c2, 0);
-	    break;
-	case XML_ELEMENT_CONTENT_OR:
-	    if ((content->c1 != NULL) &&
-	        ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
-	         (content->c1->type == XML_ELEMENT_CONTENT_SEQ)))
-		xmlDumpElementContent(buf, content->c1, 1);
-	    else
-		xmlDumpElementContent(buf, content->c1, 0);
-            xmlBufferWriteChar(buf, " | ");
-	    if ((content->c2 != NULL) &&
-	        ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
-	         ((content->c2->type == XML_ELEMENT_CONTENT_OR) &&
-		  (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))))
-		xmlDumpElementContent(buf, content->c2, 1);
-	    else
-		xmlDumpElementContent(buf, content->c2, 0);
-	    break;
-	default:
-	    xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
-		    "Internal: ELEMENT content corrupted invalid type\n",
-		    NULL);
-    }
-    if (glob)
-        xmlBufferWriteChar(buf, ")");
-    switch (content->ocur) {
-        case XML_ELEMENT_CONTENT_ONCE:
-	    break;
-        case XML_ELEMENT_CONTENT_OPT:
-	    xmlBufferWriteChar(buf, "?");
-	    break;
-        case XML_ELEMENT_CONTENT_MULT:
-	    xmlBufferWriteChar(buf, "*");
-	    break;
-        case XML_ELEMENT_CONTENT_PLUS:
-	    xmlBufferWriteChar(buf, "+");
-	    break;
-    }
+    xmlBufferWriteChar(buf, "(");
+    cur = content;
+
+    do {
+        if (cur == NULL) return;
+
+        switch (cur->type) {
+            case XML_ELEMENT_CONTENT_PCDATA:
+                xmlBufferWriteChar(buf, "#PCDATA");
+                break;
+            case XML_ELEMENT_CONTENT_ELEMENT:
+                if (cur->prefix != NULL) {
+                    xmlBufferWriteCHAR(buf, cur->prefix);
+                    xmlBufferWriteChar(buf, ":");
+                }
+                xmlBufferWriteCHAR(buf, cur->name);
+                break;
+            case XML_ELEMENT_CONTENT_SEQ:
+            case XML_ELEMENT_CONTENT_OR:
+                if ((cur != content) &&
+                    (cur->parent != NULL) &&
+                    ((cur->type != cur->parent->type) ||
+                     (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
+                    xmlBufferWriteChar(buf, "(");
+                cur = cur->c1;
+                continue;
+            default:
+                xmlErrValid(NULL, XML_ERR_INTERNAL_ERROR,
+                        "Internal: ELEMENT cur corrupted invalid type\n",
+                        NULL);
+        }
+
+        while (cur != content) {
+            xmlElementContentPtr parent = cur->parent;
+
+            if (parent == NULL) return;
+
+            if (((cur->type == XML_ELEMENT_CONTENT_OR) ||
+                 (cur->type == XML_ELEMENT_CONTENT_SEQ)) &&
+                ((cur->type != parent->type) ||
+                 (cur->ocur != XML_ELEMENT_CONTENT_ONCE)))
+                xmlBufferWriteChar(buf, ")");
+            xmlDumpElementOccur(buf, cur);
+
+            if (cur == parent->c1) {
+                if (parent->type == XML_ELEMENT_CONTENT_SEQ)
+                    xmlBufferWriteChar(buf, " , ");
+                else if (parent->type == XML_ELEMENT_CONTENT_OR)
+                    xmlBufferWriteChar(buf, " | ");
+
+                cur = parent->c2;
+                break;
+            }
+
+            cur = parent;
+        }
+    } while (cur != content);
+
+    xmlBufferWriteChar(buf, ")");
+    xmlDumpElementOccur(buf, content);
 }
 
 /**
@@ -1703,7 +1746,7 @@
 	    }
 	    xmlBufferWriteCHAR(buf, elem->name);
 	    xmlBufferWriteChar(buf, " ");
-	    xmlDumpElementContent(buf, elem->content, 1);
+	    xmlDumpElementContent(buf, elem->content);
 	    xmlBufferWriteChar(buf, ">\n");
 	    break;
 	case XML_ELEMENT_TYPE_ELEMENT:
@@ -1714,7 +1757,7 @@
 	    }
 	    xmlBufferWriteCHAR(buf, elem->name);
 	    xmlBufferWriteChar(buf, " ");
-	    xmlDumpElementContent(buf, elem->content, 1);
+	    xmlDumpElementContent(buf, elem->content);
 	    xmlBufferWriteChar(buf, ">\n");
 	    break;
 	default:
@@ -2640,7 +2683,7 @@
     ret->doc = doc;
     if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
 	/*
-	 * Operating in streaming mode, attr is gonna disapear
+	 * Operating in streaming mode, attr is gonna disappear
 	 */
 	if (doc->dict != NULL)
 	    ret->name = xmlDictLookup(doc->dict, attr->name, -1);
@@ -2968,7 +3011,7 @@
     ret->value = xmlStrdup(value);
     if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
 	/*
-	 * Operating in streaming mode, attr is gonna disapear
+	 * Operating in streaming mode, attr is gonna disappear
 	 */
 	ret->name = xmlStrdup(attr->name);
 	ret->attr = NULL;
@@ -5391,7 +5434,7 @@
     } else if (ret == -2) {
 	/*
 	 * An entities reference appeared at this level.
-	 * Buid a minimal representation of this node content
+	 * Build a minimal representation of this node content
 	 * sufficient to run the validation process on it
 	 */
 	DEBUG_VALID_MSG("Found an entity reference, linearizing");
@@ -5876,28 +5919,27 @@
 		    break;
 		case XML_ELEMENT_TYPE_MIXED:
 		    break;
-		case XML_ELEMENT_TYPE_ELEMENT:
-		    if (len > 0) {
-			int i;
+		case XML_ELEMENT_TYPE_ELEMENT: {
+                    int i;
 
-			for (i = 0;i < len;i++) {
-			    if (!IS_BLANK_CH(data[i])) {
-				xmlErrValidNode(ctxt, state->node,
-						XML_DTD_CONTENT_MODEL,
-	   "Element %s content does not follow the DTD, Text not allowed\n",
-				       state->node->name, NULL, NULL);
-				ret = 0;
-				goto done;
-			    }
-			}
-			/*
-			 * TODO:
-			 * VC: Standalone Document Declaration
-			 *  element types with element content, if white space
-			 *  occurs directly within any instance of those types.
-			 */
-		    }
-		    break;
+                    for (i = 0;i < len;i++) {
+                        if (!IS_BLANK_CH(data[i])) {
+                            xmlErrValidNode(ctxt, state->node,
+                                            XML_DTD_CONTENT_MODEL,
+       "Element %s content does not follow the DTD, Text not allowed\n",
+                                   state->node->name, NULL, NULL);
+                            ret = 0;
+                            goto done;
+                        }
+                    }
+                    /*
+                     * TODO:
+                     * VC: Standalone Document Declaration
+                     *  element types with element content, if white space
+                     *  occurs directly within any instance of those types.
+                     */
+                    break;
+                }
 	    }
 	}
     }
diff --git a/src/win32/Readme.txt b/src/win32/Readme.txt
index 6b3eddd..d02070e 100644
--- a/src/win32/Readme.txt
+++ b/src/win32/Readme.txt
@@ -23,7 +23,7 @@
    2.1 GNU C/C++, Mingw Edition
    2.2 Borland C++ Builder
        2.2.1 Building with iconv support
-	   2.2.2 Compatability problems with MSVC (and probably CYGWIN)
+	   2.2.2 Compatibility problems with MSVC (and probably CYGWIN)
 	   2.2.3 Other caveats
 
 
@@ -188,7 +188,7 @@
 not found). This should not have any disastrous side effects beyond possibly
 displaying a misleading error message in certain situations.
 
-2.2.2 Compatability problems with MSVC (and probably CYGWIN)
+2.2.2 Compatibility problems with MSVC (and probably CYGWIN)
 
 A libxml2 DLL generated by BCB is callable from MSVC programs, but there is a
 minor problem with the names of the symbols exported from the library. The
diff --git a/src/win32/VC10/README.vc10 b/src/win32/VC10/README.vc10
index f7826b0..25c385b 100644
--- a/src/win32/VC10/README.vc10
+++ b/src/win32/VC10/README.vc10
@@ -3,13 +3,13 @@
 ----------------------------------------------
 
 to clarify: This is not the readme file for the whole libxml2 project. 
-Rather, it's a readme for the VC10 project files, attached to the libxml2 proejct.
+Rather, it's a readme for the VC10 project files, attached to the libxml2 project.
 
 Quick Start
 -----------
 
 1) To use, load the libxml2.sln solution file into visual studio
-2) check and correct paths for dependent "iconv" project which most certaily 
+2) check and correct paths for dependent "iconv" project which most certainly 
 are wrong on your environment.
 3) Compile all projects
 
diff --git a/src/win32/configure.js b/src/win32/configure.js
index dbf238c..e2ab31d 100644
--- a/src/win32/configure.js
+++ b/src/win32/configure.js
@@ -165,14 +165,14 @@
 	txt += "              installed (" + buildLibPrefix + ")\n";
 	txt += "  sodir:      Directory where shared libraries should be installed\n"; 
 	txt += "              (" + buildSoPrefix + ")\n";
-	txt += "  include:    Additional search path for the compiler, particularily\n";
+	txt += "  include:    Additional search path for the compiler, particularly\n";
 	txt += "              where iconv headers can be found (" + buildInclude + ")\n";
-	txt += "  lib:        Additional search path for the linker, particularily\n";
+	txt += "  lib:        Additional search path for the linker, particularly\n";
 	txt += "              where iconv library can be found (" + buildLib + ")\n";
 	WScript.Echo(txt);
 }
 
-/* Discovers the version we are working with by reading the apropriate
+/* Discovers the version we are working with by reading the appropriate
    configuration file. Despite its name, this also writes the configuration
    file included by our makefile. */
 function discoverVersion()
@@ -210,16 +210,16 @@
 		s = new String(ln);
 		if (s.search(/^LIBXML_MAJOR_VERSION=/) != -1) {
 			vf.WriteLine(s);
-			verMajor = s.substring(s.indexOf("=") + 1, s.length)
+			verMajor = s.substring(s.indexOf("=") + 1, s.length);
 		} else if(s.search(/^LIBXML_MINOR_VERSION=/) != -1) {
 			vf.WriteLine(s);
-			verMinor = s.substring(s.indexOf("=") + 1, s.length)
+			verMinor = s.substring(s.indexOf("=") + 1, s.length);
 		} else if(s.search(/^LIBXML_MICRO_VERSION=/) != -1) {
 			vf.WriteLine(s);
-			verMicro = s.substring(s.indexOf("=") + 1, s.length)
+			verMicro = s.substring(s.indexOf("=") + 1, s.length);
 		} else if(s.search(/^LIBXML_MICRO_VERSION_SUFFIX=/) != -1) {
 			vf.WriteLine(s);
-			verMicroSuffix = s.substring(s.indexOf("=") + 1, s.length)
+			verMicroSuffix = s.substring(s.indexOf("=") + 1, s.length);
 		}
 	}
 	cf.Close();
@@ -280,7 +280,7 @@
 		vf.WriteLine("DYNRUNTIME=" + (dynruntime? "1" : "0"));
 	}
 	vf.Close();
-	versionFile = "rcVersion.h"
+	versionFile = "rcVersion.h";
 	vf = fso.CreateTextFile(versionFile, true);
 	vf.WriteLine("/*");
 	vf.WriteLine("  " + versionFile);
@@ -291,7 +291,7 @@
 	vf.WriteLine("#define LIBXML_MINOR_VERSION " + verMinor);
 	vf.WriteLine("#define LIBXML_MICRO_VERSION " + verMicro);
 	vf.WriteLine("#define LIBXML_DOTTED_VERSION " + "\"" + verMajor + "." + verMinor + "." + verMicro + "\"");
-	vf.Close()
+	vf.Close();
 }
 
 /* Configures libxml. This one will generate xmlversion.h from xmlversion.h.in
@@ -430,7 +430,7 @@
 	f.WriteLine("platform.");
 	f.WriteBlankLines(1);
 	f.WriteLine("  The files in this package do not require any special installation");
-	f.WriteLine("steps. Extract the contents of the archive whereever you wish and");
+	f.WriteLine("steps. Extract the contents of the archive wherever you wish and");
 	f.WriteLine("make sure that your tools which use " + bname + " can find it.");
 	f.WriteBlankLines(1);
 	f.WriteLine("  For example, if you want to run the supplied utilities from the command");
@@ -544,8 +544,6 @@
 			buildStatic = strToBool(arg.substring(opt.length + 1, arg.length));
 		else if (opt == "prefix")
 			buildPrefix = arg.substring(opt.length + 1, arg.length);
-		else if (opt == "incdir")
-			buildIncPrefix = arg.substring(opt.length + 1, arg.length);
 		else if (opt == "bindir")
 			buildBinPrefix = arg.substring(opt.length + 1, arg.length);
 		else if (opt == "libdir")
diff --git a/src/win32/libxml2.def.src b/src/win32/libxml2.def.src
index 1bdbed9..1e771e8 100644
--- a/src/win32/libxml2.def.src
+++ b/src/win32/libxml2.def.src
@@ -945,6 +945,7 @@
 xmlHashCopy
 xmlHashCreate
 xmlHashCreateDict
+xmlHashDefaultDeallocator
 xmlHashFree
 xmlHashLookup
 xmlHashLookup2
diff --git a/src/xml2-config.1 b/src/xml2-config.1
index 8cf9858..4dec38f 100644
--- a/src/xml2-config.1
+++ b/src/xml2-config.1
@@ -16,6 +16,7 @@
 .TP 8
 .B  \-\-libs
 Print the linker flags that are necessary to link a \fIGNOME-XML\fP program.
+Add \-\-dynamic after --libs to print only shared library linking information.
 .TP 8
 .B  \-\-cflags
 Print the compiler flags that are necessary to compile a \fIGNOME-XML\fP program.
diff --git a/src/xml2Conf.sh.in b/src/xml2Conf.sh.in
index 08cb233..31228c0 100644
--- a/src/xml2Conf.sh.in
+++ b/src/xml2Conf.sh.in
@@ -2,7 +2,7 @@
 # Configuration file for using the XML library in GNOME applications
 #
 XML2_LIBDIR="@XML_LIBDIR@"
-XML2_LIBS="@XML_LIBS@"
+XML2_LIBS="@XML_LIBS@ @XML_PRIVATE_LIBS@"
 XML2_INCLUDEDIR="@XML_INCLUDEDIR@"
 MODULE_VERSION="xml2-@VERSION@"
 
diff --git a/src/xmlIO.c b/src/xmlIO.c
index f61dd05..7827dcf 100644
--- a/src/xmlIO.c
+++ b/src/xmlIO.c
@@ -185,9 +185,9 @@
     "already connected",	/* EISCONN */
     "connection refused",	/* ECONNREFUSED */
     "unreachable network",	/* ENETUNREACH */
-    "adddress in use",		/* EADDRINUSE */
+    "address in use",		/* EADDRINUSE */
     "already in use",		/* EALREADY */
-    "unknown address familly",	/* EAFNOSUPPORT */
+    "unknown address family",	/* EAFNOSUPPORT */
 };
 
 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
@@ -224,7 +224,7 @@
 
 /**
  * xmlIOErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -238,7 +238,7 @@
  * __xmlIOErr:
  * @code:  the error number
  * @
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an I/O error
  */
@@ -416,7 +416,7 @@
 /**
  * xmlIOErr:
  * @code:  the error number
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an I/O error
  */
@@ -429,7 +429,7 @@
 /**
  * __xmlLoaderErr:
  * @ctx: the parser context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a resource access error
  */
@@ -560,6 +560,33 @@
     xmlOutputCallbackNr = 0;
     xmlOutputCallbackInitialized = 0;
 }
+
+/**
+ * xmlPopOutputCallbacks:
+ *
+ * Remove the top output callbacks from the output stack. This includes the
+ * compiled-in I/O.
+ *
+ * Returns the number of output callback registered or -1 in case of error.
+ */
+int
+xmlPopOutputCallbacks(void)
+{
+    if (!xmlOutputCallbackInitialized)
+        return(-1);
+
+    if (xmlOutputCallbackNr <= 0)
+        return(-1);
+
+    xmlOutputCallbackNr--;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = NULL;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = NULL;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = NULL;
+    xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = NULL;
+
+    return(xmlOutputCallbackNr);
+}
+
 #endif /* LIBXML_OUTPUT_ENABLED */
 
 /************************************************************************
@@ -2383,6 +2410,7 @@
     if (encoder != NULL) {
         ret->conv = xmlBufCreateSize(4000);
 	if (ret->conv == NULL) {
+            xmlBufFree(ret->buffer);
 	    xmlFree(ret);
 	    return(NULL);
 	}
@@ -2435,6 +2463,7 @@
     if (encoder != NULL) {
         ret->conv = xmlBufCreateSize(4000);
 	if (ret->conv == NULL) {
+            xmlBufFree(ret->buffer);
 	    xmlFree(ret);
 	    return(NULL);
 	}
@@ -3335,7 +3364,7 @@
     int nbchars = 0; /* number of chars to output to I/O */
     int ret;         /* return from function call */
     int written = 0; /* number of char written to I/O so far */
-    int chunk;       /* number of byte curreent processed from buf */
+    int chunk;       /* number of byte current processed from buf */
 
     if ((out == NULL) || (out->error)) return(-1);
     if (len < 0) return(0);
@@ -3372,20 +3401,26 @@
 		out->error = XML_IO_ENCODER;
 		return(-1);
 	    }
-	    nbchars = xmlBufUse(out->conv);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->conv);
+            else
+                nbchars = ret;
 	} else {
 	    ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
 	    if (ret != 0)
 	        return(-1);
-	    nbchars = xmlBufUse(out->buffer);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->buffer);
+            else
+                nbchars = chunk;
 	}
 	buf += chunk;
 	len -= chunk;
 
-	if ((nbchars < MINLEN) && (len <= 0))
-	    goto done;
-
 	if (out->writecallback) {
+            if ((nbchars < MINLEN) && (len <= 0))
+                goto done;
+
 	    /*
 	     * second write the stuff to the I/O channel
 	     */
@@ -3405,7 +3440,10 @@
 		out->error = XML_IO_WRITE;
 		return(ret);
 	    }
-	    out->written += ret;
+            if (out->written > INT_MAX - ret)
+                out->written = INT_MAX;
+            else
+                out->written += ret;
 	}
 	written += nbchars;
     } while (len > 0);
@@ -3485,7 +3523,7 @@
  * @escaping:  an optional escaping function (or NULL)
  *
  * Write the content of the string in the output I/O buffer
- * This routine escapes the caracters and then handle the I18N
+ * This routine escapes the characters and then handle the I18N
  * transcoding from internal UTF-8
  * The buffer is lossless, i.e. will store in case of partial
  * or delayed writes.
@@ -3561,21 +3599,27 @@
 		out->error = XML_IO_ENCODER;
 		return(-1);
 	    }
-	    nbchars = xmlBufUse(out->conv);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->conv);
+            else
+                nbchars = ret;
 	} else {
 	    ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
 	    if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
 	        return(-1);
             xmlBufAddLen(out->buffer, chunk);
-	    nbchars = xmlBufUse(out->buffer);
+            if (out->writecallback)
+	        nbchars = xmlBufUse(out->buffer);
+            else
+                nbchars = chunk;
 	}
 	str += cons;
 	len -= cons;
 
-	if ((nbchars < MINLEN) && (len <= 0))
-	    goto done;
-
 	if (out->writecallback) {
+            if ((nbchars < MINLEN) && (len <= 0))
+                goto done;
+
 	    /*
 	     * second write the stuff to the I/O channel
 	     */
@@ -3595,7 +3639,10 @@
 		out->error = XML_IO_WRITE;
 		return(ret);
 	    }
-	    out->written += ret;
+            if (out->written > INT_MAX - ret)
+                out->written = INT_MAX;
+            else
+                out->written += ret;
 	} else if (xmlBufAvail(out->buffer) < MINLEN) {
 	    xmlBufGrow(out->buffer, MINLEN);
 	}
@@ -3689,7 +3736,10 @@
 	out->error = XML_IO_FLUSH;
 	return(ret);
     }
-    out->written += ret;
+    if (out->written > INT_MAX - ret)
+        out->written = INT_MAX;
+    else
+        out->written += ret;
 
 #ifdef DEBUG_INPUT
     xmlGenericError(xmlGenericErrorContext,
@@ -3937,7 +3987,7 @@
  * @ID:  the System ID for the entity to load
  * @ctxt:  the context in which the entity is called or NULL
  *
- * By default we don't load external entitites, yet.
+ * By default we don't load external entities, yet.
  *
  * Returns a new allocated xmlParserInputPtr, or NULL.
  */
diff --git a/src/xmlmemory.c b/src/xmlmemory.c
index 6f16c4b..c51f49a 100644
--- a/src/xmlmemory.c
+++ b/src/xmlmemory.c
@@ -75,7 +75,7 @@
 #endif
 
 /*
- * Each of the blocks allocated begin with a header containing informations
+ * Each of the blocks allocated begin with a header containing information
  */
 
 #define MEMTAG 0x5aa5
diff --git a/src/xmlreader.c b/src/xmlreader.c
index ad9ce01..b603c72 100644
--- a/src/xmlreader.c
+++ b/src/xmlreader.c
@@ -348,7 +348,9 @@
 static void
 xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur) {
     xmlNodePtr next;
+    xmlNodePtr parent;
     xmlDictPtr dict;
+    size_t depth = 0;
 
     if ((reader != NULL) && (reader->ctxt != NULL))
 	dict = reader->ctxt->dict;
@@ -364,18 +366,21 @@
 	xmlFreeDoc((xmlDocPtr) cur);
 	return;
     }
-    while (cur != NULL) {
+    while (1) {
+        while ((cur->type != XML_DTD_NODE) &&
+               (cur->type != XML_ENTITY_REF_NODE) &&
+               (cur->children != NULL) &&
+               (cur->children->parent == cur)) {
+            cur = cur->children;
+            depth += 1;
+        }
+
         next = cur->next;
+        parent = cur->parent;
+
 	/* unroll to speed up freeing the document */
 	if (cur->type != XML_DTD_NODE) {
 
-	    if ((cur->children != NULL) &&
-		(cur->type != XML_ENTITY_REF_NODE)) {
-		if (cur->children->parent == cur)
-		    xmlTextReaderFreeNodeList(reader, cur->children);
-		cur->children = NULL;
-	    }
-
 	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 		xmlDeregisterNodeDefaultValue(cur);
 
@@ -414,7 +419,16 @@
 		xmlFree(cur);
 	    }
 	}
-	cur = next;
+
+        if (next != NULL) {
+	    cur = next;
+        } else {
+            if ((depth == 0) || (parent == NULL))
+                break;
+            depth -= 1;
+            cur = parent;
+            cur->children = NULL;
+        }
     }
 }
 
@@ -986,7 +1000,6 @@
 	     */
 	    node = xmlTextReaderExpand(reader);
 	    if (node == NULL) {
-printf("Expand failed !\n");
 	        ret = -1;
 	    } else {
 		ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
@@ -1093,20 +1106,9 @@
 xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
     xmlNodePtr oldnode = reader->node;
     xmlNodePtr node = reader->node;
-    xmlParserCtxtPtr ctxt = reader->ctxt;
 
     do {
 	if (node->type == XML_ENTITY_REF_NODE) {
-	    /*
-	     * Case where the underlying tree is not availble, lookup the entity
-	     * and walk it.
-	     */
-	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
-		(ctxt->sax->getEntity != NULL)) {
-		node->children = (xmlNodePtr)
-		    ctxt->sax->getEntity(ctxt, node->name);
-	    }
-
 	    if ((node->children != NULL) &&
 		(node->children->type == XML_ENTITY_DECL) &&
 		(node->children->children != NULL)) {
@@ -1361,7 +1363,7 @@
 
     /*
      * If we are not backtracking on ancestors or examined nodes,
-     * that the parser didn't finished or that we arent at the end
+     * that the parser didn't finished or that we aren't at the end
      * of stream, continue processing.
      */
     while ((reader->node != NULL) && (reader->node->next == NULL) &&
@@ -1551,16 +1553,6 @@
     if ((reader->node != NULL) &&
 	(reader->node->type == XML_ENTITY_REF_NODE) &&
 	(reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
-	/*
-	 * Case where the underlying tree is not availble, lookup the entity
-	 * and walk it.
-	 */
-	if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
-	    (reader->ctxt->sax->getEntity != NULL)) {
-	    reader->node->children = (xmlNodePtr)
-		reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
-	}
-
 	if ((reader->node->children != NULL) &&
 	    (reader->node->children->type == XML_ENTITY_DECL) &&
 	    (reader->node->children->children != NULL)) {
@@ -1717,6 +1709,8 @@
     }
     doc = reader->node->doc;
     buff = xmlBufferCreate();
+    if (buff == NULL)
+        return NULL;
     for (cur_node = reader->node->children; cur_node != NULL;
          cur_node = cur_node->next) {
         /* XXX: Why is the node copied? */
@@ -1759,11 +1753,11 @@
     xmlBufferPtr buff;
     xmlDocPtr doc;
 
-    node = reader->node;
-    doc = node->doc;
     if (xmlTextReaderExpand(reader) == NULL) {
         return NULL;
     }
+    node = reader->node;
+    doc = node->doc;
     /* XXX: Why is the node copied? */
 	if (node->type == XML_DTD_NODE) {
 		node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
@@ -2271,7 +2265,7 @@
 #ifdef LIBXML_REGEXP_ENABLED
             while (reader->ctxt->vctxt.vstateNr > 0)
                 xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
-#endif
+#endif /* LIBXML_REGEXP_ENABLED */
 	    xmlFree(reader->ctxt->vctxt.vstateTab);
 	    reader->ctxt->vctxt.vstateTab = NULL;
 	    reader->ctxt->vctxt.vstateMax = 0;
@@ -2508,7 +2502,7 @@
  * parser, set its state to End Of File and return the input stream with
  * what is left that the parser did not use.
  *
- * The implementation is not good, the parser certainly procgressed past
+ * The implementation is not good, the parser certainly progressed past
  * what's left in reader->input, and there is an allocation problem. Best
  * would be to rewrite it differently.
  *
@@ -2890,8 +2884,8 @@
  *
  * Parses an attribute value into one or more Text and EntityReference nodes.
  *
- * Returns 1 in case of success, 0 if the reader was not positionned on an
- *         ttribute node or all the attribute values have been read, or -1
+ * Returns 1 in case of success, 0 if the reader was not positioned on an
+ *         attribute node or all the attribute values have been read, or -1
  *         in case of error.
  */
 int
@@ -2958,7 +2952,7 @@
 
 /************************************************************************
  *									*
- *			Acces API to the current node			*
+ *			Access API to the current node			*
  *									*
  ************************************************************************/
 /**
@@ -3773,7 +3767,7 @@
  *
  * The value indicating whether to normalize white space and attribute values.
  * Since attribute value and end of line normalizations are a MUST in the XML
- * specification only the value true is accepted. The broken bahaviour of
+ * specification only the value true is accepted. The broken behaviour of
  * accepting out of range character entities like &#0; is of course not
  * supported either.
  *
@@ -3835,16 +3829,20 @@
 	    return(0);
         case XML_PARSER_VALIDATE:
 	    if (value != 0) {
+                ctxt->options |= XML_PARSE_DTDVALID;
 		ctxt->validate = 1;
 		reader->validate = XML_TEXTREADER_VALIDATE_DTD;
 	    } else {
+                ctxt->options &= ~XML_PARSE_DTDVALID;
 		ctxt->validate = 0;
 	    }
 	    return(0);
         case XML_PARSER_SUBST_ENTITIES:
 	    if (value != 0) {
+                ctxt->options |= XML_PARSE_NOENT;
 		ctxt->replaceEntities = 1;
 	    } else {
+                ctxt->options &= ~XML_PARSE_NOENT;
 		ctxt->replaceEntities = 0;
 	    }
 	    return(0);
@@ -3928,7 +3926,7 @@
  * xmlTextReaderCurrentNode:
  * @reader:  the xmlTextReaderPtr used
  *
- * Hacking interface allowing to get the xmlNodePtr correponding to the
+ * Hacking interface allowing to get the xmlNodePtr corresponding to the
  * current node being accessed by the xmlTextReader. This is dangerous
  * because the underlying node may be destroyed on the next Reads.
  *
@@ -4040,7 +4038,7 @@
  * xmlTextReaderCurrentDoc:
  * @reader:  the xmlTextReaderPtr used
  *
- * Hacking interface allowing to get the xmlDocPtr correponding to the
+ * Hacking interface allowing to get the xmlDocPtr corresponding to the
  * current document being accessed by the xmlTextReader.
  * NOTE: as a result of this call, the reader will not destroy the
  *       associated XML document and calling xmlFreeDoc() on the result
@@ -4143,11 +4141,11 @@
  *
  * Use RelaxNG to validate the document as it is processed.
  * Activation is only possible before the first Read().
- * if @schema is NULL, then RelaxNG validation is desactivated.
+ * if @schema is NULL, then RelaxNG validation is deactivated.
  @ The @schema should not be freed until the reader is deallocated
  * or its use has been deactivated.
  *
- * Returns 0 in case the RelaxNG validation could be (des)activated and
+ * Returns 0 in case the RelaxNG validation could be (de)activated and
  *         -1 in case of error.
  */
 int
@@ -4207,7 +4205,7 @@
  *
  * Internal locator function for the readers
  *
- * Returns 0 in case the Schema validation could be (des)activated and
+ * Returns 0 in case the Schema validation could be (de)activated and
  *         -1 in case of error.
  */
 static int
@@ -4260,11 +4258,11 @@
  *
  * Use XSD Schema to validate the document as it is processed.
  * Activation is only possible before the first Read().
- * if @schema is NULL, then Schema validation is desactivated.
- @ The @schema should not be freed until the reader is deallocated
+ * if @schema is NULL, then Schema validation is deactivated.
+ * The @schema should not be freed until the reader is deallocated
  * or its use has been deactivated.
  *
- * Returns 0 in case the Schema validation could be (des)activated and
+ * Returns 0 in case the Schema validation could be (de)activated and
  *         -1 in case of error.
  */
 int
diff --git a/src/xmlsave.c b/src/xmlsave.c
index 7a05d83..0e698bb 100644
--- a/src/xmlsave.c
+++ b/src/xmlsave.c
@@ -1,5 +1,5 @@
 /*
- * xmlsave.c: Implemetation of the document serializer
+ * xmlsave.c: Implementation of the document serializer
  *
  * See Copyright for the status of this software.
  *
@@ -83,7 +83,6 @@
     const xmlChar *encoding;
     xmlCharEncodingHandlerPtr handler;
     xmlOutputBufferPtr buf;
-    xmlDocPtr doc;
     int options;
     int level;
     int format;
@@ -101,7 +100,7 @@
  ************************************************************************/
 /**
  * xmlSaveErrMemory:
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -115,7 +114,7 @@
  * xmlSaveErr:
  * @code:  the error number
  * @node:  the location of the error.
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle an out of memory condition
  */
@@ -356,7 +355,7 @@
 /**
  * xmlFreeSaveCtxt:
  *
- * Free a saving context, destroying the ouptut in any remaining buffer
+ * Free a saving context, destroying the output in any remaining buffer
  */
 static void
 xmlFreeSaveCtxt(xmlSaveCtxtPtr ctxt)
@@ -707,7 +706,6 @@
 xmlDtdDumpOutput(xmlSaveCtxtPtr ctxt, xmlDtdPtr dtd) {
     xmlOutputBufferPtr buf;
     int format, level;
-    xmlDocPtr doc;
 
     if (dtd == NULL) return;
     if ((ctxt == NULL) || (ctxt->buf == NULL))
@@ -742,14 +740,11 @@
     }
     format = ctxt->format;
     level = ctxt->level;
-    doc = ctxt->doc;
     ctxt->format = 0;
     ctxt->level = -1;
-    ctxt->doc = dtd->doc;
     xmlNodeListDumpOutput(ctxt, dtd->children);
     ctxt->format = format;
     ctxt->level = level;
-    ctxt->doc = doc;
     xmlOutputBufferWrite(buf, 2, "]>");
 }
 
@@ -1807,6 +1802,7 @@
     if (ret == NULL) return(NULL);
     ret->buf = xmlOutputBufferCreateFd(fd, ret->handler);
     if (ret->buf == NULL) {
+        xmlCharEncCloseFunc(ret->handler);
 	xmlFreeSaveCtxt(ret);
 	return(NULL);
     }
@@ -1836,6 +1832,7 @@
     ret->buf = xmlOutputBufferCreateFilename(filename, ret->handler,
                                              compression);
     if (ret->buf == NULL) {
+        xmlCharEncCloseFunc(ret->handler);
 	xmlFreeSaveCtxt(ret);
 	return(NULL);
     }
@@ -1858,28 +1855,15 @@
 xmlSaveToBuffer(xmlBufferPtr buffer, const char *encoding, int options)
 {
     xmlSaveCtxtPtr ret;
-    xmlOutputBufferPtr out_buff;
-    xmlCharEncodingHandlerPtr handler;
 
     ret = xmlNewSaveCtxt(encoding, options);
     if (ret == NULL) return(NULL);
-
-    if (encoding != NULL) {
-        handler = xmlFindCharEncodingHandler(encoding);
-        if (handler == NULL) {
-            xmlFree(ret);
-            return(NULL);
-        }
-    } else
-        handler = NULL;
-    out_buff = xmlOutputBufferCreateBuffer(buffer, handler);
-    if (out_buff == NULL) {
-        xmlFree(ret);
-        if (handler) xmlCharEncCloseFunc(handler);
-        return(NULL);
+    ret->buf = xmlOutputBufferCreateBuffer(buffer, ret->handler);
+    if (ret->buf == NULL) {
+        xmlCharEncCloseFunc(ret->handler);
+	xmlFreeSaveCtxt(ret);
+	return(NULL);
     }
-
-    ret->buf = out_buff;
     return(ret);
 }
 
@@ -1907,6 +1891,7 @@
     if (ret == NULL) return(NULL);
     ret->buf = xmlOutputBufferCreateIO(iowrite, ioclose, ioctx, ret->handler);
     if (ret->buf == NULL) {
+        xmlCharEncCloseFunc(ret->handler);
 	xmlFreeSaveCtxt(ret);
 	return(NULL);
     }
@@ -2191,9 +2176,9 @@
  *
  * Dump an XML node, recursive behaviour,children are printed too.
  * Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
- * or xmlKeepBlanksDefault(0) was called
+ * or xmlKeepBlanksDefault(0) was called.
  * Since this is using xmlBuffer structures it is limited to 2GB and somehow
- * deprecated, use xmlBufNodeDump() instead.
+ * deprecated, use xmlNodeDumpOutput() instead.
  *
  * Returns the number of bytes written to the buffer or -1 in case of error
  */
@@ -2202,7 +2187,7 @@
             int format)
 {
     xmlBufPtr buffer;
-    int ret;
+    size_t ret;
 
     if ((buf == NULL) || (cur == NULL))
         return(-1);
@@ -2360,7 +2345,6 @@
         encoding = "UTF-8";
 
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = doc;
     ctxt.buf = buf;
     ctxt.level = level;
     ctxt.format = format ? 1 : 0;
@@ -2446,7 +2430,6 @@
     }
 
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = out_doc;
     ctxt.buf = out_buff;
     ctxt.level = 0;
     ctxt.format = format ? 1 : 0;
@@ -2565,7 +2548,6 @@
     buf = xmlOutputBufferCreateFile(f, handler);
     if (buf == NULL) return(-1);
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
     ctxt.format = format ? 1 : 0;
@@ -2596,7 +2578,7 @@
  * xmlSaveFileTo:
  * @buf:  an output I/O buffer
  * @cur:  the document
- * @encoding:  the encoding if any assuming the I/O layer handles the trancoding
+ * @encoding:  the encoding if any assuming the I/O layer handles the transcoding
  *
  * Dump an XML document to an I/O buffer.
  * Warning ! This call xmlOutputBufferClose() on buf which is not available
@@ -2615,7 +2597,6 @@
 	return(-1);
     }
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
     ctxt.format = 0;
@@ -2631,7 +2612,7 @@
  * xmlSaveFormatFileTo:
  * @buf:  an output I/O buffer
  * @cur:  the document
- * @encoding:  the encoding if any assuming the I/O layer handles the trancoding
+ * @encoding:  the encoding if any assuming the I/O layer handles the transcoding
  * @format: should formatting spaces been added
  *
  * Dump an XML document to an I/O buffer.
@@ -2655,7 +2636,6 @@
 	return(-1);
     }
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
     ctxt.format = format ? 1 : 0;
@@ -2710,7 +2690,6 @@
     buf = xmlOutputBufferCreateFilename(filename, handler, cur->compression);
     if (buf == NULL) return(-1);
     memset(&ctxt, 0, sizeof(ctxt));
-    ctxt.doc = cur;
     ctxt.buf = buf;
     ctxt.level = 0;
     ctxt.format = format ? 1 : 0;
diff --git a/src/xmlwriter.c b/src/xmlwriter.c
index b5cd171..58445c8 100644
--- a/src/xmlwriter.c
+++ b/src/xmlwriter.c
@@ -541,8 +541,8 @@
     if (encoding != NULL) {
         encoder = xmlFindCharEncodingHandler(encoding);
         if (encoder == NULL) {
-            xmlWriterErrMsg(writer, XML_ERR_NO_MEMORY,
-                            "xmlTextWriterStartDocument : out of memory!\n");
+            xmlWriterErrMsg(writer, XML_ERR_UNSUPPORTED_ENCODING,
+                            "xmlTextWriterStartDocument : unsupported encoding\n");
             return -1;
         }
     }
@@ -801,7 +801,7 @@
  * xmlTextWriterEndComment:
  * @writer:  the xmlTextWriterPtr
  *
- * End the current xml coment.
+ * End the current xml comment.
  *
  * Returns the bytes written (may be 0 because of buffering) or -1 in case of error
  */
diff --git a/src/xpath.c b/src/xpath.c
index 59f2e10..0d5aa68 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -343,7 +343,7 @@
     }
 
     /*
-     * Speedup using document order if availble.
+     * Speedup using document order if available.
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
 	(node2->type == XML_ELEMENT_NODE) &&
@@ -411,7 +411,7 @@
     if (node1 == node2->next)
 	return(-1);
     /*
-     * Speedup using document order if availble.
+     * Speedup using document order if available.
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
 	(node2->type == XML_ELEMENT_NODE) &&
@@ -435,7 +435,7 @@
 #endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
 
 /*
- * Wrapper for the Timsort argorithm from timsort.h
+ * Wrapper for the Timsort algorithm from timsort.h
  */
 #ifdef WITH_TIM_SORT
 #define SORT_NAME libxml_domnode
@@ -610,6 +610,8 @@
     "Invalid or incomplete context\n",
     "Stack usage error\n",
     "Forbidden variable\n",
+    "Operation limit exceeded\n",
+    "Recursion limit exceeded\n",
     "?? Unknown error ??\n"	/* Must be last in the list! */
 };
 #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
@@ -617,7 +619,7 @@
 /**
  * xmlXPathErrMemory:
  * @ctxt:  an XPath context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a redefinition of attribute error
  */
@@ -625,6 +627,7 @@
 xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra)
 {
     if (ctxt != NULL) {
+        xmlResetError(&ctxt->lastError);
         if (extra) {
             xmlChar buf[200];
 
@@ -659,7 +662,7 @@
 /**
  * xmlXPathPErrMemory:
  * @ctxt:  an XPath parser context
- * @extra:  extra informations
+ * @extra:  extra information
  *
  * Handle a redefinition of attribute error
  */
@@ -747,6 +750,32 @@
     xmlXPathErr(ctxt, no);
 }
 
+/**
+ * xmlXPathCheckOpLimit:
+ * @ctxt:  the XPath Parser context
+ * @opCount:  the number of operations to be added
+ *
+ * Adds opCount to the running total of operations and returns -1 if the
+ * operation limit is exceeded. Returns 0 otherwise.
+ */
+static int
+xmlXPathCheckOpLimit(xmlXPathParserContextPtr ctxt, unsigned long opCount) {
+    xmlXPathContextPtr xpctxt = ctxt->context;
+
+    if ((opCount > xpctxt->opLimit) ||
+        (xpctxt->opCount > xpctxt->opLimit - opCount)) {
+        xpctxt->opCount = xpctxt->opLimit;
+        xmlXPathErr(ctxt, XPATH_OP_LIMIT_EXCEEDED);
+        return(-1);
+    }
+
+    xpctxt->opCount += opCount;
+    return(0);
+}
+
+#define OP_LIMIT_EXCEEDED(ctxt, n) \
+    ((ctxt->context->opLimit != 0) && (xmlXPathCheckOpLimit(ctxt, n) < 0))
+
 /************************************************************************
  *									*
  *			Utilities					*
@@ -1076,14 +1105,15 @@
  * Returns -1 in case of failure, the index otherwise
  */
 static int
-xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
+xmlXPathCompExprAdd(xmlXPathParserContextPtr ctxt, int ch1, int ch2,
    xmlXPathOp op, int value,
    int value2, int value3, void *value4, void *value5) {
+    xmlXPathCompExprPtr comp = ctxt->comp;
     if (comp->nbStep >= comp->maxStep) {
 	xmlXPathStepOp *real;
 
         if (comp->maxStep >= XPATH_MAX_STEPS) {
-	    xmlXPathErrMemory(NULL, "adding step\n");
+	    xmlXPathPErrMemory(ctxt, "adding step\n");
 	    return(-1);
         }
 	comp->maxStep *= 2;
@@ -1091,7 +1121,7 @@
 		                      comp->maxStep * sizeof(xmlXPathStepOp));
 	if (real == NULL) {
 	    comp->maxStep /= 2;
-	    xmlXPathErrMemory(NULL, "adding step\n");
+	    xmlXPathPErrMemory(ctxt, "adding step\n");
 	    return(-1);
 	}
 	comp->steps = real;
@@ -1153,20 +1183,20 @@
 }
 
 #define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5)	\
-    xmlXPathCompExprAdd(ctxt->comp, (op1), (op2),			\
+    xmlXPathCompExprAdd(ctxt, (op1), (op2),			\
 	                (op), (val), (val2), (val3), (val4), (val5))
 #define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5)			\
-    xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1,		\
+    xmlXPathCompExprAdd(ctxt, ctxt->comp->last, -1,		\
 	                (op), (val), (val2), (val3), (val4), (val5))
 
 #define PUSH_LEAVE_EXPR(op, val, val2)					\
-xmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
+xmlXPathCompExprAdd(ctxt, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
 
 #define PUSH_UNARY_EXPR(op, ch, val, val2)				\
-xmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
+xmlXPathCompExprAdd(ctxt, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
 
 #define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2)			\
-xmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op),			\
+xmlXPathCompExprAdd(ctxt, (ch1), (ch2), (op),			\
 			(val), (val2), 0 ,NULL ,NULL)
 
 /************************************************************************
@@ -2226,7 +2256,7 @@
  *
  * @ctxt:  the XPath context
  * @active: enables/disables (creates/frees) the cache
- * @value: a value with semantics dependant on @options
+ * @value: a value with semantics dependent on @options
  * @options: options (currently only the value 0 is used)
  *
  * Creates/frees an object cache on the XPath context.
@@ -2386,7 +2416,7 @@
 	{
 	    xmlXPathObjectPtr ret;
 	    /*
-	    * Use the nodset-cache.
+	    * Use the nodeset-cache.
 	    */
 	    ret = (xmlXPathObjectPtr)
 		cache->nodesetObjs->items[--cache->nodesetObjs->number];
@@ -2396,6 +2426,7 @@
 		if ((ret->nodesetval->nodeMax == 0) ||
 		    (val->type == XML_NAMESPACE_DECL))
 		{
+                    /* TODO: Check memory error. */
 		    xmlXPathNodeSetAddUnique(ret->nodesetval, val);
 		} else {
 		    ret->nodesetval->nodeTab[0] = val;
@@ -2842,29 +2873,36 @@
  * @ctxt:  an XPath evaluation context
  * @value:  the XPath object
  *
- * Pushes a new XPath object on top of the value stack
+ * Pushes a new XPath object on top of the value stack. If value is NULL,
+ * a memory error is recorded in the parser context.
  *
- * returns the number of items on the value stack
+ * Returns the number of items on the value stack, or -1 in case of error.
  */
 int
 valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
 {
-    if ((ctxt == NULL) || (value == NULL)) return(-1);
+    if (ctxt == NULL) return(-1);
+    if (value == NULL) {
+        /*
+         * A NULL value typically indicates that a memory allocation failed,
+         * so we set ctxt->error here to propagate the error.
+         */
+	ctxt->error = XPATH_MEMORY_ERROR;
+        return(-1);
+    }
     if (ctxt->valueNr >= ctxt->valueMax) {
         xmlXPathObjectPtr *tmp;
 
         if (ctxt->valueMax >= XPATH_MAX_STACK_DEPTH) {
-            xmlXPathErrMemory(NULL, "XPath stack depth limit reached\n");
-            ctxt->error = XPATH_MEMORY_ERROR;
-            return (0);
+            xmlXPathPErrMemory(ctxt, "XPath stack depth limit reached\n");
+            return (-1);
         }
         tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
                                              2 * ctxt->valueMax *
                                              sizeof(ctxt->valueTab[0]));
         if (tmp == NULL) {
-            xmlXPathErrMemory(NULL, "pushing value\n");
-            ctxt->error = XPATH_MEMORY_ERROR;
-            return (0);
+            xmlXPathPErrMemory(ctxt, "pushing value\n");
+            return (-1);
         }
         ctxt->valueMax *= 2;
 	ctxt->valueTab = tmp;
@@ -3320,7 +3358,7 @@
 	return(-1);
 
     /*
-     * Speedup using document order if availble.
+     * Speedup using document order if available.
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
 	(node2->type == XML_ELEMENT_NODE) &&
@@ -3383,7 +3421,7 @@
     if (node1 == node2->next)
 	return(-1);
     /*
-     * Speedup using document order if availble.
+     * Speedup using document order if available.
      */
     if ((node1->type == XML_ELEMENT_NODE) &&
 	(node2->type == XML_ELEMENT_NODE) &&
@@ -3547,6 +3585,7 @@
 	if (val->type == XML_NAMESPACE_DECL) {
 	    xmlNsPtr ns = (xmlNsPtr) val;
 
+            /* TODO: Check memory error. */
 	    ret->nodeTab[ret->nodeNr++] =
 		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
 	} else
@@ -3556,37 +3595,6 @@
 }
 
 /**
- * xmlXPathNodeSetCreateSize:
- * @size:  the initial size of the set
- *
- * Create a new xmlNodeSetPtr of type double and of value @val
- *
- * Returns the newly created object.
- */
-static xmlNodeSetPtr
-xmlXPathNodeSetCreateSize(int size) {
-    xmlNodeSetPtr ret;
-
-    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
-    if (ret == NULL) {
-        xmlXPathErrMemory(NULL, "creating nodeset\n");
-	return(NULL);
-    }
-    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
-    if (size < XML_NODESET_DEFAULT)
-	size = XML_NODESET_DEFAULT;
-    ret->nodeTab = (xmlNodePtr *) xmlMalloc(size * sizeof(xmlNodePtr));
-    if (ret->nodeTab == NULL) {
-	xmlXPathErrMemory(NULL, "creating nodeset\n");
-	xmlFree(ret);
-	return(NULL);
-    }
-    memset(ret->nodeTab, 0 , size * (size_t) sizeof(xmlNodePtr));
-    ret->nodeMax = size;
-    return(ret);
-}
-
-/**
  * xmlXPathNodeSetContains:
  * @cur:  the node-set
  * @val:  the node
@@ -3684,6 +3692,7 @@
         cur->nodeMax *= 2;
 	cur->nodeTab = temp;
     }
+    /* TODO: Check memory error. */
     cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
     return(0);
 }
@@ -3742,6 +3751,7 @@
     if (val->type == XML_NAMESPACE_DECL) {
 	xmlNsPtr ns = (xmlNsPtr) val;
 
+        /* TODO: Check memory error. */
 	cur->nodeTab[cur->nodeNr++] =
 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
     } else
@@ -3796,6 +3806,7 @@
     if (val->type == XML_NAMESPACE_DECL) {
 	xmlNsPtr ns = (xmlNsPtr) val;
 
+        /* TODO: Check memory error. */
 	cur->nodeTab[cur->nodeNr++] =
 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
     } else
@@ -3830,7 +3841,7 @@
 	*  xmlXPathNodeSetDupNs() to the set; thus a pure
 	*  memcpy is not possible.
 	*  If there was a flag on the nodesetval, indicating that
-	*  some temporary nodes are in, that would be helpfull.
+	*  some temporary nodes are in, that would be helpful.
 	*/
 	/*
 	* Optimization: Create an equally sized node-set
@@ -3912,6 +3923,7 @@
 	if (n2->type == XML_NAMESPACE_DECL) {
 	    xmlNsPtr ns = (xmlNsPtr) n2;
 
+            /* TODO: Check memory error. */
 	    val1->nodeTab[val1->nodeNr++] =
 		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
 	} else
@@ -3926,49 +3938,23 @@
  * xmlXPathNodeSetMergeAndClear:
  * @set1:  the first NodeSet or NULL
  * @set2:  the second NodeSet
- * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
  *
- * Merges two nodesets, all nodes from @set2 are added to @set1
- * if @set1 is NULL, a new set is created and copied from @set2.
+ * Merges two nodesets, all nodes from @set2 are added to @set1.
  * Checks for duplicate nodes. Clears set2.
  *
  * Returns @set1 once extended or NULL in case of error.
  */
 static xmlNodeSetPtr
-xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
-			     int hasNullEntries)
+xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
 {
-    if ((set1 == NULL) && (hasNullEntries == 0)) {
-	/*
-	* Note that doing a memcpy of the list, namespace nodes are
-	* just assigned to set1, since set2 is cleared anyway.
-	*/
-	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
-	if (set1 == NULL)
-	    return(NULL);
-	if (set2->nodeNr != 0) {
-	    memcpy(set1->nodeTab, set2->nodeTab,
-		set2->nodeNr * sizeof(xmlNodePtr));
-	    set1->nodeNr = set2->nodeNr;
-	}
-    } else {
+    {
 	int i, j, initNbSet1;
 	xmlNodePtr n1, n2;
 
-	if (set1 == NULL)
-            set1 = xmlXPathNodeSetCreate(NULL);
-        if (set1 == NULL)
-            return (NULL);
-
 	initNbSet1 = set1->nodeNr;
 	for (i = 0;i < set2->nodeNr;i++) {
 	    n2 = set2->nodeTab[i];
 	    /*
-	    * Skip NULLed entries.
-	    */
-	    if (n2 == NULL)
-		continue;
-	    /*
 	    * Skip duplicates.
 	    */
 	    for (j = 0; j < initNbSet1; j++) {
@@ -4033,49 +4019,21 @@
  * xmlXPathNodeSetMergeAndClearNoDupls:
  * @set1:  the first NodeSet or NULL
  * @set2:  the second NodeSet
- * @hasSet2NsNodes: 1 if set2 contains namespaces nodes
  *
- * Merges two nodesets, all nodes from @set2 are added to @set1
- * if @set1 is NULL, a new set is created and copied from @set2.
- * Doesn't chack for duplicate nodes. Clears set2.
+ * Merges two nodesets, all nodes from @set2 are added to @set1.
+ * Doesn't check for duplicate nodes. Clears set2.
  *
  * Returns @set1 once extended or NULL in case of error.
  */
 static xmlNodeSetPtr
-xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
-				    int hasNullEntries)
+xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2)
 {
-    if (set2 == NULL)
-	return(set1);
-    if ((set1 == NULL) && (hasNullEntries == 0)) {
-	/*
-	* Note that doing a memcpy of the list, namespace nodes are
-	* just assigned to set1, since set2 is cleared anyway.
-	*/
-	set1 = xmlXPathNodeSetCreateSize(set2->nodeNr);
-	if (set1 == NULL)
-	    return(NULL);
-	if (set2->nodeNr != 0) {
-	    memcpy(set1->nodeTab, set2->nodeTab,
-		set2->nodeNr * sizeof(xmlNodePtr));
-	    set1->nodeNr = set2->nodeNr;
-	}
-    } else {
+    {
 	int i;
 	xmlNodePtr n2;
 
-	if (set1 == NULL)
-	    set1 = xmlXPathNodeSetCreate(NULL);
-        if (set1 == NULL)
-            return (NULL);
-
 	for (i = 0;i < set2->nodeNr;i++) {
 	    n2 = set2->nodeTab[i];
-	    /*
-	    * Skip NULLed entries.
-	    */
-	    if (n2 == NULL)
-		continue;
 	    if (set1->nodeMax == 0) {
 		set1->nodeTab = (xmlNodePtr *) xmlMalloc(
 		    XML_NODESET_DEFAULT * sizeof(xmlNodePtr));
@@ -4346,6 +4304,7 @@
     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
     ret->type = XPATH_NODESET;
     ret->boolval = 0;
+    /* TODO: Check memory error. */
     ret->nodesetval = xmlXPathNodeSetCreate(val);
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
 #ifdef XP_DEBUG_OBJ_USAGE
@@ -4406,6 +4365,7 @@
         ret = xmlXPathNewNodeSet(val->nodeTab[0]);
         if (ret) {
             for (i = 1; i < val->nodeNr; ++i) {
+                /* TODO: Propagate memory error. */
                 if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i])
 		    < 0) break;
 	    }
@@ -4477,6 +4437,7 @@
     if (xmlXPathNodeSetIsEmpty(nodes2))
 	return(nodes1);
 
+    /* TODO: Check memory error. */
     ret = xmlXPathNodeSetCreate(NULL);
     if (xmlXPathNodeSetIsEmpty(nodes1))
 	return(ret);
@@ -4486,6 +4447,7 @@
     for (i = 0; i < l1; i++) {
 	cur = xmlXPathNodeSetItem(nodes1, i);
 	if (!xmlXPathNodeSetContains(nodes2, cur)) {
+            /* TODO: Propagate memory error. */
 	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
 	        break;
 	}
@@ -4522,6 +4484,7 @@
     for (i = 0; i < l1; i++) {
 	cur = xmlXPathNodeSetItem(nodes1, i);
 	if (xmlXPathNodeSetContains(nodes2, cur)) {
+            /* TODO: Propagate memory error. */
 	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
 	        break;
 	}
@@ -4560,6 +4523,7 @@
 	strval = xmlXPathCastNodeToString(cur);
 	if (xmlHashLookup(hash, strval) == NULL) {
 	    xmlHashAddEntry(hash, strval, strval);
+            /* TODO: Propagate memory error. */
 	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
 	        break;
 	} else {
@@ -4653,6 +4617,7 @@
 	cur = xmlXPathNodeSetItem(nodes, i);
 	if (cur == node)
 	    break;
+        /* TODO: Propagate memory error. */
 	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
 	    break;
     }
@@ -4758,6 +4723,7 @@
 	cur = xmlXPathNodeSetItem(nodes, i);
 	if (cur == node)
 	    break;
+        /* TODO: Propagate memory error. */
 	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
 	    break;
     }
@@ -5457,6 +5423,7 @@
 	    break;
 #endif
 	case XPATH_NODESET:
+            /* TODO: Check memory error. */
 	    ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
 	    /* Do not deallocate the copied tree value */
 	    ret->boolval = 0;
@@ -5944,7 +5911,7 @@
 	return(NAN);
     switch (val->type) {
     case XPATH_UNDEFINED:
-#ifdef DEGUB_EXPR
+#ifdef DEBUG_EXPR
 	xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
 #endif
 	ret = NAN;
@@ -6153,6 +6120,9 @@
     ret->contextSize = -1;
     ret->proximityPosition = -1;
 
+    ret->maxDepth = INT_MAX;
+    ret->maxParserDepth = INT_MAX;
+
 #ifdef XP_DEFAULT_CACHE_ON
     if (xmlXPathContextSetCache(ret, 1, -1, 0) == -1) {
 	xmlXPathFreeContext(ret);
@@ -6643,6 +6613,7 @@
 
     values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
     if (values2 == NULL) {
+        /* TODO: Propagate memory error. */
         xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlXPathFreeObject(arg1);
 	xmlXPathFreeObject(arg2);
@@ -6903,11 +6874,13 @@
 
     values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
     if (values1 == NULL) {
+        /* TODO: Propagate memory error. */
         xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	return(0);
     }
     hashs1 = (unsigned int *) xmlMalloc(ns1->nodeNr * sizeof(unsigned int));
     if (hashs1 == NULL) {
+        /* TODO: Propagate memory error. */
         xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(values1);
 	return(0);
@@ -6915,6 +6888,7 @@
     memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
     values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
     if (values2 == NULL) {
+        /* TODO: Propagate memory error. */
         xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(hashs1);
 	xmlFree(values1);
@@ -6922,6 +6896,7 @@
     }
     hashs2 = (unsigned int *) xmlMalloc(ns2->nodeNr * sizeof(unsigned int));
     if (hashs2 == NULL) {
+        /* TODO: Propagate memory error. */
         xmlXPathErrMemory(NULL, "comparing nodesets\n");
 	xmlFree(hashs1);
 	xmlFree(values1);
@@ -7551,6 +7526,7 @@
  * The numeric operators convert their operands to numbers as if
  * by calling the number function.
  */
+ATTRIBUTE_NO_SANITIZE("float-divide-by-zero")
 void
 xmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
     xmlXPathObjectPtr arg;
@@ -7623,7 +7599,7 @@
  * Used for merging node sets in xmlXPathCollectAndTest().
  */
 typedef xmlNodeSetPtr (*xmlXPathNodeSetMergeFunction)
-		    (xmlNodeSetPtr, xmlNodeSetPtr, int);
+		    (xmlNodeSetPtr, xmlNodeSetPtr);
 
 
 /**
@@ -8562,28 +8538,9 @@
 
     if ((cur == NULL) || (cur->nodesetval == NULL))
 	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
-    else if ((cur->type == XPATH_NODESET) || (cur->type == XPATH_XSLT_TREE)) {
+    else
 	valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context,
 	    (double) cur->nodesetval->nodeNr));
-    } else {
-	if ((cur->nodesetval->nodeNr != 1) ||
-	    (cur->nodesetval->nodeTab == NULL)) {
-	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) 0));
-	} else {
-	    xmlNodePtr tmp;
-	    int i = 0;
-
-	    tmp = cur->nodesetval->nodeTab[0];
-	    if ((tmp != NULL) && (tmp->type != XML_NAMESPACE_DECL)) {
-		tmp = tmp->children;
-		while (tmp != NULL) {
-		    tmp = tmp->next;
-		    i++;
-		}
-	    }
-	    valuePush(ctxt, xmlXPathCacheNewFloat(ctxt->context, (double) i));
-	}
-    }
     xmlXPathReleaseObject(ctxt->context, cur);
 }
 
@@ -8621,7 +8578,7 @@
 	     * We used to check the fact that the value passed
 	     * was an NCName, but this generated much troubles for
 	     * me and Aleksey Sanin, people blatantly violated that
-	     * constaint, like Visa3D spec.
+	     * constraint, like Visa3D spec.
 	     * if (xmlValidateNCName(ID, 1) == 0)
 	     */
 	    attr = xmlGetID(doc, ID);
@@ -8632,6 +8589,7 @@
 		    elem = (xmlNodePtr) attr;
 		else
 		    elem = NULL;
+                /* TODO: Check memory error. */
 		if (elem != NULL)
 		    xmlXPathNodeSetAdd(ret, elem);
 	    }
@@ -8675,18 +8633,15 @@
 	xmlNodeSetPtr ns;
 	int i;
 
+        /* TODO: Check memory error. */
 	ret = xmlXPathNodeSetCreate(NULL);
-        /*
-         * FIXME -- in an out-of-memory condition this will behave badly.
-         * The solution is not clear -- we already popped an item from
-         * ctxt, so the object is in a corrupt state.
-         */
 
 	if (obj->nodesetval != NULL) {
 	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
 		tokens =
 		    xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
 		ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
+                /* TODO: Check memory error. */
 		ret = xmlXPathNodeSetMerge(ret, ns);
 		xmlXPathFreeNodeSet(ns);
 		if (tokens != NULL)
@@ -8698,6 +8653,7 @@
 	return;
     }
     obj = xmlXPathCacheConvertString(ctxt->context, obj);
+    if (obj == NULL) return;
     ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
     valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, ret));
     xmlXPathReleaseObject(ctxt->context, obj);
@@ -9135,8 +9091,7 @@
 xmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlXPathObjectPtr str, start, len;
     double le=0, in;
-    int i, l, m;
-    xmlChar *ret;
+    int i = 1, j = INT_MAX;
 
     if (nargs < 2) {
 	CHECK_ARITY(2);
@@ -9163,67 +9118,42 @@
     CAST_TO_STRING;
     CHECK_TYPE(XPATH_STRING);
     str = valuePop(ctxt);
-    m = xmlUTF8Strlen((const unsigned char *)str->stringval);
 
-    /*
-     * If last pos not present, calculate last position
-    */
-    if (nargs != 3) {
-	le = (double)m;
-	if (in < 1.0)
-	    in = 1.0;
+    if (!(in < INT_MAX)) { /* Logical NOT to handle NaNs */
+        i = INT_MAX;
+    } else if (in >= 1.0) {
+        i = (int)in;
+        if (in - floor(in) >= 0.5)
+            i += 1;
     }
 
-    /* Need to check for the special cases where either
-     * the index is NaN, the length is NaN, or both
-     * arguments are infinity (relying on Inf + -Inf = NaN)
-     */
-    if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
-        /*
-         * To meet the requirements of the spec, the arguments
-	 * must be converted to integer format before
-	 * initial index calculations are done
-         *
-         * First we go to integer form, rounding up
-	 * and checking for special cases
-         */
-        i = (int) in;
-        if (((double)i)+0.5 <= in) i++;
+    if (nargs == 3) {
+        double rin, rle, end;
 
-	if (xmlXPathIsInf(le) == 1) {
-	    l = m;
-	    if (i < 1)
-		i = 1;
-	}
-	else if (xmlXPathIsInf(le) == -1 || le < 0.0)
-	    l = 0;
-	else {
-	    l = (int) le;
-	    if (((double)l)+0.5 <= le) l++;
-	}
+        rin = floor(in);
+        if (in - rin >= 0.5)
+            rin += 1.0;
 
-	/* Now we normalize inidices */
-        i -= 1;
-        l += i;
-        if (i < 0)
-            i = 0;
-        if (l > m)
-            l = m;
+        rle = floor(le);
+        if (le - rle >= 0.5)
+            rle += 1.0;
 
-        /* number of chars to copy */
-        l -= i;
-
-        ret = xmlUTF8Strsub(str->stringval, i, l);
+        end = rin + rle;
+        if (!(end >= 1.0)) { /* Logical NOT to handle NaNs */
+            j = 1;
+        } else if (end < INT_MAX) {
+            j = (int)end;
+        }
     }
-    else {
-        ret = NULL;
-    }
-    if (ret == NULL)
-	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
-    else {
+
+    if (i < j) {
+        xmlChar *ret = xmlUTF8Strsub(str->stringval, i - 1, j - i);
 	valuePush(ctxt, xmlXPathCacheNewString(ctxt->context, ret));
 	xmlFree(ret);
+    } else {
+	valuePush(ctxt, xmlXPathCacheNewCString(ctxt->context, ""));
     }
+
     xmlXPathReleaseObject(ctxt->context, str);
 }
 
@@ -9682,7 +9612,12 @@
     CAST_TO_NUMBER;
     CHECK_TYPE(XPATH_NUMBER);
 
+#ifdef _AIX
+    /* Work around buggy ceil() function on AIX */
+    ctxt->value->floatval = copysign(ceil(ctxt->value->floatval), ctxt->value->floatval);
+#else
     ctxt->value->floatval = ceil(ctxt->value->floatval);
+#endif
 }
 
 /**
@@ -9999,15 +9934,19 @@
 		   (IS_COMBINING(c)) ||
 		   (IS_EXTENDER(c))) {
 		if (len + 10 > max) {
+                    xmlChar *tmp;
                     if (max > XML_MAX_NAME_LENGTH) {
+                        xmlFree(buffer);
                         XP_ERRORNULL(XPATH_EXPR_ERROR);
                     }
 		    max *= 2;
-		    buffer = (xmlChar *) xmlRealloc(buffer,
-			                            max * sizeof(xmlChar));
-		    if (buffer == NULL) {
+		    tmp = (xmlChar *) xmlRealloc(buffer,
+			                         max * sizeof(xmlChar));
+		    if (tmp == NULL) {
+                        xmlFree(buffer);
 			XP_ERRORNULL(XPATH_MEMORY_ERROR);
 		    }
+                    buffer = tmp;
 		}
 		COPY_BUF(l,buffer,len,c);
 		NEXTL(l);
@@ -10149,6 +10088,7 @@
     int ok = 0;
     int exponent = 0;
     int is_exponent_negative = 0;
+    xmlXPathObjectPtr num;
 #ifdef __GNUC__
     unsigned long tmp = 0;
     double temp;
@@ -10221,8 +10161,13 @@
             exponent = -exponent;
         ret *= pow(10.0, (double) exponent);
     }
-    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
-                   xmlXPathCacheNewFloat(ctxt->context, ret), NULL);
+    num = xmlXPathCacheNewFloat(ctxt->context, ret);
+    if (num == NULL) {
+	ctxt->error = XPATH_MEMORY_ERROR;
+    } else if (PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, num,
+                              NULL) == -1) {
+        xmlXPathReleaseObject(ctxt->context, num);
+    }
 }
 
 /**
@@ -10284,6 +10229,7 @@
 xmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
     const xmlChar *q;
     xmlChar *ret = NULL;
+    xmlXPathObjectPtr lit;
 
     if (CUR == '"') {
         NEXT;
@@ -10311,8 +10257,13 @@
 	XP_ERROR(XPATH_START_LITERAL_ERROR);
     }
     if (ret == NULL) return;
-    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
-	           xmlXPathCacheNewString(ctxt->context, ret), NULL);
+    lit = xmlXPathCacheNewString(ctxt->context, ret);
+    if (lit == NULL) {
+	ctxt->error = XPATH_MEMORY_ERROR;
+    } else if (PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0, lit,
+                              NULL) == -1) {
+        xmlXPathReleaseObject(ctxt->context, lit);
+    }
     xmlFree(ret);
 }
 
@@ -10349,8 +10300,10 @@
 	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
     }
     ctxt->comp->last = -1;
-    PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
-	           name, prefix);
+    if (PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0, name, prefix) == -1) {
+        xmlFree(prefix);
+        xmlFree(name);
+    }
     SKIP_BLANKS;
     if ((ctxt->context != NULL) && (ctxt->context->flags & XML_XPATH_NOVAR)) {
 	XP_ERROR(XPATH_FORBID_VARIABLE_ERROR);
@@ -10457,8 +10410,10 @@
 	    SKIP_BLANKS;
 	}
     }
-    PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
-	           name, prefix);
+    if (PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, name, prefix) == -1) {
+        xmlFree(prefix);
+        xmlFree(name);
+    }
     NEXT;
     SKIP_BLANKS;
 }
@@ -10899,10 +10854,7 @@
     xmlXPathCompAdditiveExpr(ctxt);
     CHECK_ERROR;
     SKIP_BLANKS;
-    while ((CUR == '<') ||
-           (CUR == '>') ||
-           ((CUR == '<') && (NXT(1) == '=')) ||
-           ((CUR == '>') && (NXT(1) == '='))) {
+    while ((CUR == '<') || (CUR == '>')) {
 	int inf, strict;
 	int op1 = ctxt->comp->last;
 
@@ -10995,6 +10947,14 @@
  */
 static void
 xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
+    xmlXPathContextPtr xpctxt = ctxt->context;
+
+    if (xpctxt != NULL) {
+        if (xpctxt->depth >= xpctxt->maxParserDepth)
+            XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
+        xpctxt->depth += 1;
+    }
+
     xmlXPathCompAndExpr(ctxt);
     CHECK_ERROR;
     SKIP_BLANKS;
@@ -11016,6 +10976,9 @@
 	*/
 	PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
     }
+
+    if (xpctxt != NULL)
+        xpctxt->depth -= 1;
 }
 
 /**
@@ -11091,7 +11054,7 @@
  */
 static xmlChar *
 xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
-	             xmlXPathTypeVal *type, const xmlChar **prefix,
+	             xmlXPathTypeVal *type, xmlChar **prefix,
 		     xmlChar *name) {
     int blanks;
 
@@ -11322,7 +11285,7 @@
 	SKIP_BLANKS;
     } else {
 	xmlChar *name = NULL;
-	const xmlChar *prefix = NULL;
+	xmlChar *prefix = NULL;
 	xmlXPathTestVal test = (xmlXPathTestVal) 0;
 	xmlXPathAxisVal axis = (xmlXPathAxisVal) 0;
 	xmlXPathTypeVal type = (xmlXPathTypeVal) 0;
@@ -11432,9 +11395,11 @@
 	    PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
 	} else
 #endif
-	    PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
-			   test, type, (void *)prefix, (void *)name);
-
+        if (PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
+                           test, type, (void *)prefix, (void *)name) == -1) {
+            xmlFree(prefix);
+            xmlFree(name);
+        }
     }
 #ifdef DEBUG_STEP
     xmlGenericError(xmlGenericErrorContext, "Step : ");
@@ -11634,11 +11599,277 @@
 }
 #endif /* DEBUG_STEP */
 
-static int
+/**
+ * xmlXPathNodeSetFilter:
+ * @ctxt:  the XPath Parser context
+ * @set: the node set to filter
+ * @filterOpIndex: the index of the predicate/filter op
+ * @minPos: minimum position in the filtered set (1-based)
+ * @maxPos: maximum position in the filtered set (1-based)
+ * @hasNsNodes: true if the node set may contain namespace nodes
+ *
+ * Filter a node set, keeping only nodes for which the predicate expression
+ * matches. Afterwards, keep only nodes between minPos and maxPos in the
+ * filtered result.
+ */
+static void
+xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt,
+		      xmlNodeSetPtr set,
+		      int filterOpIndex,
+                      int minPos, int maxPos,
+		      int hasNsNodes)
+{
+    xmlXPathContextPtr xpctxt;
+    xmlNodePtr oldnode;
+    xmlDocPtr olddoc;
+    xmlXPathStepOpPtr filterOp;
+    int oldcs, oldpp;
+    int i, j, pos;
+
+    if ((set == NULL) || (set->nodeNr == 0))
+        return;
+
+    /*
+    * Check if the node set contains a sufficient number of nodes for
+    * the requested range.
+    */
+    if (set->nodeNr < minPos) {
+        xmlXPathNodeSetClear(set, hasNsNodes);
+        return;
+    }
+
+    xpctxt = ctxt->context;
+    oldnode = xpctxt->node;
+    olddoc = xpctxt->doc;
+    oldcs = xpctxt->contextSize;
+    oldpp = xpctxt->proximityPosition;
+    filterOp = &ctxt->comp->steps[filterOpIndex];
+
+    xpctxt->contextSize = set->nodeNr;
+
+    for (i = 0, j = 0, pos = 1; i < set->nodeNr; i++) {
+        xmlNodePtr node = set->nodeTab[i];
+        int res;
+
+        xpctxt->node = node;
+        xpctxt->proximityPosition = i + 1;
+
+        /*
+        * Also set the xpath document in case things like
+        * key() are evaluated in the predicate.
+        *
+        * TODO: Get real doc for namespace nodes.
+        */
+        if ((node->type != XML_NAMESPACE_DECL) &&
+            (node->doc != NULL))
+            xpctxt->doc = node->doc;
+
+        res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1);
+
+        if (ctxt->error != XPATH_EXPRESSION_OK)
+            goto exit;
+        if (res < 0) {
+            /* Shouldn't happen */
+            xmlXPathErr(ctxt, XPATH_EXPR_ERROR);
+            goto exit;
+        }
+
+        if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) {
+            if (i != j) {
+                set->nodeTab[j] = node;
+                set->nodeTab[i] = NULL;
+            }
+
+            j += 1;
+        } else {
+            /* Remove the entry from the initial node set. */
+            set->nodeTab[i] = NULL;
+            if (node->type == XML_NAMESPACE_DECL)
+                xmlXPathNodeSetFreeNs((xmlNsPtr) node);
+        }
+
+        if (res != 0) {
+            if (pos == maxPos) {
+                /* Clear remaining nodes and exit loop. */
+                if (hasNsNodes) {
+                    for (i++; i < set->nodeNr; i++) {
+                        node = set->nodeTab[i];
+                        if ((node != NULL) &&
+                            (node->type == XML_NAMESPACE_DECL))
+                            xmlXPathNodeSetFreeNs((xmlNsPtr) node);
+                    }
+                }
+                break;
+            }
+
+            pos += 1;
+        }
+    }
+
+    set->nodeNr = j;
+
+    /* If too many elements were removed, shrink table to preserve memory. */
+    if ((set->nodeMax > XML_NODESET_DEFAULT) &&
+        (set->nodeNr < set->nodeMax / 2)) {
+        xmlNodePtr *tmp;
+        int nodeMax = set->nodeNr;
+
+        if (nodeMax < XML_NODESET_DEFAULT)
+            nodeMax = XML_NODESET_DEFAULT;
+        tmp = (xmlNodePtr *) xmlRealloc(set->nodeTab,
+                nodeMax * sizeof(xmlNodePtr));
+        if (tmp == NULL) {
+            xmlXPathPErrMemory(ctxt, "shrinking nodeset\n");
+        } else {
+            set->nodeTab = tmp;
+            set->nodeMax = nodeMax;
+        }
+    }
+
+exit:
+    xpctxt->node = oldnode;
+    xpctxt->doc = olddoc;
+    xpctxt->contextSize = oldcs;
+    xpctxt->proximityPosition = oldpp;
+}
+
+#ifdef LIBXML_XPTR_ENABLED
+/**
+ * xmlXPathLocationSetFilter:
+ * @ctxt:  the XPath Parser context
+ * @locset: the location set to filter
+ * @filterOpIndex: the index of the predicate/filter op
+ * @minPos: minimum position in the filtered set (1-based)
+ * @maxPos: maximum position in the filtered set (1-based)
+ *
+ * Filter a location set, keeping only nodes for which the predicate
+ * expression matches. Afterwards, keep only nodes between minPos and maxPos
+ * in the filtered result.
+ */
+static void
+xmlXPathLocationSetFilter(xmlXPathParserContextPtr ctxt,
+		          xmlLocationSetPtr locset,
+		          int filterOpIndex,
+                          int minPos, int maxPos)
+{
+    xmlXPathContextPtr xpctxt;
+    xmlNodePtr oldnode;
+    xmlDocPtr olddoc;
+    xmlXPathStepOpPtr filterOp;
+    int oldcs, oldpp;
+    int i, j, pos;
+
+    if ((locset == NULL) || (locset->locNr == 0) || (filterOpIndex == -1))
+        return;
+
+    xpctxt = ctxt->context;
+    oldnode = xpctxt->node;
+    olddoc = xpctxt->doc;
+    oldcs = xpctxt->contextSize;
+    oldpp = xpctxt->proximityPosition;
+    filterOp = &ctxt->comp->steps[filterOpIndex];
+
+    xpctxt->contextSize = locset->locNr;
+
+    for (i = 0, j = 0, pos = 1; i < locset->locNr; i++) {
+        xmlNodePtr contextNode = locset->locTab[i]->user;
+        int res;
+
+        xpctxt->node = contextNode;
+        xpctxt->proximityPosition = i + 1;
+
+        /*
+        * Also set the xpath document in case things like
+        * key() are evaluated in the predicate.
+        *
+        * TODO: Get real doc for namespace nodes.
+        */
+        if ((contextNode->type != XML_NAMESPACE_DECL) &&
+            (contextNode->doc != NULL))
+            xpctxt->doc = contextNode->doc;
+
+        res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1);
+
+        if (ctxt->error != XPATH_EXPRESSION_OK)
+            goto exit;
+        if (res < 0) {
+            /* Shouldn't happen */
+            xmlXPathErr(ctxt, XPATH_EXPR_ERROR);
+            goto exit;
+        }
+
+        if ((res != 0) && ((pos >= minPos) && (pos <= maxPos))) {
+            if (i != j) {
+                locset->locTab[j] = locset->locTab[i];
+                locset->locTab[i] = NULL;
+            }
+
+            j += 1;
+        } else {
+            /* Remove the entry from the initial location set. */
+            xmlXPathFreeObject(locset->locTab[i]);
+            locset->locTab[i] = NULL;
+        }
+
+        if (res != 0) {
+            if (pos == maxPos) {
+                /* Clear remaining nodes and exit loop. */
+                for (i++; i < locset->locNr; i++) {
+                    xmlXPathFreeObject(locset->locTab[i]);
+                }
+                break;
+            }
+
+            pos += 1;
+        }
+    }
+
+    locset->locNr = j;
+
+    /* If too many elements were removed, shrink table to preserve memory. */
+    if ((locset->locMax > XML_NODESET_DEFAULT) &&
+        (locset->locNr < locset->locMax / 2)) {
+        xmlXPathObjectPtr *tmp;
+        int locMax = locset->locNr;
+
+        if (locMax < XML_NODESET_DEFAULT)
+            locMax = XML_NODESET_DEFAULT;
+        tmp = (xmlXPathObjectPtr *) xmlRealloc(locset->locTab,
+                locMax * sizeof(xmlXPathObjectPtr));
+        if (tmp == NULL) {
+            xmlXPathPErrMemory(ctxt, "shrinking locset\n");
+        } else {
+            locset->locTab = tmp;
+            locset->locMax = locMax;
+        }
+    }
+
+exit:
+    xpctxt->node = oldnode;
+    xpctxt->doc = olddoc;
+    xpctxt->contextSize = oldcs;
+    xpctxt->proximityPosition = oldpp;
+}
+#endif /* LIBXML_XPTR_ENABLED */
+
+/**
+ * xmlXPathCompOpEvalPredicate:
+ * @ctxt:  the XPath Parser context
+ * @op: the predicate op
+ * @set: the node set to filter
+ * @minPos: minimum position in the filtered set (1-based)
+ * @maxPos: maximum position in the filtered set (1-based)
+ * @hasNsNodes: true if the node set may contain namespace nodes
+ *
+ * Filter a node set, keeping only nodes for which the sequence of predicate
+ * expressions matches. Afterwards, keep only nodes between minPos and maxPos
+ * in the filtered result.
+ */
+static void
 xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
 			    xmlXPathStepOpPtr op,
 			    xmlNodeSetPtr set,
-			    int contextSize,
+                            int minPos, int maxPos,
 			    int hasNsNodes)
 {
     if (op->ch1 != -1) {
@@ -11647,353 +11878,21 @@
 	* Process inner predicates first.
 	*/
 	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
-	    /*
-	    * TODO: raise an internal error.
-	    */
+            xmlGenericError(xmlGenericErrorContext,
+                "xmlXPathCompOpEvalPredicate: Expected a predicate\n");
+            XP_ERROR(XPATH_INVALID_OPERAND);
 	}
-	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
-	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
-	CHECK_ERROR0;
-	if (contextSize <= 0)
-	    return(0);
+        if (ctxt->context->depth >= ctxt->context->maxDepth)
+            XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED);
+        ctxt->context->depth += 1;
+	xmlXPathCompOpEvalPredicate(ctxt, &comp->steps[op->ch1], set,
+                                    1, set->nodeNr, hasNsNodes);
+        ctxt->context->depth -= 1;
+	CHECK_ERROR;
     }
-    if (op->ch2 != -1) {
-	xmlXPathContextPtr xpctxt = ctxt->context;
-	xmlNodePtr contextNode, oldContextNode;
-	xmlDocPtr oldContextDoc;
-        int oldcs, oldpp;
-	int i, res, contextPos = 0, newContextSize;
-	xmlXPathStepOpPtr exprOp;
-	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
 
-#ifdef LIBXML_XPTR_ENABLED
-	/*
-	* URGENT TODO: Check the following:
-	*  We don't expect location sets if evaluating prediates, right?
-	*  Only filters should expect location sets, right?
-	*/
-#endif
-	/*
-	* SPEC XPath 1.0:
-	*  "For each node in the node-set to be filtered, the
-	*  PredicateExpr is evaluated with that node as the
-	*  context node, with the number of nodes in the
-	*  node-set as the context size, and with the proximity
-	*  position of the node in the node-set with respect to
-	*  the axis as the context position;"
-	* @oldset is the node-set" to be filtered.
-	*
-	* SPEC XPath 1.0:
-	*  "only predicates change the context position and
-	*  context size (see [2.4 Predicates])."
-	* Example:
-	*   node-set  context pos
-	*    nA         1
-	*    nB         2
-	*    nC         3
-	*   After applying predicate [position() > 1] :
-	*   node-set  context pos
-	*    nB         1
-	*    nC         2
-	*/
-	oldContextNode = xpctxt->node;
-	oldContextDoc = xpctxt->doc;
-        oldcs = xpctxt->contextSize;
-        oldpp = xpctxt->proximityPosition;
-	/*
-	* Get the expression of this predicate.
-	*/
-	exprOp = &ctxt->comp->steps[op->ch2];
-	newContextSize = 0;
-	for (i = 0; i < set->nodeNr; i++) {
-	    if (set->nodeTab[i] == NULL)
-		continue;
-
-	    contextNode = set->nodeTab[i];
-	    xpctxt->node = contextNode;
-	    xpctxt->contextSize = contextSize;
-	    xpctxt->proximityPosition = ++contextPos;
-
-	    /*
-	    * Also set the xpath document in case things like
-	    * key() are evaluated in the predicate.
-	    */
-	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
-		(contextNode->doc != NULL))
-		xpctxt->doc = contextNode->doc;
-	    /*
-	    * Evaluate the predicate expression with 1 context node
-	    * at a time; this node is packaged into a node set; this
-	    * node set is handed over to the evaluation mechanism.
-	    */
-	    if (contextObj == NULL)
-		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
-	    else {
-		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
-		    contextNode) < 0) {
-		    ctxt->error = XPATH_MEMORY_ERROR;
-		    goto evaluation_exit;
-		}
-	    }
-
-	    valuePush(ctxt, contextObj);
-
-	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
-
-	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
-		xmlXPathNodeSetClear(set, hasNsNodes);
-		newContextSize = 0;
-		goto evaluation_exit;
-	    }
-
-	    if (res != 0) {
-		newContextSize++;
-	    } else {
-		/*
-		* Remove the entry from the initial node set.
-		*/
-		set->nodeTab[i] = NULL;
-		if (contextNode->type == XML_NAMESPACE_DECL)
-		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
-	    }
-	    if (ctxt->value == contextObj) {
-		/*
-		* Don't free the temporary XPath object holding the
-		* context node, in order to avoid massive recreation
-		* inside this loop.
-		*/
-		valuePop(ctxt);
-		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
-	    } else {
-		/*
-		* TODO: The object was lost in the evaluation machinery.
-		*  Can this happen? Maybe in internal-error cases.
-		*/
-		contextObj = NULL;
-	    }
-	}
-
-	if (contextObj != NULL) {
-	    if (ctxt->value == contextObj)
-		valuePop(ctxt);
-	    xmlXPathReleaseObject(xpctxt, contextObj);
-	}
-evaluation_exit:
-	if (exprRes != NULL)
-	    xmlXPathReleaseObject(ctxt->context, exprRes);
-	/*
-	* Reset/invalidate the context.
-	*/
-	xpctxt->node = oldContextNode;
-	xpctxt->doc = oldContextDoc;
-	xpctxt->contextSize = oldcs;
-	xpctxt->proximityPosition = oldpp;
-	return(newContextSize);
-    }
-    return(contextSize);
-}
-
-static int
-xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
-				      xmlXPathStepOpPtr op,
-				      xmlNodeSetPtr set,
-				      int contextSize,
-				      int minPos,
-				      int maxPos,
-				      int hasNsNodes)
-{
-    if (op->ch1 != -1) {
-	xmlXPathCompExprPtr comp = ctxt->comp;
-	if (comp->steps[op->ch1].op != XPATH_OP_PREDICATE) {
-	    /*
-	    * TODO: raise an internal error.
-	    */
-	}
-	contextSize = xmlXPathCompOpEvalPredicate(ctxt,
-	    &comp->steps[op->ch1], set, contextSize, hasNsNodes);
-	CHECK_ERROR0;
-	if (contextSize <= 0)
-	    return(0);
-    }
-    /*
-    * Check if the node set contains a sufficient number of nodes for
-    * the requested range.
-    */
-    if (contextSize < minPos) {
-	xmlXPathNodeSetClear(set, hasNsNodes);
-	return(0);
-    }
-    if (op->ch2 == -1) {
-	/*
-	* TODO: Can this ever happen?
-	*/
-	return (contextSize);
-    } else {
-	xmlDocPtr oldContextDoc;
-        int oldcs, oldpp;
-	int i, pos = 0, newContextSize = 0, contextPos = 0, res;
-	xmlXPathStepOpPtr exprOp;
-	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
-	xmlNodePtr oldContextNode, contextNode = NULL;
-	xmlXPathContextPtr xpctxt = ctxt->context;
-        int frame;
-
-#ifdef LIBXML_XPTR_ENABLED
-	    /*
-	    * URGENT TODO: Check the following:
-	    *  We don't expect location sets if evaluating prediates, right?
-	    *  Only filters should expect location sets, right?
-	*/
-#endif /* LIBXML_XPTR_ENABLED */
-
-	/*
-	* Save old context.
-	*/
-	oldContextNode = xpctxt->node;
-	oldContextDoc = xpctxt->doc;
-        oldcs = xpctxt->contextSize;
-        oldpp = xpctxt->proximityPosition;
-	/*
-	* Get the expression of this predicate.
-	*/
-	exprOp = &ctxt->comp->steps[op->ch2];
-	for (i = 0; i < set->nodeNr; i++) {
-            xmlXPathObjectPtr tmp;
-
-	    if (set->nodeTab[i] == NULL)
-		continue;
-
-	    contextNode = set->nodeTab[i];
-	    xpctxt->node = contextNode;
-	    xpctxt->contextSize = contextSize;
-	    xpctxt->proximityPosition = ++contextPos;
-
-	    /*
-	    * Initialize the new set.
-	    * Also set the xpath document in case things like
-	    * key() evaluation are attempted on the predicate
-	    */
-	    if ((contextNode->type != XML_NAMESPACE_DECL) &&
-		(contextNode->doc != NULL))
-		xpctxt->doc = contextNode->doc;
-	    /*
-	    * Evaluate the predicate expression with 1 context node
-	    * at a time; this node is packaged into a node set; this
-	    * node set is handed over to the evaluation mechanism.
-	    */
-	    if (contextObj == NULL)
-		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
-	    else {
-		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
-		    contextNode) < 0) {
-		    ctxt->error = XPATH_MEMORY_ERROR;
-		    goto evaluation_exit;
-		}
-	    }
-
-	    valuePush(ctxt, contextObj);
-            frame = xmlXPathSetFrame(ctxt);
-	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
-            xmlXPathPopFrame(ctxt, frame);
-            tmp = valuePop(ctxt);
-
-	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
-                while (tmp != contextObj) {
-                    /*
-                     * Free up the result
-                     * then pop off contextObj, which will be freed later
-                     */
-                    xmlXPathReleaseObject(xpctxt, tmp);
-                    tmp = valuePop(ctxt);
-                }
-		goto evaluation_error;
-	    }
-            /* push the result back onto the stack */
-            valuePush(ctxt, tmp);
-
-	    if (res)
-		pos++;
-
-	    if (res && (pos >= minPos) && (pos <= maxPos)) {
-		/*
-		* Fits in the requested range.
-		*/
-		newContextSize++;
-		if (minPos == maxPos) {
-		    /*
-		    * Only 1 node was requested.
-		    */
-		    if (contextNode->type == XML_NAMESPACE_DECL) {
-			/*
-			* As always: take care of those nasty
-			* namespace nodes.
-			*/
-			set->nodeTab[i] = NULL;
-		    }
-		    xmlXPathNodeSetClear(set, hasNsNodes);
-		    set->nodeNr = 1;
-		    set->nodeTab[0] = contextNode;
-		    goto evaluation_exit;
-		}
-		if (pos == maxPos) {
-		    /*
-		    * We are done.
-		    */
-		    xmlXPathNodeSetClearFromPos(set, i +1, hasNsNodes);
-		    goto evaluation_exit;
-		}
-	    } else {
-		/*
-		* Remove the entry from the initial node set.
-		*/
-		set->nodeTab[i] = NULL;
-		if (contextNode->type == XML_NAMESPACE_DECL)
-		    xmlXPathNodeSetFreeNs((xmlNsPtr) contextNode);
-	    }
-	    if (exprRes != NULL) {
-		xmlXPathReleaseObject(ctxt->context, exprRes);
-		exprRes = NULL;
-	    }
-	    if (ctxt->value == contextObj) {
-		/*
-		* Don't free the temporary XPath object holding the
-		* context node, in order to avoid massive recreation
-		* inside this loop.
-		*/
-		valuePop(ctxt);
-		xmlXPathNodeSetClear(contextObj->nodesetval, hasNsNodes);
-	    } else {
-		/*
-		* The object was lost in the evaluation machinery.
-		* Can this happen? Maybe in case of internal-errors.
-		*/
-		contextObj = NULL;
-	    }
-	}
-	goto evaluation_exit;
-
-evaluation_error:
-	xmlXPathNodeSetClear(set, hasNsNodes);
-	newContextSize = 0;
-
-evaluation_exit:
-	if (contextObj != NULL) {
-	    if (ctxt->value == contextObj)
-		valuePop(ctxt);
-	    xmlXPathReleaseObject(xpctxt, contextObj);
-	}
-	if (exprRes != NULL)
-	    xmlXPathReleaseObject(ctxt->context, exprRes);
-	/*
-	* Reset/invalidate the context.
-	*/
-	xpctxt->node = oldContextNode;
-	xpctxt->doc = oldContextDoc;
-	xpctxt->contextSize = oldcs;
-	xpctxt->proximityPosition = oldpp;
-	return(newContextSize);
-    }
-    return(contextSize);
+    if (op->ch2 != -1)
+        xmlXPathNodeSetFilter(ctxt, set, op->ch2, minPos, maxPos, hasNsNodes);
 }
 
 static int
@@ -12013,7 +11912,7 @@
     * 1) For predicates (XPATH_OP_PREDICATE):
     *    - an inner predicate operator
     * 2) For filters (XPATH_OP_FILTER):
-    *    - an inner filter operater OR
+    *    - an inner filter operator OR
     *    - an expression selecting the node set.
     *      E.g. "key('a', 'b')" or "(//foo | //bar)".
     */
@@ -12111,7 +12010,7 @@
     /* First predicate operator */
     xmlXPathStepOpPtr predOp;
     int maxPos; /* The requested position() (when a "[n]" predicate) */
-    int hasPredicateRange, hasAxisRange, pos, size, newSize;
+    int hasPredicateRange, hasAxisRange, pos;
     int breakOnFirstHit;
 
     xmlXPathTraversalFunction next = NULL;
@@ -12304,6 +12203,7 @@
 	if (seq == NULL) {
 	    seq = xmlXPathNodeSetCreate(NULL);
 	    if (seq == NULL) {
+                /* TODO: Propagate memory error. */
 		total = 0;
 		goto error;
 	    }
@@ -12315,6 +12215,9 @@
 	cur = NULL;
 	hasNsNodes = 0;
         do {
+            if (OP_LIMIT_EXCEEDED(ctxt, 1))
+                goto error;
+
             cur = next(ctxt, cur);
             if (cur == NULL)
                 break;
@@ -12522,7 +12425,8 @@
 	    outSeq = seq;
 	    seq = NULL;
 	} else
-	    outSeq = mergeAndClear(outSeq, seq, 0);
+            /* TODO: Check memory error. */
+	    outSeq = mergeAndClear(outSeq, seq);
 	/*
 	* Break if only a true/false result was requested.
 	*/
@@ -12539,7 +12443,8 @@
 	    outSeq = seq;
 	    seq = NULL;
 	} else
-	    outSeq = mergeAndClear(outSeq, seq, 0);
+            /* TODO: Check memory error. */
+	    outSeq = mergeAndClear(outSeq, seq);
 	break;
 
 #ifdef DEBUG_STEP
@@ -12583,51 +12488,20 @@
 	    * For the moment, I'll try to solve this with a recursive
 	    * function: xmlXPathCompOpEvalPredicate().
 	    */
-	    size = seq->nodeNr;
 	    if (hasPredicateRange != 0)
-		newSize = xmlXPathCompOpEvalPositionalPredicate(ctxt,
-		    predOp, seq, size, maxPos, maxPos, hasNsNodes);
+		xmlXPathCompOpEvalPredicate(ctxt, predOp, seq, maxPos, maxPos,
+					    hasNsNodes);
 	    else
-		newSize = xmlXPathCompOpEvalPredicate(ctxt,
-		    predOp, seq, size, hasNsNodes);
+		xmlXPathCompOpEvalPredicate(ctxt, predOp, seq, 1, seq->nodeNr,
+					    hasNsNodes);
 
 	    if (ctxt->error != XPATH_EXPRESSION_OK) {
 		total = 0;
 		goto error;
 	    }
-	    /*
-	    * Add the filtered set of nodes to the result node set.
-	    */
-	    if (newSize == 0) {
-		/*
-		* The predicates filtered all nodes out.
-		*/
-		xmlXPathNodeSetClear(seq, hasNsNodes);
-	    } else if (seq->nodeNr > 0) {
-		/*
-		* Add to result set.
-		*/
-		if (outSeq == NULL) {
-		    if (size != newSize) {
-			/*
-			* We need to merge and clear here, since
-			* the sequence will contained NULLed entries.
-			*/
-			outSeq = mergeAndClear(NULL, seq, 1);
-		    } else {
-			outSeq = seq;
-			seq = NULL;
-		    }
-		} else
-		    outSeq = mergeAndClear(outSeq, seq,
-			(size != newSize) ? 1: 0);
-		/*
-		* Break if only a true/false result was requested.
-		*/
-		if (toBool)
-		    break;
-	    }
-        } else if (seq->nodeNr > 0) {
+        }
+
+        if (seq->nodeNr > 0) {
 	    /*
 	    * Add to result set.
 	    */
@@ -12635,8 +12509,12 @@
 		outSeq = seq;
 		seq = NULL;
 	    } else {
-		outSeq = mergeAndClear(outSeq, seq, 0);
+                /* TODO: Check memory error. */
+		outSeq = mergeAndClear(outSeq, seq);
 	    }
+
+            if (toBool)
+                break;
 	}
     }
 
@@ -12655,14 +12533,14 @@
     xmlXPathReleaseObject(xpctxt, obj);
 
     /*
-    * Ensure we return at least an emtpy set.
+    * Ensure we return at least an empty set.
     */
     if (outSeq == NULL) {
 	if ((seq != NULL) && (seq->nodeNr == 0))
 	    outSeq = seq;
 	else
+            /* TODO: Check memory error. */
 	    outSeq = xmlXPathNodeSetCreate(NULL);
-        /* XXX what if xmlXPathNodeSetCreate returned NULL here? */
     }
     if ((seq != NULL) && (seq != outSeq)) {
 	 xmlXPathFreeNodeSet(seq);
@@ -12718,10 +12596,15 @@
     xmlXPathObjectPtr arg1, arg2;
 
     CHECK_ERROR0;
+    if (OP_LIMIT_EXCEEDED(ctxt, 1))
+        return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
-            return (0);
+            break;
         case XPATH_OP_UNION:
             total =
                 xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch1],
@@ -12735,11 +12618,11 @@
                  * limit tree traversing to first node in the result
                  */
 		/*
-		* OPTIMIZE TODO: This implicitely sorts
+		* OPTIMIZE TODO: This implicitly sorts
 		*  the result, even if not needed. E.g. if the argument
 		*  of the count() function, no sorting is needed.
 		* OPTIMIZE TODO: How do we know if the node-list wasn't
-		*  aready sorted?
+		*  already sorted?
 		*/
 		if (ctxt->value->nodesetval->nodeNr > 1)
 		    xmlXPathNodeSetSort(ctxt->value->nodesetval);
@@ -12758,7 +12641,19 @@
 	        xmlXPathReleaseObject(ctxt->context, arg2);
                 XP_ERROR0(XPATH_INVALID_TYPE);
             }
+            if ((ctxt->context->opLimit != 0) &&
+                (((arg1->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg1->nodesetval->nodeNr) < 0)) ||
+                 ((arg2->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg2->nodesetval->nodeNr) < 0)))) {
+	        xmlXPathReleaseObject(ctxt->context, arg1);
+	        xmlXPathReleaseObject(ctxt->context, arg2);
+                break;
+            }
 
+            /* TODO: Check memory error. */
             arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
                                                     arg2->nodesetval);
             valuePush(ctxt, arg1);
@@ -12766,10 +12661,11 @@
             /* optimizer */
 	    if (total > cur)
 		xmlXPathCompSwap(op);
-            return (total + cur);
+            total += cur;
+            break;
         case XPATH_OP_ROOT:
             xmlXPathRoot(ctxt);
-            return (0);
+            break;
         case XPATH_OP_NODE:
             if (op->ch1 != -1)
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
@@ -12779,22 +12675,22 @@
 	    CHECK_ERROR0;
 	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
 		ctxt->context->node));
-            return (total);
+            break;
         case XPATH_OP_COLLECT:{
                 if (op->ch1 == -1)
-                    return (total);
+                    break;
 
                 total = xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 		CHECK_ERROR0;
 
                 total += xmlXPathNodeCollectAndTest(ctxt, op, first, NULL, 0);
-                return (total);
+                break;
             }
         case XPATH_OP_VALUE:
             valuePush(ctxt,
                       xmlXPathCacheObjectCopy(ctxt->context,
 			(xmlXPathObjectPtr) op->value4));
-            return (0);
+            break;
         case XPATH_OP_SORT:
             if (op->ch1 != -1)
                 total +=
@@ -12806,15 +12702,19 @@
                 && (ctxt->value->nodesetval != NULL)
 		&& (ctxt->value->nodesetval->nodeNr > 1))
                 xmlXPathNodeSetSort(ctxt->value->nodesetval);
-            return (total);
+            break;
 #ifdef XP_OPTIMIZED_FILTER_FIRST
 	case XPATH_OP_FILTER:
                 total += xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
-            return (total);
+            break;
 #endif
         default:
-            return (xmlXPathCompOpEval(ctxt, op));
+            total += xmlXPathCompOpEval(ctxt, op);
+            break;
     }
+
+    ctxt->context->depth -= 1;
+    return(total);
 }
 
 /**
@@ -12837,10 +12737,15 @@
     xmlXPathObjectPtr arg1, arg2;
 
     CHECK_ERROR0;
+    if (OP_LIMIT_EXCEEDED(ctxt, 1))
+        return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
-            return (0);
+            break;
         case XPATH_OP_UNION:
             total =
                 xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last);
@@ -12876,7 +12781,19 @@
 	        xmlXPathReleaseObject(ctxt->context, arg2);
                 XP_ERROR0(XPATH_INVALID_TYPE);
             }
+            if ((ctxt->context->opLimit != 0) &&
+                (((arg1->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg1->nodesetval->nodeNr) < 0)) ||
+                 ((arg2->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg2->nodesetval->nodeNr) < 0)))) {
+	        xmlXPathReleaseObject(ctxt->context, arg1);
+	        xmlXPathReleaseObject(ctxt->context, arg2);
+                break;
+            }
 
+            /* TODO: Check memory error. */
             arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
                                                     arg2->nodesetval);
             valuePush(ctxt, arg1);
@@ -12884,10 +12801,11 @@
             /* optimizer */
 	    if (total > cur)
 		xmlXPathCompSwap(op);
-            return (total + cur);
+            total += cur;
+            break;
         case XPATH_OP_ROOT:
             xmlXPathRoot(ctxt);
-            return (0);
+            break;
         case XPATH_OP_NODE:
             if (op->ch1 != -1)
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
@@ -12897,22 +12815,22 @@
 	    CHECK_ERROR0;
 	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
 		ctxt->context->node));
-            return (total);
+            break;
         case XPATH_OP_COLLECT:{
                 if (op->ch1 == -1)
-                    return (0);
+                    break;
 
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 		CHECK_ERROR0;
 
                 total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, last, 0);
-                return (total);
+                break;
             }
         case XPATH_OP_VALUE:
             valuePush(ctxt,
                       xmlXPathCacheObjectCopy(ctxt->context,
 			(xmlXPathObjectPtr) op->value4));
-            return (0);
+            break;
         case XPATH_OP_SORT:
             if (op->ch1 != -1)
                 total +=
@@ -12924,10 +12842,14 @@
                 && (ctxt->value->nodesetval != NULL)
 		&& (ctxt->value->nodesetval->nodeNr > 1))
                 xmlXPathNodeSetSort(ctxt->value->nodesetval);
-            return (total);
+            break;
         default:
-            return (xmlXPathCompOpEval(ctxt, op));
+            total += xmlXPathCompOpEval(ctxt, op);
+            break;
     }
+
+    ctxt->context->depth -= 1;
+    return (total);
 }
 
 #ifdef XP_OPTIMIZED_FILTER_FIRST
@@ -12937,13 +12859,7 @@
 {
     int total = 0;
     xmlXPathCompExprPtr comp;
-    xmlXPathObjectPtr res;
-    xmlXPathObjectPtr obj;
-    xmlNodeSetPtr oldset;
-    xmlNodePtr oldnode;
-    xmlDocPtr oldDoc;
-    int oldcs, oldpp;
-    int i;
+    xmlNodeSetPtr set;
 
     CHECK_ERROR0;
     comp = ctxt->comp;
@@ -12998,205 +12914,27 @@
     * Hum are we filtering the result of an XPointer expression
     */
     if (ctxt->value->type == XPATH_LOCATIONSET) {
-	xmlXPathObjectPtr tmp = NULL;
-	xmlLocationSetPtr newlocset = NULL;
-	xmlLocationSetPtr oldlocset;
+        xmlLocationSetPtr locset = ctxt->value->user;
 
-	/*
-	* Extract the old locset, and then evaluate the result of the
-	* expression for all the element in the locset. use it to grow
-	* up a new locset.
-	*/
-	CHECK_TYPE0(XPATH_LOCATIONSET);
+        if (locset != NULL) {
+            xmlXPathLocationSetFilter(ctxt, locset, op->ch2, 1, 1);
+            if (locset->locNr > 0)
+                *first = (xmlNodePtr) locset->locTab[0]->user;
+        }
 
-	if ((ctxt->value->user == NULL) ||
-            (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
-	    return (total);
-
-	obj = valuePop(ctxt);
-	oldlocset = obj->user;
-        oldnode = ctxt->context->node;
-        oldcs = ctxt->context->contextSize;
-        oldpp = ctxt->context->proximityPosition;
-
-	newlocset = xmlXPtrLocationSetCreate(NULL);
-
-	for (i = 0; i < oldlocset->locNr; i++) {
-	    /*
-	    * Run the evaluation with a node list made of a
-	    * single item in the nodelocset.
-	    */
-	    ctxt->context->node = oldlocset->locTab[i]->user;
-	    ctxt->context->contextSize = oldlocset->locNr;
-	    ctxt->context->proximityPosition = i + 1;
-	    if (tmp == NULL) {
-		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
-		    ctxt->context->node);
-	    } else {
-		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
-		                             ctxt->context->node) < 0) {
-		    ctxt->error = XPATH_MEMORY_ERROR;
-		}
-	    }
-	    valuePush(ctxt, tmp);
-	    if (op->ch2 != -1)
-		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
-	    if (ctxt->error != XPATH_EXPRESSION_OK) {
-                xmlXPtrFreeLocationSet(newlocset);
-                goto xptr_error;
-	    }
-	    /*
-	    * The result of the evaluation need to be tested to
-	    * decided whether the filter succeeded or not
-	    */
-	    res = valuePop(ctxt);
-	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-		xmlXPtrLocationSetAdd(newlocset,
-		    xmlXPathCacheObjectCopy(ctxt->context,
-			oldlocset->locTab[i]));
-	    }
-	    /*
-	    * Cleanup
-	    */
-	    if (res != NULL) {
-		xmlXPathReleaseObject(ctxt->context, res);
-	    }
-	    if (ctxt->value == tmp) {
-		valuePop(ctxt);
-		xmlXPathNodeSetClear(tmp->nodesetval, 1);
-		/*
-		* REVISIT TODO: Don't create a temporary nodeset
-		* for everly iteration.
-		*/
-		/* OLD: xmlXPathFreeObject(res); */
-	    } else
-		tmp = NULL;
-	    /*
-	    * Only put the first node in the result, then leave.
-	    */
-	    if (newlocset->locNr > 0) {
-		*first = (xmlNodePtr) oldlocset->locTab[i]->user;
-		break;
-	    }
-	}
-	if (tmp != NULL) {
-	    xmlXPathReleaseObject(ctxt->context, tmp);
-	}
-	/*
-	* The result is used as the new evaluation locset.
-	*/
-	valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
-xptr_error:
-	xmlXPathReleaseObject(ctxt->context, obj);
-	ctxt->context->node = oldnode;
-	ctxt->context->contextSize = oldcs;
-	ctxt->context->proximityPosition = oldpp;
 	return (total);
     }
 #endif /* LIBXML_XPTR_ENABLED */
 
-    /*
-    * Extract the old set, and then evaluate the result of the
-    * expression for all the element in the set. use it to grow
-    * up a new set.
-    */
     CHECK_TYPE0(XPATH_NODESET);
-
-    if ((ctxt->value->nodesetval != NULL) &&
-        (ctxt->value->nodesetval->nodeNr != 0)) {
-	xmlNodeSetPtr newset;
-	xmlXPathObjectPtr tmp = NULL;
-
-        obj = valuePop(ctxt);
-        oldset = obj->nodesetval;
-        oldnode = ctxt->context->node;
-        oldDoc = ctxt->context->doc;
-        oldcs = ctxt->context->contextSize;
-        oldpp = ctxt->context->proximityPosition;
-
-	/*
-	* Initialize the new set.
-	* Also set the xpath document in case things like
-	* key() evaluation are attempted on the predicate
-	*/
-	newset = xmlXPathNodeSetCreate(NULL);
-        /* XXX what if xmlXPathNodeSetCreate returned NULL? */
-
-	for (i = 0; i < oldset->nodeNr; i++) {
-	    /*
-	    * Run the evaluation with a node list made of
-	    * a single item in the nodeset.
-	    */
-	    ctxt->context->node = oldset->nodeTab[i];
-	    if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
-		(oldset->nodeTab[i]->doc != NULL))
-		ctxt->context->doc = oldset->nodeTab[i]->doc;
-	    if (tmp == NULL) {
-		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
-		    ctxt->context->node);
-	    } else {
-		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
-		                             ctxt->context->node) < 0) {
-		    ctxt->error = XPATH_MEMORY_ERROR;
-		}
-	    }
-	    valuePush(ctxt, tmp);
-	    ctxt->context->contextSize = oldset->nodeNr;
-	    ctxt->context->proximityPosition = i + 1;
-	    if (op->ch2 != -1)
-		total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
-	    if (ctxt->error != XPATH_EXPRESSION_OK) {
-		xmlXPathFreeNodeSet(newset);
-                goto error;
-	    }
-	    /*
-	    * The result of the evaluation needs to be tested to
-	    * decide whether the filter succeeded or not
-	    */
-	    res = valuePop(ctxt);
-	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-		if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0)
-		    ctxt->error = XPATH_MEMORY_ERROR;
-	    }
-	    /*
-	    * Cleanup
-	    */
-	    if (res != NULL) {
-		xmlXPathReleaseObject(ctxt->context, res);
-	    }
-	    if (ctxt->value == tmp) {
-		valuePop(ctxt);
-		/*
-		* Don't free the temporary nodeset
-		* in order to avoid massive recreation inside this
-		* loop.
-		*/
-		xmlXPathNodeSetClear(tmp->nodesetval, 1);
-	    } else
-		tmp = NULL;
-	    /*
-	    * Only put the first node in the result, then leave.
-	    */
-	    if (newset->nodeNr > 0) {
-		*first = *(newset->nodeTab);
-		break;
-	    }
-	}
-	if (tmp != NULL) {
-	    xmlXPathReleaseObject(ctxt->context, tmp);
-	}
-	/*
-	* The result is used as the new evaluation set.
-	*/
-	valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset));
-error:
-	xmlXPathReleaseObject(ctxt->context, obj);
-	ctxt->context->node = oldnode;
-	ctxt->context->doc = oldDoc;
-	ctxt->context->contextSize = oldcs;
-	ctxt->context->proximityPosition = oldpp;
+    set = ctxt->value->nodesetval;
+    if (set != NULL) {
+        xmlXPathNodeSetFilter(ctxt, set, op->ch2, 1, 1, 1);
+        if (set->nodeNr > 0)
+            *first = set->nodeTab[0];
     }
-    return(total);
+
+    return (total);
 }
 #endif /* XP_OPTIMIZED_FILTER_FIRST */
 
@@ -13217,44 +12955,49 @@
     xmlXPathObjectPtr arg1, arg2;
 
     CHECK_ERROR0;
+    if (OP_LIMIT_EXCEEDED(ctxt, 1))
+        return(0);
+    if (ctxt->context->depth >= ctxt->context->maxDepth)
+        XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED);
+    ctxt->context->depth += 1;
     comp = ctxt->comp;
     switch (op->op) {
         case XPATH_OP_END:
-            return (0);
+            break;
         case XPATH_OP_AND:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
             xmlXPathBooleanFunction(ctxt, 1);
             if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
-                return (total);
+                break;
             arg2 = valuePop(ctxt);
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
 	    if (ctxt->error) {
 		xmlXPathFreeObject(arg2);
-		return(0);
+		break;
 	    }
             xmlXPathBooleanFunction(ctxt, 1);
             if (ctxt->value != NULL)
                 ctxt->value->boolval &= arg2->boolval;
 	    xmlXPathReleaseObject(ctxt->context, arg2);
-            return (total);
+            break;
         case XPATH_OP_OR:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
             xmlXPathBooleanFunction(ctxt, 1);
             if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
-                return (total);
+                break;
             arg2 = valuePop(ctxt);
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
 	    if (ctxt->error) {
 		xmlXPathFreeObject(arg2);
-		return(0);
+		break;
 	    }
             xmlXPathBooleanFunction(ctxt, 1);
             if (ctxt->value != NULL)
                 ctxt->value->boolval |= arg2->boolval;
 	    xmlXPathReleaseObject(ctxt->context, arg2);
-            return (total);
+            break;
         case XPATH_OP_EQUAL:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
@@ -13265,7 +13008,7 @@
 	    else
 		equal = xmlXPathNotEqualValues(ctxt);
 	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal));
-            return (total);
+            break;
         case XPATH_OP_CMP:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
@@ -13273,7 +13016,7 @@
 	    CHECK_ERROR0;
             ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
 	    valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret));
-            return (total);
+            break;
         case XPATH_OP_PLUS:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
@@ -13291,7 +13034,7 @@
                 CAST_TO_NUMBER;
                 CHECK_TYPE0(XPATH_NUMBER);
             }
-            return (total);
+            break;
         case XPATH_OP_MULT:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
@@ -13303,7 +13046,7 @@
                 xmlXPathDivValues(ctxt);
             else if (op->value == 2)
                 xmlXPathModValues(ctxt);
-            return (total);
+            break;
         case XPATH_OP_UNION:
             total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 	    CHECK_ERROR0;
@@ -13318,21 +13061,33 @@
 	        xmlXPathReleaseObject(ctxt->context, arg2);
                 XP_ERROR0(XPATH_INVALID_TYPE);
             }
+            if ((ctxt->context->opLimit != 0) &&
+                (((arg1->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg1->nodesetval->nodeNr) < 0)) ||
+                 ((arg2->nodesetval != NULL) &&
+                  (xmlXPathCheckOpLimit(ctxt,
+                                        arg2->nodesetval->nodeNr) < 0)))) {
+	        xmlXPathReleaseObject(ctxt->context, arg1);
+	        xmlXPathReleaseObject(ctxt->context, arg2);
+                break;
+            }
 
 	    if ((arg1->nodesetval == NULL) ||
 		((arg2->nodesetval != NULL) &&
 		 (arg2->nodesetval->nodeNr != 0)))
 	    {
+                /* TODO: Check memory error. */
 		arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
 							arg2->nodesetval);
 	    }
 
             valuePush(ctxt, arg1);
 	    xmlXPathReleaseObject(ctxt->context, arg2);
-            return (total);
+            break;
         case XPATH_OP_ROOT:
             xmlXPathRoot(ctxt);
-            return (total);
+            break;
         case XPATH_OP_NODE:
             if (op->ch1 != -1)
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
@@ -13342,22 +13097,22 @@
 	    CHECK_ERROR0;
 	    valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context,
 		ctxt->context->node));
-            return (total);
+            break;
         case XPATH_OP_COLLECT:{
                 if (op->ch1 == -1)
-                    return (total);
+                    break;
 
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 		CHECK_ERROR0;
 
                 total += xmlXPathNodeCollectAndTest(ctxt, op, NULL, NULL, 0);
-                return (total);
+                break;
             }
         case XPATH_OP_VALUE:
             valuePush(ctxt,
                       xmlXPathCacheObjectCopy(ctxt->context,
 			(xmlXPathObjectPtr) op->value4));
-            return (total);
+            break;
         case XPATH_OP_VARIABLE:{
 		xmlXPathObjectPtr val;
 
@@ -13378,7 +13133,7 @@
             "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
                                     (char *) op->value4, (char *)op->value5);
                         ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
-                        return (total);
+                        break;
                     }
 		    val = xmlXPathVariableLookupNS(ctxt->context,
                                                        op->value4, URI);
@@ -13386,7 +13141,7 @@
 			XP_ERROR0(XPATH_UNDEF_VARIABLE_ERROR);
                     valuePush(ctxt, val);
                 }
-                return (total);
+                break;
             }
         case XPATH_OP_FUNCTION:{
                 xmlXPathFunction func;
@@ -13400,7 +13155,7 @@
                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
                     if (ctxt->error != XPATH_EXPRESSION_OK) {
                         xmlXPathPopFrame(ctxt, frame);
-                        return (total);
+                        break;
                     }
                 }
 		if (ctxt->valueNr < ctxt->valueFrame + op->value) {
@@ -13408,7 +13163,7 @@
 			    "xmlXPathCompOpEval: parameter error\n");
 		    ctxt->error = XPATH_INVALID_OPERAND;
                     xmlXPathPopFrame(ctxt, frame);
-		    return (total);
+		    break;
 		}
 		for (i = 0; i < op->value; i++) {
 		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
@@ -13416,7 +13171,7 @@
 				"xmlXPathCompOpEval: parameter error\n");
 			ctxt->error = XPATH_INVALID_OPERAND;
                         xmlXPathPopFrame(ctxt, frame);
-			return (total);
+			break;
 		    }
                 }
                 if (op->cache != NULL)
@@ -13436,7 +13191,7 @@
                                     (char *)op->value4, (char *)op->value5);
                             xmlXPathPopFrame(ctxt, frame);
                             ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
-                            return (total);
+                            break;
                         }
                         func = xmlXPathFunctionLookupNS(ctxt->context,
                                                         op->value4, URI);
@@ -13457,8 +13212,11 @@
                 func(ctxt, op->value);
                 ctxt->context->function = oldFunc;
                 ctxt->context->functionURI = oldFuncURI;
+                if ((ctxt->error == XPATH_EXPRESSION_OK) &&
+                    (ctxt->valueNr != ctxt->valueFrame + 1))
+                    XP_ERROR0(XPATH_STACK_ERROR);
                 xmlXPathPopFrame(ctxt, frame);
-                return (total);
+                break;
             }
         case XPATH_OP_ARG:
             if (op->ch1 != -1) {
@@ -13469,17 +13227,10 @@
                 total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
 	        CHECK_ERROR0;
 	    }
-            return (total);
+            break;
         case XPATH_OP_PREDICATE:
         case XPATH_OP_FILTER:{
-                xmlXPathObjectPtr res;
-                xmlXPathObjectPtr obj, tmp;
-                xmlNodeSetPtr newset = NULL;
-                xmlNodeSetPtr oldset;
-                xmlNodePtr oldnode;
-		xmlDocPtr oldDoc;
-                int oldcs, oldpp;
-                int i;
+                xmlNodeSetPtr set;
 
                 /*
                  * Optimization for ()[1] selection i.e. the first elem
@@ -13491,7 +13242,7 @@
 		    *  will result in an ordered list if we have an
 		    *  XPATH_OP_FILTER?
 		    *  What about an additional field or flag on
-		    *  xmlXPathObject like @sorted ? This way we wouln'd need
+		    *  xmlXPathObject like @sorted ? This way we wouldn't need
 		    *  to assume anything, so it would be more robust and
 		    *  easier to optimize.
 		    */
@@ -13523,7 +13274,7 @@
                             (ctxt->value->nodesetval->nodeNr > 1))
                             xmlXPathNodeSetClearFromPos(ctxt->value->nodesetval,
                                                         1, 1);
-                        return (total);
+                        break;
                     }
                 }
                 /*
@@ -13558,7 +13309,7 @@
                             (ctxt->value->nodesetval->nodeTab != NULL) &&
                             (ctxt->value->nodesetval->nodeNr > 1))
                             xmlXPathNodeSetKeepLast(ctxt->value->nodesetval);
-                        return (total);
+                        break;
                     }
                 }
 		/*
@@ -13577,224 +13328,28 @@
                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
 		CHECK_ERROR0;
                 if (op->ch2 == -1)
-                    return (total);
+                    break;
                 if (ctxt->value == NULL)
-                    return (total);
+                    break;
 
 #ifdef LIBXML_XPTR_ENABLED
                 /*
                  * Hum are we filtering the result of an XPointer expression
                  */
                 if (ctxt->value->type == XPATH_LOCATIONSET) {
-                    xmlLocationSetPtr newlocset = NULL;
-                    xmlLocationSetPtr oldlocset;
-
-                    /*
-                     * Extract the old locset, and then evaluate the result of the
-                     * expression for all the element in the locset. use it to grow
-                     * up a new locset.
-                     */
-                    CHECK_TYPE0(XPATH_LOCATIONSET);
-
-                    if ((ctxt->value->user == NULL) ||
-                        (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
-                        return (total);
-
-                    obj = valuePop(ctxt);
-                    oldlocset = obj->user;
-                    oldnode = ctxt->context->node;
-                    oldcs = ctxt->context->contextSize;
-                    oldpp = ctxt->context->proximityPosition;
-
-                    newlocset = xmlXPtrLocationSetCreate(NULL);
-
-                    for (i = 0; i < oldlocset->locNr; i++) {
-                        /*
-                         * Run the evaluation with a node list made of a
-                         * single item in the nodelocset.
-                         */
-                        ctxt->context->node = oldlocset->locTab[i]->user;
-                        ctxt->context->contextSize = oldlocset->locNr;
-                        ctxt->context->proximityPosition = i + 1;
-			tmp = xmlXPathCacheNewNodeSet(ctxt->context,
-			    ctxt->context->node);
-                        valuePush(ctxt, tmp);
-
-                        if (op->ch2 != -1)
-                            total +=
-                                xmlXPathCompOpEval(ctxt,
-                                                   &comp->steps[op->ch2]);
-			if (ctxt->error != XPATH_EXPRESSION_OK) {
-                            xmlXPtrFreeLocationSet(newlocset);
-                            goto filter_xptr_error;
-			}
-
-                        /*
-                         * The result of the evaluation need to be tested to
-                         * decided whether the filter succeeded or not
-                         */
-                        res = valuePop(ctxt);
-                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-                            xmlXPtrLocationSetAdd(newlocset,
-                                                  xmlXPathObjectCopy
-                                                  (oldlocset->locTab[i]));
-                        }
-
-                        /*
-                         * Cleanup
-                         */
-                        if (res != NULL) {
-			    xmlXPathReleaseObject(ctxt->context, res);
-			}
-                        if (ctxt->value == tmp) {
-                            res = valuePop(ctxt);
-			    xmlXPathReleaseObject(ctxt->context, res);
-                        }
-                    }
-
-                    /*
-                     * The result is used as the new evaluation locset.
-                     */
-                    valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
-filter_xptr_error:
-		    xmlXPathReleaseObject(ctxt->context, obj);
-                    ctxt->context->node = oldnode;
-                    ctxt->context->contextSize = oldcs;
-                    ctxt->context->proximityPosition = oldpp;
-                    return (total);
+                    xmlLocationSetPtr locset = ctxt->value->user;
+                    xmlXPathLocationSetFilter(ctxt, locset, op->ch2,
+                                              1, locset->locNr);
+                    break;
                 }
 #endif /* LIBXML_XPTR_ENABLED */
 
-                /*
-                 * Extract the old set, and then evaluate the result of the
-                 * expression for all the element in the set. use it to grow
-                 * up a new set.
-                 */
                 CHECK_TYPE0(XPATH_NODESET);
-
-                if ((ctxt->value->nodesetval != NULL) &&
-                    (ctxt->value->nodesetval->nodeNr != 0)) {
-                    obj = valuePop(ctxt);
-                    oldset = obj->nodesetval;
-                    oldnode = ctxt->context->node;
-                    oldDoc = ctxt->context->doc;
-                    oldcs = ctxt->context->contextSize;
-                    oldpp = ctxt->context->proximityPosition;
-		    tmp = NULL;
-                    /*
-                     * Initialize the new set.
-		     * Also set the xpath document in case things like
-		     * key() evaluation are attempted on the predicate
-                     */
-                    newset = xmlXPathNodeSetCreate(NULL);
-		    /*
-		    * SPEC XPath 1.0:
-		    *  "For each node in the node-set to be filtered, the
-		    *  PredicateExpr is evaluated with that node as the
-		    *  context node, with the number of nodes in the
-		    *  node-set as the context size, and with the proximity
-		    *  position of the node in the node-set with respect to
-		    *  the axis as the context position;"
-		    * @oldset is the node-set" to be filtered.
-		    *
-		    * SPEC XPath 1.0:
-		    *  "only predicates change the context position and
-		    *  context size (see [2.4 Predicates])."
-		    * Example:
-		    *   node-set  context pos
-		    *    nA         1
-		    *    nB         2
-		    *    nC         3
-		    *   After applying predicate [position() > 1] :
-		    *   node-set  context pos
-		    *    nB         1
-		    *    nC         2
-		    *
-		    * removed the first node in the node-set, then
-		    * the context position of the
-		    */
-                    for (i = 0; i < oldset->nodeNr; i++) {
-                        /*
-                         * Run the evaluation with a node list made of
-                         * a single item in the nodeset.
-                         */
-                        ctxt->context->node = oldset->nodeTab[i];
-			if ((oldset->nodeTab[i]->type != XML_NAMESPACE_DECL) &&
-			    (oldset->nodeTab[i]->doc != NULL))
-		            ctxt->context->doc = oldset->nodeTab[i]->doc;
-			if (tmp == NULL) {
-			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
-				ctxt->context->node);
-			} else {
-			    if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
-				               ctxt->context->node) < 0) {
-				ctxt->error = XPATH_MEMORY_ERROR;
-			    }
-			}
-                        valuePush(ctxt, tmp);
-                        ctxt->context->contextSize = oldset->nodeNr;
-                        ctxt->context->proximityPosition = i + 1;
-			/*
-			* Evaluate the predicate against the context node.
-			* Can/should we optimize position() predicates
-			* here (e.g. "[1]")?
-			*/
-                        if (op->ch2 != -1)
-                            total +=
-                                xmlXPathCompOpEval(ctxt,
-                                                   &comp->steps[op->ch2]);
-			if (ctxt->error != XPATH_EXPRESSION_OK) {
-			    xmlXPathFreeNodeSet(newset);
-                            goto filter_error;
-			}
-
-                        /*
-                         * The result of the evaluation needs to be tested to
-                         * decide whether the filter succeeded or not
-                         */
-			/*
-			* OPTIMIZE TODO: Can we use
-			* xmlXPathNodeSetAdd*Unique()* instead?
-			*/
-                        res = valuePop(ctxt);
-                        if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
-                            if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i])
-			        < 0)
-				ctxt->error = XPATH_MEMORY_ERROR;
-                        }
-
-                        /*
-                         * Cleanup
-                         */
-                        if (res != NULL) {
-			    xmlXPathReleaseObject(ctxt->context, res);
-			}
-                        if (ctxt->value == tmp) {
-                            valuePop(ctxt);
-			    xmlXPathNodeSetClear(tmp->nodesetval, 1);
-			    /*
-			    * Don't free the temporary nodeset
-			    * in order to avoid massive recreation inside this
-			    * loop.
-			    */
-                        } else
-			    tmp = NULL;
-                    }
-		    if (tmp != NULL)
-			xmlXPathReleaseObject(ctxt->context, tmp);
-                    /*
-                     * The result is used as the new evaluation set.
-                     */
-		    valuePush(ctxt,
-			xmlXPathCacheWrapNodeSet(ctxt->context, newset));
-filter_error:
-		    xmlXPathReleaseObject(ctxt->context, obj);
-		    ctxt->context->node = oldnode;
-		    ctxt->context->doc = oldDoc;
-                    ctxt->context->contextSize = oldcs;
-                    ctxt->context->proximityPosition = oldpp;
-                }
-                return (total);
+                set = ctxt->value->nodesetval;
+                if (set != NULL)
+                    xmlXPathNodeSetFilter(ctxt, set, op->ch2,
+                                          1, set->nodeNr, 1);
+                break;
             }
         case XPATH_OP_SORT:
             if (op->ch1 != -1)
@@ -13807,7 +13362,7 @@
 	    {
                 xmlXPathNodeSetSort(ctxt->value->nodesetval);
 	    }
-            return (total);
+            break;
 #ifdef LIBXML_XPTR_ENABLED
         case XPATH_OP_RANGETO:{
                 xmlXPathObjectPtr range;
@@ -13830,7 +13385,7 @@
                     XP_ERROR0(XPATH_INVALID_OPERAND);
                 }
                 if (op->ch2 == -1)
-                    return (total);
+                    break;
 
                 if (ctxt->value->type == XPATH_LOCATIONSET) {
                     /*
@@ -13842,7 +13397,7 @@
 
                     if ((ctxt->value->user == NULL) ||
                         (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0))
-                        return (total);
+                        break;
 
                     obj = valuePop(ctxt);
                     oldlocset = obj->user;
@@ -13964,13 +13519,17 @@
                 ctxt->context->node = oldnode;
                 ctxt->context->contextSize = oldcs;
                 ctxt->context->proximityPosition = oldpp;
-                return (total);
+                break;
             }
 #endif /* LIBXML_XPTR_ENABLED */
+        default:
+            xmlGenericError(xmlGenericErrorContext,
+                            "XPath: unknown precompiled operation %d\n", op->op);
+            ctxt->error = XPATH_INVALID_OPERAND;
+            break;
     }
-    xmlGenericError(xmlGenericErrorContext,
-                    "XPath: unknown precompiled operation %d\n", op->op);
-    ctxt->error = XPATH_INVALID_OPERAND;
+
+    ctxt->context->depth -= 1;
     return (total);
 }
 
@@ -13990,6 +13549,8 @@
     xmlXPathObjectPtr resObj = NULL;
 
 start:
+    if (OP_LIMIT_EXCEEDED(ctxt, 1))
+        return(0);
     /* comp = ctxt->comp; */
     switch (op->op) {
         case XPATH_OP_END:
@@ -14116,12 +13677,14 @@
 	    /* Select "/" */
 	    if (toBool)
 		return(1);
+            /* TODO: Check memory error. */
 	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
 		                     (xmlNodePtr) ctxt->doc);
 	} else {
 	    /* Select "self::node()" */
 	    if (toBool)
 		return(1);
+            /* TODO: Check memory error. */
 	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, ctxt->node);
 	}
     }
@@ -14182,6 +13745,7 @@
 	} else if (ret == 1) {
 	    if (toBool)
 		goto return_1;
+            /* TODO: Check memory error. */
 	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
 	}
     }
@@ -14189,6 +13753,16 @@
     goto scan_children;
 next_node:
     do {
+        if (ctxt->opLimit != 0) {
+            if (ctxt->opCount >= ctxt->opLimit) {
+                xmlGenericError(xmlGenericErrorContext,
+                        "XPath operation limit exceeded\n");
+                xmlFreeStreamCtxt(patstream);
+                return(-1);
+            }
+            ctxt->opCount++;
+        }
+
         nb_nodes++;
 
 	switch (cur->type) {
@@ -14312,6 +13886,8 @@
     if ((ctxt == NULL) || (ctxt->comp == NULL))
 	return(-1);
 
+    ctxt->context->depth = 0;
+
     if (ctxt->valueTab == NULL) {
 	/* Allocate the value stack */
 	ctxt->valueTab = (xmlXPathObjectPtr *)
@@ -14498,7 +14074,7 @@
 
 	/*
 	 * We don't try to handle expressions using the verbose axis
-	 * specifiers ("::"), just the simplied form at this point.
+	 * specifiers ("::"), just the simplified form at this point.
 	 * Additionally, if there is no list of namespaces available and
 	 *  there's a ":" in the expression, indicating a prefixed QName,
 	 *  then we won't try to compile either. xmlPatterncompile() needs
@@ -14552,8 +14128,12 @@
 #endif /* XPATH_STREAMING */
 
 static void
-xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
+xmlXPathOptimizeExpression(xmlXPathParserContextPtr pctxt,
+                           xmlXPathStepOpPtr op)
 {
+    xmlXPathCompExprPtr comp = pctxt->comp;
+    xmlXPathContextPtr ctxt;
+
     /*
     * Try to rewrite "descendant-or-self::node()/foo" to an optimized
     * internal representation.
@@ -14609,10 +14189,18 @@
         return;
 
     /* Recurse */
+    ctxt = pctxt->context;
+    if (ctxt != NULL) {
+        if (ctxt->depth >= ctxt->maxDepth)
+            return;
+        ctxt->depth += 1;
+    }
     if (op->ch1 != -1)
-        xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
+        xmlXPathOptimizeExpression(pctxt, &comp->steps[op->ch1]);
     if (op->ch2 != -1)
-	xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
+	xmlXPathOptimizeExpression(pctxt, &comp->steps[op->ch2]);
+    if (ctxt != NULL)
+        ctxt->depth -= 1;
 }
 
 /**
@@ -14641,6 +14229,8 @@
     pctxt = xmlXPathNewParserContext(str, ctxt);
     if (pctxt == NULL)
         return NULL;
+    if (ctxt != NULL)
+        ctxt->depth = 0;
     xmlXPathCompileExpr(pctxt, 1);
 
     if( pctxt->error != XPATH_EXPRESSION_OK )
@@ -14660,6 +14250,11 @@
 	comp = NULL;
     } else {
 	comp = pctxt->comp;
+	if ((comp->nbStep > 1) && (comp->last >= 0)) {
+            if (ctxt != NULL)
+                ctxt->depth = 0;
+	    xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]);
+	}
 	pctxt->comp = NULL;
     }
     xmlXPathFreeParserContext(pctxt);
@@ -14670,9 +14265,6 @@
 	comp->string = xmlStrdup(str);
 	comp->nb = 0;
 #endif
-	if ((comp->nbStep > 1) && (comp->last >= 0)) {
-	    xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
-	}
     }
     return(comp);
 }
@@ -14829,6 +14421,8 @@
     } else
 #endif
     {
+        if (ctxt->context != NULL)
+            ctxt->context->depth = 0;
 	xmlXPathCompileExpr(ctxt, 1);
         CHECK_ERROR;
 
@@ -14836,9 +14430,12 @@
         if (*ctxt->cur != 0)
             XP_ERROR(XPATH_EXPR_ERROR);
 
-	if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0))
-	    xmlXPathOptimizeExpression(ctxt->comp,
+	if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) {
+            if (ctxt->context != NULL)
+                ctxt->context->depth = 0;
+	    xmlXPathOptimizeExpression(ctxt,
 		&ctxt->comp->steps[ctxt->comp->last]);
+        }
     }
 
     xmlXPathRunEval(ctxt, 0);
diff --git a/src/xzlib.h b/src/xzlib.h
index 29ba55e..7b1df15 100644
--- a/src/xzlib.h
+++ b/src/xzlib.h
@@ -1,5 +1,5 @@
 /**
- * xzlib.h: header for the front end for the transparent suport of lzma
+ * xzlib.h: header for the front end for the transparent support of lzma
  *          compression at the I/O layer
  *
  * See Copyright for the status of this software.
diff --git a/win32/config.h b/win32/config.h
index c1e16f1..324b74f 100644
--- a/win32/config.h
+++ b/win32/config.h
@@ -37,7 +37,7 @@
 #if defined(_MSC_VER) || defined(__BORLANDC__)
 /* MS C-runtime has functions which can be used in order to determine if
    a given floating-point variable contains NaN, (+-)INF. These are 
-   preferred, because floating-point technology is considered propriatary
+   preferred, because floating-point technology is considered proprietary
    by MS and we can assume that their functions know more about their 
    oddities than we do. */
 #include <float.h>
diff --git a/win32/include/libxml/xmlversion.h b/win32/include/libxml/xmlversion.h
index 23989a5..28ecf08 100644
--- a/win32/include/libxml/xmlversion.h
+++ b/win32/include/libxml/xmlversion.h
@@ -1,6 +1,6 @@
 /*
- * Summary: compile-time version informations
- * Description: compile-time version informations for the XML library
+ * Summary: compile-time version information
+ * Description: compile-time version information for the XML library
  *
  * Copy: See Copyright for the status of this software.
  *
@@ -29,21 +29,21 @@
  *
  * the version string like "1.2.3"
  */
-#define LIBXML_DOTTED_VERSION "2.9.9"
+#define LIBXML_DOTTED_VERSION "2.9.10"
 
 /**
  * LIBXML_VERSION:
  *
  * the version number: 1.2.3 value is 10203
  */
-#define LIBXML_VERSION 20909
+#define LIBXML_VERSION 20910
 
 /**
  * LIBXML_VERSION_STRING:
  *
  * the version number string, 1.2.3 value is "10203"
  */
-#define LIBXML_VERSION_STRING "20909"
+#define LIBXML_VERSION_STRING "20910"
 
 /**
  * LIBXML_VERSION_EXTRA:
@@ -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(20909);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20910);
 
 #ifndef VMS
 #if 0
@@ -91,11 +91,8 @@
  * Whether the thread support is configured in
  */
 #if 0
-#if defined(_REENTRANT) || defined(__MT__) || \
-    (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE - 0 >= 199506L))
 #define LIBXML_THREAD_ENABLED
 #endif
-#endif
 
 /**
  * LIBXML_THREAD_ALLOC_ENABLED:
@@ -353,6 +350,8 @@
  * LIBXML_EXPR_ENABLED:
  *
  * Whether the formal expressions interfaces are compiled in
+ *
+ * This code is unused and disabled unconditionally for now.
  */
 #if 0
 #define LIBXML_EXPR_ENABLED