[libxml2/f17] Accumulated fixes for various security errata + a few bug fixes

Daniel Veillard veillard at fedoraproject.org
Mon Sep 10 05:41:51 UTC 2012


commit 4e98652b8701a7f6ccb59484210930abf5ab9544
Author: Daniel Veillard <veillard at redhat.com>
Date:   Mon Sep 10 13:40:16 2012 +0800

    Accumulated fixes for various security errata + a few bug fixes
    
    - Fixes for CVE-2011-3919 CVE-2011-3905 CVE-2011-2834 (rhbz#772122)
    - Fixes for CVE-2012-2807 (843743)
    - Fixes for CVE-2012-0841 (795698)
    - Fix for CVE-2011-1944 (709750)
    - Fix for CVE-2011-0216 (755813)
    - Fix for CVE-2011-2821 (735715)
    - Fix for CVE-2011-3102 (822171)
    Daniel

 libxml2-2.7.7-xpath-double-free.patch              |   22 -
 libxml2-2.7.8-reactivate-versionning-script.patch  |   58 ---
 ...randomization-to-hash-and-dict-structures.patch |  300 +++++++++++
 ...atic-behaviour-in-some-push-parsing-cases.patch |  247 ++++++++++
 ...XPath-code-to-percolate-allocation-errors.patch |  484 ++++++++++++++++++
 ...anups-and-new-limit-APIs-for-dictionaries.patch |  519 ++++++++++++++++++++
 ...ml2-Do-not-fetch-external-parsed-entities.patch |   71 +++
 ...SER_EOF-state-handling-through-the-parser.patch |  481 ++++++++++++++++++
 ...lure-to-report-xmlreader-parsing-failures.patch |   37 ++
 ...l2-Fix-a-potential-freeing-error-in-XPath.patch |   38 ++
 ...gfault-on-XSD-validation-on-pattern-error.patch |   56 +++
 ...an-allocation-error-when-copying-entities.patch |   27 +
 libxml2-Fix-an-error-in-previous-commit.patch      |   27 +
 libxml2-Fix-an-off-by-one-error-in-encoding.patch  |   39 ++
 libxml2-Fix-an-off-by-one-pointer-access.patch     |   46 ++
 ...nimplemented-part-in-RNG-value-validation.patch |   67 +++
 ...-Fix-entities-local-buffers-size-problems.patch |  103 ++++
 ...-missing-error-status-in-XPath-evaluation.patch |   69 +++
 ...l2-Fix-parser-local-buffers-size-problems.patch |  269 ++++++++++
 ...tential-problems-on-reallocation-failures.patch |  108 ++++
 libxml2-Fixup-limits-parser.patch                  |   26 +
 libxml2-Hardening-of-XPath-evaluation.patch        |  233 +++++++++
 ...t-some-default-limits-in-the-XPath-module.patch |  328 ++++++++++++
 libxml2-Impose-a-reasonable-limit-on-PI-size.patch |   82 +++
 ...pose-a-reasonable-limit-on-attribute-size.patch |  110 ++++
 ...Impose-a-reasonable-limit-on-comment-size.patch |   97 ++++
 libxml2-Introduce-some-default-parser-limits.patch |  310 ++++++++++++
 ...-parser-returns-when-getting-a-Stop-order.patch |   69 +++
 libxml2-More-avoid-quadratic-behaviour.patch       |  102 ++++
 ...-More-fixups-on-the-push-parser-behaviour.patch |   62 +++
 libxml2-Multilib-fix.patch                         |   34 ++
 ...ate-the-shared-library-versionning-script.patch |   27 +
 libxml2-Small-fix-for-previous-commit.patch        |   34 ++
 ...the-push-parser-in-problematic-situations.patch |   71 +++
 libxml2-force-randomization-of-dict-and-hash.patch |   45 ++
 libxml2-multilib.patch                             |   24 -
 libxml2.spec                                       |  107 ++++-
 37 files changed, 4721 insertions(+), 108 deletions(-)
---
diff --git a/libxml2-Add-hash-randomization-to-hash-and-dict-structures.patch b/libxml2-Add-hash-randomization-to-hash-and-dict-structures.patch
new file mode 100644
index 0000000..2a9f380
--- /dev/null
+++ b/libxml2-Add-hash-randomization-to-hash-and-dict-structures.patch
@@ -0,0 +1,300 @@
+From 97de04bc2b75d98a0d8c08f5a757b209d36812ed Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Sat, 4 Feb 2012 19:07:44 +0800
+Subject: [PATCH] Add hash randomization to hash and dict structures
+To: libvir-list at redhat.com
+
+Following http://www.ocert.org/advisories/ocert-2011-003.html
+it seems that having hash randomization might be a good idea
+when using XML with untrusted data
+* configure.in: lookup for rand, srand and time
+* dict.c: add randomization to dictionaries hash tables
+* hash.c: add randomization to normal hash tables
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ configure.in |  1 +
+ dict.c       | 81 ++++++++++++++++++++++++++++++++++++++++++------------------
+ hash.c       | 38 +++++++++++++++++++++++++++-
+ 3 files changed, 95 insertions(+), 25 deletions(-)
+
+diff --git a/configure.in b/configure.in
+index a1d2c89..d35c2e0 100644
+--- a/configure.in
++++ b/configure.in
+@@ -475,6 +475,7 @@ AC_CHECK_FUNCS(strdup strndup strerror)
+ AC_CHECK_FUNCS(finite isnand fp_class class fpclass)
+ AC_CHECK_FUNCS(strftime localtime gettimeofday ftime)
+ AC_CHECK_FUNCS(stat _stat signal)
++AC_CHECK_FUNCS(rand srand time)
+ 
+ dnl Checking the standard string functions availability
+ AC_CHECK_FUNCS(printf sprintf fprintf snprintf vfprintf vsprintf vsnprintf sscanf,,
+diff --git a/dict.c b/dict.c
+index 3eff231..d73d230 100644
+--- a/dict.c
++++ b/dict.c
+@@ -2,7 +2,7 @@
+  * dict.c: dictionary of reusable strings, just used to avoid allocation
+  *         and freeing operations.
+  *
+- * Copyright (C) 2003 Daniel Veillard.
++ * Copyright (C) 2003-2012 Daniel Veillard.
+  *
+  * Permission to use, copy, modify, and distribute this software for any
+  * purpose with or without fee is hereby granted, provided that the above
+@@ -19,6 +19,28 @@
+ #define IN_LIBXML
+ #include "libxml.h"
+ 
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++#ifdef HAVE_STDLIB_H
++#include <time.h>
++#endif
++
++/*
++ * Following http://www.ocert.org/advisories/ocert-2011-003.html
++ * it seems that having hash randomization might be a good idea
++ * when using XML with untrusted data
++ * Note1: that it works correctly only if compiled with WITH_BIG_KEY
++ *  which is the default.
++ * Note2: the fast function used for a small dict won't protect very
++ *  well but since the attack is based on growing a very big hash
++ *  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)
++#define DICT_RANDOMIZATION
++#endif
++
+ #include <string.h>
+ #ifdef HAVE_STDINT_H
+ #include <stdint.h>
+@@ -44,23 +66,23 @@ typedef unsigned __int32 uint32_t;
+ #define WITH_BIG_KEY
+ 
+ #ifdef WITH_BIG_KEY
+-#define xmlDictComputeKey(dict, name, len)			\
+-    (((dict)->size == MIN_DICT_SIZE) ?				\
+-     xmlDictComputeFastKey(name, len) :				\
+-     xmlDictComputeBigKey(name, len))
+-
+-#define xmlDictComputeQKey(dict, prefix, plen, name, len)	\
+-    (((prefix) == NULL) ?					\
+-      (xmlDictComputeKey(dict, name, len)) :			\
+-      (((dict)->size == MIN_DICT_SIZE) ?			\
+-       xmlDictComputeFastQKey(prefix, plen, name, len) :	\
+-       xmlDictComputeBigQKey(prefix, plen, name, len)))
++#define xmlDictComputeKey(dict, name, len)                              \
++    (((dict)->size == MIN_DICT_SIZE) ?                                  \
++     xmlDictComputeFastKey(name, len, (dict)->seed) :                   \
++     xmlDictComputeBigKey(name, len, (dict)->seed))
++
++#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
++    (((prefix) == NULL) ?                                               \
++      (xmlDictComputeKey(dict, name, len)) :                             \
++      (((dict)->size == MIN_DICT_SIZE) ?                                \
++       xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) :	\
++       xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
+ 
+ #else /* !WITH_BIG_KEY */
+-#define xmlDictComputeKey(dict, name, len)			\
+-        xmlDictComputeFastKey(name, len)
+-#define xmlDictComputeQKey(dict, prefix, plen, name, len)	\
+-        xmlDictComputeFastQKey(prefix, plen, name, len)
++#define xmlDictComputeKey(dict, name, len)                              \
++        xmlDictComputeFastKey(name, len, (dict)->seed)
++#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
++        xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
+ #endif /* WITH_BIG_KEY */
+ 
+ /*
+@@ -98,6 +120,8 @@ struct _xmlDict {
+     xmlDictStringsPtr strings;
+ 
+     struct _xmlDict *subdict;
++    /* used for randomization */
++    int seed;
+ };
+ 
+ /*
+@@ -125,6 +149,9 @@ static int xmlInitializeDict(void) {
+     if ((xmlDictMutex = xmlNewRMutex()) == NULL)
+         return(0);
+ 
++#ifdef DICT_RANDOMIZATION
++    srand(time(NULL));
++#endif
+     xmlDictInitialized = 1;
+     return(1);
+ }
+@@ -277,13 +304,13 @@ found_pool:
+  */
+ 
+ static uint32_t
+-xmlDictComputeBigKey(const xmlChar* data, int namelen) {
++xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
+     uint32_t hash;
+     int i;
+ 
+     if (namelen <= 0 || data == NULL) return(0);
+ 
+-    hash = 0;
++    hash = seed;
+ 
+     for (i = 0;i < namelen; i++) {
+         hash += data[i];
+@@ -310,12 +337,12 @@ xmlDictComputeBigKey(const xmlChar* data, int namelen) {
+  */
+ static unsigned long
+ xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
+-                      const xmlChar *name, int len)
++                      const xmlChar *name, int len, int seed)
+ {
+     uint32_t hash;
+     int i;
+ 
+-    hash = 0;
++    hash = seed;
+ 
+     for (i = 0;i < plen; i++) {
+         hash += prefix[i];
+@@ -346,8 +373,8 @@ xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
+  * for low hash table fill.
+  */
+ static unsigned long
+-xmlDictComputeFastKey(const xmlChar *name, int namelen) {
+-    unsigned long value = 0L;
++xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
++    unsigned long value = seed;
+ 
+     if (name == NULL) return(0);
+     value = *name;
+@@ -381,9 +408,9 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen) {
+  */
+ static unsigned long
+ xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
+-                       const xmlChar *name, int len)
++                       const xmlChar *name, int len, int seed)
+ {
+-    unsigned long value = 0L;
++    unsigned long value = (unsigned long) seed;
+ 
+     if (plen == 0)
+ 	value += 30 * (unsigned long) ':';
+@@ -460,6 +487,11 @@ xmlDictCreate(void) {
+ 	dict->subdict = NULL;
+         if (dict->dict) {
+ 	    memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
++#ifdef DICT_RANDOMIZATION
++            dict->seed = rand();
++#else
++            dict->seed = 0;
++#endif
+ 	    return(dict);
+         }
+         xmlFree(dict);
+@@ -486,6 +518,7 @@ xmlDictCreateSub(xmlDictPtr sub) {
+ #ifdef DICT_DEBUG_PATTERNS
+         fprintf(stderr, "R");
+ #endif
++        dict->seed = sub->seed;
+         dict->subdict = sub;
+ 	xmlDictReference(dict->subdict);
+     }
+diff --git a/hash.c b/hash.c
+index b78bc2d..02e01fb 100644
+--- a/hash.c
++++ b/hash.c
+@@ -3,7 +3,7 @@
+  *
+  * Reference: Your favorite introductory book on algorithms
+  *
+- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
++ * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
+  *
+  * Permission to use, copy, modify, and distribute this software for any
+  * purpose with or without fee is hereby granted, provided that the above
+@@ -21,6 +21,22 @@
+ #include "libxml.h"
+ 
+ #include <string.h>
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++#ifdef HAVE_STDLIB_H
++#include <time.h>
++#endif
++
++/*
++ * Following http://www.ocert.org/advisories/ocert-2011-003.html
++ * 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)
++#define HASH_RANDOMIZATION
++#endif
++
+ #include <libxml/parser.h>
+ #include <libxml/hash.h>
+ #include <libxml/xmlmemory.h>
+@@ -31,6 +47,10 @@
+ 
+ /* #define DEBUG_GROW */
+ 
++#ifdef HASH_RANDOMIZATION
++static int hash_initialized = 0;
++#endif
++
+ /*
+  * A single entry in the hash table
+  */
+@@ -53,6 +73,9 @@ struct _xmlHashTable {
+     int size;
+     int nbElems;
+     xmlDictPtr dict;
++#ifdef HASH_RANDOMIZATION
++    int random_seed;
++#endif
+ };
+ 
+ /*
+@@ -65,6 +88,9 @@ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
+     unsigned long value = 0L;
+     char ch;
+     
++#ifdef HASH_RANDOMIZATION
++    value = table->random_seed;
++#endif
+     if (name != NULL) {
+ 	value += 30 * (*name);
+ 	while ((ch = *name++) != 0) {
+@@ -92,6 +118,9 @@ xmlHashComputeQKey(xmlHashTablePtr table,
+     unsigned long value = 0L;
+     char ch;
+     
++#ifdef HASH_RANDOMIZATION
++    value = table->random_seed;
++#endif
+     if (prefix != NULL)
+ 	value += 30 * (*prefix);
+     else
+@@ -156,6 +185,13 @@ xmlHashCreate(int size) {
+         table->table = xmlMalloc(size * sizeof(xmlHashEntry));
+         if (table->table) {
+   	    memset(table->table, 0, size * sizeof(xmlHashEntry));
++#ifdef HASH_RANDOMIZATION
++            if (!hash_initialized) {
++                srand(time(NULL));
++                hash_initialized = 1;
++            }
++            table->random_seed = rand();
++#endif
+   	    return(table);
+         }
+         xmlFree(table);
+-- 
+1.7.11.4
+
diff --git a/libxml2-Avoid-quadratic-behaviour-in-some-push-parsing-cases.patch b/libxml2-Avoid-quadratic-behaviour-in-some-push-parsing-cases.patch
new file mode 100644
index 0000000..b65f533
--- /dev/null
+++ b/libxml2-Avoid-quadratic-behaviour-in-some-push-parsing-cases.patch
@@ -0,0 +1,247 @@
+From de7893b8e2d73cb9512da7cb7f142d3c31dbbfb5 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 19 Jul 2012 18:25:01 +0800
+Subject: [PATCH] Avoid quadratic behaviour in some push parsing cases
+To: libvir-list at redhat.com
+
+avoid rescanning over and over a very long input, just check
+the incoming chunks
+
+Conflicts:
+	parser.c: needed some massaging to apply on 2.7.6
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 74 insertions(+), 17 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 78ae09b..0bb4591 100644
+--- a/parser.c
++++ b/parser.c
+@@ -7303,8 +7303,6 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
+ 	     * Seems we are generating the DOM content, do
+ 	     * a simple tree copy for all references except the first
+ 	     * In the first occurrence list contains the replacement.
+-	     * progressive == 2 means we are operating on the Reader
+-	     * and since nodes are discarded we must copy all the time.
+ 	     */
+ 	    if (((list == NULL) && (ent->owner == 0)) ||
+ 		(ctxt->parseMode == XML_PARSE_READER)) {
+@@ -11283,6 +11281,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    } else {
+ 			ctxt->instate = XML_PARSER_CONTENT;
+ 		    }
++                    ctxt->progressive = 1;
+ 		    break;
+ 		}
+ 		if (RAW == '>') {
+@@ -11302,6 +11301,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ #endif /* LIBXML_SAX1_ENABLED */
+ 
+ 		ctxt->instate = XML_PARSER_CONTENT;
++                ctxt->progressive = 1;
+                 break;
+ 	    }
+             case XML_PARSER_CONTENT: {
+@@ -11335,10 +11335,13 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    ctxt->input->cur += 4;
+ 		    term = xmlParseLookupSequence(ctxt, '-', '-', '>');
+ 		    ctxt->input->cur -= 4;
+-		    if ((!terminate) && (term < 0))
++		    if ((!terminate) && (term < 0)) {
++                        ctxt->progressive = XML_PARSER_COMMENT;
+ 			goto done;
++                    }
+ 		    xmlParseComment(ctxt);
+ 		    ctxt->instate = XML_PARSER_CONTENT;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
+ 		    (ctxt->input->cur[2] == '[') &&
+ 		    (ctxt->input->cur[3] == 'C') &&
+@@ -11529,14 +11532,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    (ctxt->input->cur[2] == '-') &&
+ 		    (ctxt->input->cur[3] == '-')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
++		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
++                        ctxt->progressive = XML_PARSER_COMMENT;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing Comment\n");
+ #endif
+ 		    xmlParseComment(ctxt);
+ 		    ctxt->instate = XML_PARSER_MISC;
++                    ctxt->progressive = 1;
+ 		    ctxt->checkIndex = 0;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == 'D') &&
+@@ -11584,7 +11590,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    goto done;
+ 		} else {
+ 		    ctxt->instate = XML_PARSER_START_TAG;
+-		    ctxt->progressive = 1;
++		    ctxt->progressive = XML_PARSER_START_TAG;
+ 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+@@ -11614,21 +11620,24 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
++		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
++                        ctxt->progressive = XML_PARSER_COMMENT;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing Comment\n");
+ #endif
+ 		    xmlParseComment(ctxt);
+ 		    ctxt->instate = XML_PARSER_PROLOG;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		           (avail < 4)) {
+ 		    goto done;
+ 		} else {
+ 		    ctxt->instate = XML_PARSER_START_TAG;
+ 		    if (ctxt->progressive == 0)
+-			ctxt->progressive = 1;
++			ctxt->progressive = XML_PARSER_START_TAG;
+ 		    xmlParseGetLasts(ctxt, &lastlt, &lastgt);
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+@@ -11659,14 +11668,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0))
++		        (xmlParseLookupSequence(ctxt, '-', '-', '>') < 0)) {
++                        ctxt->progressive = XML_PARSER_COMMENT;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing Comment\n");
+ #endif
+ 		    xmlParseComment(ctxt);
+ 		    ctxt->instate = XML_PARSER_EPILOG;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		           (avail < 4)) {
+ 		    goto done;
+@@ -11903,6 +11915,34 @@ encoding_error:
+ }
+ 
+ /**
++ * xmlParseCheckTransition:
++ * @ctxt:  an XML parser context
++ * @chunk:  a char array
++ * @size:  the size in byte of the chunk
++ *
++ * Check depending on the current parser state if the chunk given must be
++ * processed immediately or one need more data to advance on parsing.
++ *
++ * Returns -1 in case of error, 0 if the push is not needed and 1 if needed
++ */
++static int
++xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
++    if ((ctxt == NULL) || (chunk == NULL) || (size < 0))
++        return(-1);
++    if (ctxt->instate == XML_PARSER_START_TAG) {
++        if (memchr(chunk, '>', size) != NULL)
++            return(1);
++        return(0);
++    }
++    if (ctxt->progressive == XML_PARSER_COMMENT) {
++        if (memchr(chunk, '>', size) != NULL)
++            return(1);
++        return(0);
++    }
++    return(1);
++}
++
++/**
+  * xmlParseChunk:
+  * @ctxt:  an XML parser context
+  * @chunk:  an char array
+@@ -11918,6 +11958,8 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
+               int terminate) {
+     int end_in_lf = 0;
+     int remain = 0;
++    size_t old_avail = 0;
++    size_t avail = 0;
+ 
+     if (ctxt == NULL)
+         return(XML_ERR_INTERNAL_ERROR);
+@@ -11941,6 +11983,7 @@ xmldecl_done:
+ 	int cur = ctxt->input->cur - ctxt->input->base;
+ 	int res;
+ 
++        old_avail = ctxt->input->buf->buffer->use;
+         /*
+          * Specific handling if we autodetected an encoding, we should not
+          * push more than the first line ... which depend on the encoding
+@@ -12007,10 +12050,24 @@ xmldecl_done:
+ 	    }
+ 	}
+     }
+-    if (remain != 0)
++    if (remain != 0) {
+         xmlParseTryOrFinish(ctxt, 0);
+-    else
+-        xmlParseTryOrFinish(ctxt, terminate);
++    } else {
++        if ((ctxt->input != NULL) && (ctxt->input->buf != NULL))
++            avail = ctxt->input->buf->buffer->use;
++        /*
++         * Depending on the current state it may not be such
++         * a good idea to try parsing if there is nothing in the chunk
++         * which would be worth doing a parser state transition and we
++         * need to wait for more data
++         */
++        if ((terminate) || (avail > XML_MAX_TEXT_LENGTH) ||
++            (old_avail == 0) || (avail == 0) ||
++            (xmlParseCheckTransition(ctxt,
++                       (const char *)&ctxt->input->base[old_avail],
++                                     avail - old_avail)))
++            xmlParseTryOrFinish(ctxt, terminate);
++    }
+     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+         return(ctxt->errNo);
+ 
+@@ -12028,22 +12085,22 @@ xmldecl_done:
+ 	/*
+ 	 * Check for termination
+ 	 */
+-	int avail = 0;
++	int cur_avail = 0;
+ 
+ 	if (ctxt->input != NULL) {
+ 	    if (ctxt->input->buf == NULL)
+-		avail = ctxt->input->length -
+-			(ctxt->input->cur - ctxt->input->base);
++		cur_avail = ctxt->input->length -
++			    (ctxt->input->cur - ctxt->input->base);
+ 	    else
+-		avail = ctxt->input->buf->buffer->use -
++		cur_avail = ctxt->input->buf->buffer->use -
+ 			(ctxt->input->cur - ctxt->input->base);
+ 	}
+ 			    
+ 	if ((ctxt->instate != XML_PARSER_EOF) &&
+ 	    (ctxt->instate != XML_PARSER_EPILOG)) {
+ 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+-	} 
+-	if ((ctxt->instate == XML_PARSER_EPILOG) && (avail > 0)) {
++	}
++	if ((ctxt->instate == XML_PARSER_EPILOG) && (cur_avail > 0)) {
+ 	    xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+ 	}
+ 	if (ctxt->instate != XML_PARSER_EOF) {
+-- 
+1.7.11.4
+
diff --git a/libxml2-Change-the-XPath-code-to-percolate-allocation-errors.patch b/libxml2-Change-the-XPath-code-to-percolate-allocation-errors.patch
new file mode 100644
index 0000000..8da0cd0
--- /dev/null
+++ b/libxml2-Change-the-XPath-code-to-percolate-allocation-errors.patch
@@ -0,0 +1,484 @@
+From 5543440af0c7c2da8f292ea624cf79d7fb0a6fbf Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Wed, 5 Sep 2012 15:35:19 +0800
+Subject: [PATCH] Change the XPath code to percolate allocation errors
+To: libvir-list at redhat.com
+
+looping 1000 time on an error stating that a nodeset has
+grown out of control is useless, make sure we percolate
+error up to the various loops and break when errors occurs
+
+Conflicts:
+	xpath.c: solve a couple of context differences
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ include/libxml/xpathInternals.h |   6 +-
+ xpath.c                         | 156 ++++++++++++++++++++++++++--------------
+ 2 files changed, 107 insertions(+), 55 deletions(-)
+
+diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h
+index dcd5243..02e8f46 100644
+--- a/include/libxml/xpathInternals.h
++++ b/include/libxml/xpathInternals.h
+@@ -498,13 +498,13 @@ XMLPUBFUN xmlXPathObjectPtr XMLCALL
+ 		xmlXPathNewNodeSet		(xmlNodePtr val);
+ XMLPUBFUN xmlXPathObjectPtr XMLCALL 
+ 		xmlXPathNewValueTree		(xmlNodePtr val);
+-XMLPUBFUN void XMLCALL		  
++XMLPUBFUN int XMLCALL		  
+ 		xmlXPathNodeSetAdd		(xmlNodeSetPtr cur,
+ 						 xmlNodePtr val);
+-XMLPUBFUN void XMLCALL              
++XMLPUBFUN int XMLCALL              
+ 		xmlXPathNodeSetAddUnique	(xmlNodeSetPtr cur,
+ 						 xmlNodePtr val);
+-XMLPUBFUN void XMLCALL		  
++XMLPUBFUN int XMLCALL		  
+ 		xmlXPathNodeSetAddNs		(xmlNodeSetPtr cur, 
+ 						 xmlNodePtr node, 
+ 						 xmlNsPtr ns);
+diff --git a/xpath.c b/xpath.c
+index a983f41..3936e97 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -2088,6 +2088,11 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
+ 	    ret->type = XPATH_NODESET;
+ 	    ret->boolval = 0;
+ 	    ret->nodesetval = xmlXPathNodeSetCreate(val);
++	    if (ret->nodesetval == NULL) {
++		ctxt->lastError.domain = XML_FROM_XPATH;
++		ctxt->lastError.code = XML_ERR_NO_MEMORY;
++		return(NULL);
++	    }
+ #ifdef XP_DEBUG_OBJ_USAGE
+ 	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
+ #endif
+@@ -3568,8 +3573,10 @@ xmlXPathNodeSetContains (xmlNodeSetPtr cur, xmlNodePtr val) {
+  * @ns:  a the namespace node
+  *
+  * add a new namespace node to an existing NodeSet
++ *
++ * Returns 0 in case of success and -1 in case of error
+  */
+-void
++int
+ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+     int i;
+ 
+@@ -3577,7 +3584,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+     if ((cur == NULL) || (ns == NULL) || (node == NULL) ||
+         (ns->type != XML_NAMESPACE_DECL) ||
+ 	(node->type != XML_ELEMENT_NODE))
+-	return;
++	return(-1);
+ 
+     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+     /*
+@@ -3588,7 +3595,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+ 	    (cur->nodeTab[i]->type == XML_NAMESPACE_DECL) &&
+ 	    (((xmlNsPtr)cur->nodeTab[i])->next == (xmlNsPtr) node) &&
+ 	    (xmlStrEqual(ns->prefix, ((xmlNsPtr)cur->nodeTab[i])->prefix)))
+-	    return;
++	    return(0);
+     }
+ 
+     /*
+@@ -3599,7 +3606,7 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+ 					     sizeof(xmlNodePtr));
+ 	if (cur->nodeTab == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+ 	memset(cur->nodeTab, 0 ,
+ 	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+@@ -3609,18 +3616,19 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+ 
+         if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+             xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+-            return;
++            return(-1);
+         }
+ 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+         cur->nodeMax *= 2;
+ 	cur->nodeTab = temp;
+     }
+     cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
++    return(0);
+ }
+ 
+ /**
+@@ -3629,19 +3637,21 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+  * @val:  a new xmlNodePtr
+  *
+  * add a new xmlNodePtr to an existing NodeSet
++ *
++ * Returns 0 in case of success, and -1 in case of error
+  */
+-void
++int
+ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+     int i;
+ 
+-    if ((cur == NULL) || (val == NULL)) return;
++    if ((cur == NULL) || (val == NULL)) return(-1);
+ 
+     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+     /*
+      * prevent duplcates
+      */
+     for (i = 0;i < cur->nodeNr;i++)
+-        if (cur->nodeTab[i] == val) return;
++        if (cur->nodeTab[i] == val) return(0);
+ 
+     /*
+      * grow the nodeTab if needed
+@@ -3651,7 +3661,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 					     sizeof(xmlNodePtr));
+ 	if (cur->nodeTab == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+ 	memset(cur->nodeTab, 0 ,
+ 	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+@@ -3661,13 +3671,13 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 
+         if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+             xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+-            return;
++            return(-1);
+         }
+ 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				         sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+         cur->nodeMax *= 2;
+ 	cur->nodeTab = temp;
+@@ -3679,6 +3689,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+     } else
+ 	cur->nodeTab[cur->nodeNr++] = val;
++    return(0);
+ }
+ 
+ /**
+@@ -3688,10 +3699,12 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+  *
+  * add a new xmlNodePtr to an existing NodeSet, optimized version
+  * when we are sure the node is not already in the set.
++ *
++ * Returns 0 in case of success and -1 in case of failure
+  */
+-void
++int
+ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+-    if ((cur == NULL) || (val == NULL)) return;
++    if ((cur == NULL) || (val == NULL)) return(-1);
+ 
+     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+     /*
+@@ -3702,7 +3715,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 					     sizeof(xmlNodePtr));
+ 	if (cur->nodeTab == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+ 	memset(cur->nodeTab, 0 ,
+ 	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+@@ -3712,13 +3725,13 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 
+         if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
+             xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
+-            return;
++            return(-1);
+         }
+ 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+-	    return;
++	    return(-1);
+ 	}
+ 	cur->nodeTab = temp;
+         cur->nodeMax *= 2;
+@@ -3730,6 +3743,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 	    xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+     } else
+ 	cur->nodeTab[cur->nodeNr++] = val;
++    return(0);
+ }
+ 
+ /**
+@@ -4326,9 +4340,12 @@ xmlXPathNewNodeSetList(xmlNodeSetPtr val)
+         ret = xmlXPathNewNodeSet(NULL);
+     else {
+         ret = xmlXPathNewNodeSet(val->nodeTab[0]);
+-        if (ret)
+-            for (i = 1; i < val->nodeNr; ++i)
+-                xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
++        if (ret) {
++            for (i = 1; i < val->nodeNr; ++i) {
++                if (xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i])
++		    < 0) break;
++	    }
++	}
+     }
+ 
+     return (ret);
+@@ -4404,8 +4421,10 @@ xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+ 
+     for (i = 0; i < l1; i++) {
+ 	cur = xmlXPathNodeSetItem(nodes1, i);
+-	if (!xmlXPathNodeSetContains(nodes2, cur))
+-	    xmlXPathNodeSetAddUnique(ret, cur);
++	if (!xmlXPathNodeSetContains(nodes2, cur)) {
++	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
++	        break;
++	}
+     }
+     return(ret);
+ }
+@@ -4438,8 +4457,10 @@ xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
+ 
+     for (i = 0; i < l1; i++) {
+ 	cur = xmlXPathNodeSetItem(nodes1, i);
+-	if (xmlXPathNodeSetContains(nodes2, cur))
+-	    xmlXPathNodeSetAddUnique(ret, cur);
++	if (xmlXPathNodeSetContains(nodes2, cur)) {
++	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
++	        break;
++	}
+     }
+     return(ret);
+ }
+@@ -4475,7 +4496,8 @@ xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
+ 	strval = xmlXPathCastNodeToString(cur);
+ 	if (xmlHashLookup(hash, strval) == NULL) {
+ 	    xmlHashAddEntry(hash, strval, strval);
+-	    xmlXPathNodeSetAddUnique(ret, cur);
++	    if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
++	        break;
+ 	} else {
+ 	    xmlFree(strval);
+ 	}
+@@ -4567,7 +4589,8 @@ xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
+ 	cur = xmlXPathNodeSetItem(nodes, i);
+ 	if (cur == node)
+ 	    break;
+-	xmlXPathNodeSetAddUnique(ret, cur);
++	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
++	    break;
+     }
+     return(ret);
+ }
+@@ -4671,7 +4694,8 @@ xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) {
+ 	cur = xmlXPathNodeSetItem(nodes, i);
+ 	if (cur == node)
+ 	    break;
+-	xmlXPathNodeSetAddUnique(ret, cur);
++	if (xmlXPathNodeSetAddUnique(ret, cur) < 0)
++	    break;
+     }
+     xmlXPathNodeSetSort(ret);	/* bug 413451 */
+     return(ret);
+@@ -11659,9 +11683,13 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt,
+ 	    */
+ 	    if (contextObj == NULL)
+ 		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
+-	    else
+-		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+-		    contextNode);
++	    else {
++		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
++		    contextNode) < 0) {
++		    ctxt->error = XPATH_MEMORY_ERROR;
++		    goto evaluation_exit;
++		}
++	    }
+ 
+ 	    valuePush(ctxt, contextObj);
+ 
+@@ -11807,9 +11835,13 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 	    */
+ 	    if (contextObj == NULL)
+ 		contextObj = xmlXPathCacheNewNodeSet(xpctxt, contextNode);
+-	    else
+-		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+-		    contextNode);
++	    else {
++		if (xmlXPathNodeSetAddUnique(contextObj->nodesetval,
++		    contextNode) < 0) {
++		    ctxt->error = XPATH_MEMORY_ERROR;
++		    goto evaluation_exit;
++		}
++	    }
+ 
+             frame = xmlXPathSetFrame(ctxt);
+ 	    valuePush(ctxt, contextObj);
+@@ -11981,22 +12013,25 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
+ #define XP_TEST_HIT \
+     if (hasAxisRange != 0) { \
+ 	if (++pos == maxPos) { \
+-	    addNode(seq, cur); \
+-	goto axis_range_end; } \
++	    if (addNode(seq, cur) < 0) \
++	        ctxt->error = XPATH_MEMORY_ERROR; \
++	    goto axis_range_end; } \
+     } else { \
+-	addNode(seq, cur); \
++	if (addNode(seq, cur) < 0) \
++	    ctxt->error = XPATH_MEMORY_ERROR; \
+ 	if (breakOnFirstHit) goto first_hit; }
+ 
+ #define XP_TEST_HIT_NS \
+     if (hasAxisRange != 0) { \
+ 	if (++pos == maxPos) { \
+ 	    hasNsNodes = 1; \
+-	    xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur); \
++	    if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
++	        ctxt->error = XPATH_MEMORY_ERROR; \
+ 	goto axis_range_end; } \
+     } else { \
+ 	hasNsNodes = 1; \
+-	xmlXPathNodeSetAddNs(seq, \
+-	xpctxt->node, (xmlNsPtr) cur); \
++	if (xmlXPathNodeSetAddNs(seq, xpctxt->node, (xmlNsPtr) cur) < 0) \
++	    ctxt->error = XPATH_MEMORY_ERROR; \
+ 	if (breakOnFirstHit) goto first_hit; }
+ 
+     xmlXPathAxisVal axis = (xmlXPathAxisVal) op->value;
+@@ -12035,7 +12070,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
+     xmlXPathTraversalFunction next = NULL;
+     /* compound axis traversal */
+     xmlXPathTraversalFunctionExt outerNext = NULL;
+-    void (*addNode) (xmlNodeSetPtr, xmlNodePtr);
++    int (*addNode) (xmlNodeSetPtr, xmlNodePtr);
+     xmlXPathNodeSetMergeFunction mergeAndClear;
+     xmlNodePtr oldContextNode;
+     xmlXPathContextPtr xpctxt = ctxt->context;
+@@ -12225,7 +12260,8 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
+     contextIdx = 0;
+ 
+ 
+-    while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL)) {
++    while ((contextIdx < contextSeq->nodeNr) || (contextNode != NULL) &&
++           (ctxt->error == XPATH_EXPRESSION_OK)) {
+ 	if (outerNext != NULL) {
+ 	    /*
+ 	    * This is a compound traversal.
+@@ -12443,7 +12479,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
+                     }
+                     break;
+ 	    } /* switch(test) */
+-        } while (cur != NULL);
++        } while ((cur != NULL) && (ctxt->error == XPATH_EXPRESSION_OK));
+ 
+ 	goto apply_predicates;
+ 
+@@ -12484,6 +12520,9 @@ first_hit: /* ---------------------------------------------------------- */
+ #endif
+ 
+ apply_predicates: /* --------------------------------------------------- */
++        if (ctxt->error != XPATH_EXPRESSION_OK)
++	    goto error;
++
+         /*
+ 	* Apply predicates.
+ 	*/
+@@ -12992,8 +13031,10 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
+ 		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+ 		    ctxt->context->node);
+ 	    } else {
+-		xmlXPathNodeSetAddUnique(tmp->nodesetval,
+-		    ctxt->context->node);
++		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
++		                             ctxt->context->node) < 0) {
++		    ctxt->error = XPATH_MEMORY_ERROR;
++		}
+ 	    }
+ 	    valuePush(ctxt, tmp);
+ 	    if (op->ch2 != -1)
+@@ -13106,8 +13147,10 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
+ 		tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+ 		    ctxt->context->node);
+ 	    } else {
+-		xmlXPathNodeSetAddUnique(tmp->nodesetval,
+-		    ctxt->context->node);
++		if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
++		                             ctxt->context->node) < 0) {
++		    ctxt->error = XPATH_MEMORY_ERROR;
++		}
+ 	    }
+ 	    valuePush(ctxt, tmp);
+ 	    ctxt->context->contextSize = oldset->nodeNr;
+@@ -13125,7 +13168,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
+ 	    */
+ 	    res = valuePop(ctxt);
+ 	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+-		xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
++		if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]) < 0)
++		    ctxt->error = XPATH_MEMORY_ERROR;
+ 	    }
+ 	    /*
+ 	    * Cleanup
+@@ -13804,8 +13848,10 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+ 			    tmp = xmlXPathCacheNewNodeSet(ctxt->context,
+ 				ctxt->context->node);
+ 			} else {
+-			    xmlXPathNodeSetAddUnique(tmp->nodesetval,
+-				ctxt->context->node);
++			    if (xmlXPathNodeSetAddUnique(tmp->nodesetval,
++				               ctxt->context->node) < 0) {
++				ctxt->error = XPATH_MEMORY_ERROR;
++			    }
+ 			}
+                         valuePush(ctxt, tmp);
+                         ctxt->context->contextSize = oldset->nodeNr;
+@@ -13835,7 +13881,9 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+ 			*/
+                         res = valuePop(ctxt);
+                         if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
+-                            xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
++                            if (xmlXPathNodeSetAdd(newset, oldset->nodeTab[i])
++			        < 0)
++				ctxt->error = XPATH_MEMORY_ERROR;
+                         }
+ 
+                         /*
+@@ -14198,7 +14246,7 @@ xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp,
+ 	    if (toBool)
+ 		return(1);
+ 	    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval,
+-		(xmlNodePtr) ctxt->doc);
++		                     (xmlNodePtr) ctxt->doc);
+ 	} else {
+ 	    /* Select "self::node()" */
+ 	    if (toBool)
+@@ -14291,7 +14339,11 @@ next_node:
+ 		} else if (ret == 1) {
+ 		    if (toBool)
+ 			goto return_1;
+-		    xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur);
++		    if (xmlXPathNodeSetAddUnique((*resultSeq)->nodesetval, cur)
++		        < 0) {
++			ctxt->lastError.domain = XML_FROM_XPATH;
++			ctxt->lastError.code = XML_ERR_NO_MEMORY;
++		    }
+ 		}
+ 		if ((cur->children == NULL) || (depth >= max_depth)) {
+ 		    ret = xmlStreamPop(patstream);
+-- 
+1.7.11.4
+
diff --git a/libxml2-Cleanups-and-new-limit-APIs-for-dictionaries.patch b/libxml2-Cleanups-and-new-limit-APIs-for-dictionaries.patch
new file mode 100644
index 0000000..3054c5a
--- /dev/null
+++ b/libxml2-Cleanups-and-new-limit-APIs-for-dictionaries.patch
@@ -0,0 +1,519 @@
+From f21e6d04502c872974df198facbf5d7787dfefb5 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Wed, 25 Jul 2012 16:32:18 +0800
+Subject: [PATCH] Cleanups and new limit APIs for dictionaries
+To: libvir-list at redhat.com
+
+* include/libxml/dict.h dict.c: adding 2 new functions xmlDictGetUsage
+  and xmlDictSetLimit allowing to review the amount of memory allocated
+  for dictionary strings. Aslo cleanup of various signed int used as
+  size values in the code.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ dict.c                | 193 ++++++++++++++++++++++++++++++++++----------------
+ include/libxml/dict.h |   6 ++
+ 2 files changed, 139 insertions(+), 60 deletions(-)
+
+diff --git a/dict.c b/dict.c
+index bd64afb..3ad89b5 100644
+--- a/dict.c
++++ b/dict.c
+@@ -19,6 +19,7 @@
+ #define IN_LIBXML
+ #include "libxml.h"
+ 
++#include <limits.h>
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
+@@ -96,7 +97,7 @@ typedef xmlDictEntry *xmlDictEntryPtr;
+ struct _xmlDictEntry {
+     struct _xmlDictEntry *next;
+     const xmlChar *name;
+-    int len;
++    unsigned int len;
+     int valid;
+     unsigned long okey;
+ };
+@@ -107,8 +108,8 @@ struct _xmlDictStrings {
+     xmlDictStringsPtr next;
+     xmlChar *free;
+     xmlChar *end;
+-    int size;
+-    int nbStrings;
++    size_t size;
++    size_t nbStrings;
+     xmlChar array[1];
+ };
+ /*
+@@ -118,13 +119,15 @@ struct _xmlDict {
+     int ref_counter;
+ 
+     struct _xmlDictEntry *dict;
+-    int size;
+-    int nbElems;
++    size_t size;
++    unsigned int nbElems;
+     xmlDictStringsPtr strings;
+ 
+     struct _xmlDict *subdict;
+     /* used for randomization */
+     int seed;
++    /* used to impose a limit on size */
++    size_t limit;
+ };
+ 
+ /*
+@@ -178,17 +181,18 @@ xmlDictCleanup(void) {
+  * xmlDictAddString:
+  * @dict: the dictionnary
+  * @name: the name of the userdata
+- * @len: the length of the name, if -1 it is recomputed
++ * @len: the length of the name
+  *
+  * Add the string to the array[s]
+  *
+  * Returns the pointer of the local string, or NULL in case of error.
+  */
+ static const xmlChar *
+-xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
++xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
+     xmlDictStringsPtr pool;
+     const xmlChar *ret;
+-    int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
++    size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
++    size_t limit = 0;
+ 
+ #ifdef DICT_DEBUG_PATTERNS
+     fprintf(stderr, "-");
+@@ -198,15 +202,20 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
+ 	if (pool->end - pool->free > namelen)
+ 	    goto found_pool;
+ 	if (pool->size > size) size = pool->size;
++        limit += pool->size;
+ 	pool = pool->next;
+     }
+     /*
+      * Not found, need to allocate
+      */
+     if (pool == NULL) {
++        if ((dict->limit > 0) && (limit > dict->limit)) {
++            return(NULL);
++        }
++
+         if (size == 0) size = 1000;
+ 	else size *= 4; /* exponential growth */
+-        if (size < 4 * namelen) 
++        if (size < 4 * namelen)
+ 	    size = 4 * namelen; /* just in case ! */
+ 	pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
+ 	if (pool == NULL)
+@@ -236,19 +245,20 @@ found_pool:
+  * @prefix: the prefix of the userdata
+  * @plen: the prefix length
+  * @name: the name of the userdata
+- * @len: the length of the name, if -1 it is recomputed
++ * @len: the length of the name
+  *
+  * Add the QName to the array[s]
+  *
+  * Returns the pointer of the local string, or NULL in case of error.
+  */
+ static const xmlChar *
+-xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
+-                 const xmlChar *name, int namelen)
++xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
++                 const xmlChar *name, unsigned int namelen)
+ {
+     xmlDictStringsPtr pool;
+     const xmlChar *ret;
+-    int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
++    size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
++    size_t limit = 0;
+ 
+     if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
+ 
+@@ -260,12 +270,17 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
+ 	if (pool->end - pool->free > namelen + plen + 1)
+ 	    goto found_pool;
+ 	if (pool->size > size) size = pool->size;
++        limit += pool->size;
+ 	pool = pool->next;
+     }
+     /*
+      * Not found, need to allocate
+      */
+     if (pool == NULL) {
++        if ((dict->limit > 0) && (limit > dict->limit)) {
++            return(NULL);
++        }
++
+         if (size == 0) size = 1000;
+ 	else size *= 4; /* exponential growth */
+         if (size < 4 * (namelen + plen + 1))
+@@ -482,6 +497,7 @@ xmlDictCreate(void) {
+     dict = xmlMalloc(sizeof(xmlDict));
+     if (dict) {
+         dict->ref_counter = 1;
++        dict->limit = 0;
+ 
+         dict->size = MIN_DICT_SIZE;
+ 	dict->nbElems = 0;
+@@ -559,9 +575,9 @@ xmlDictReference(xmlDictPtr dict) {
+  * Returns 0 in case of success, -1 in case of failure
+  */
+ static int
+-xmlDictGrow(xmlDictPtr dict, int size) {
++xmlDictGrow(xmlDictPtr dict, size_t size) {
+     unsigned long key, okey;
+-    int oldsize, i;
++    size_t oldsize, i;
+     xmlDictEntryPtr iter, next;
+     struct _xmlDictEntry *olddict;
+ #ifdef DEBUG_GROW
+@@ -678,7 +694,7 @@ xmlDictGrow(xmlDictPtr dict, int size) {
+ 
+ #ifdef DEBUG_GROW
+     xmlGenericError(xmlGenericErrorContext,
+-	    "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
++	    "xmlDictGrow : from %lu to %lu, %u elems\n", oldsize, size, nbElem);
+ #endif
+ 
+     return(ret);
+@@ -693,7 +709,7 @@ xmlDictGrow(xmlDictPtr dict, int size) {
+  */
+ void
+ xmlDictFree(xmlDictPtr dict) {
+-    int i;
++    size_t i;
+     xmlDictEntryPtr iter;
+     xmlDictEntryPtr next;
+     int inside_dict = 0;
+@@ -762,17 +778,24 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+     xmlDictEntryPtr entry;
+     xmlDictEntryPtr insert;
+     const xmlChar *ret;
++    unsigned int l;
+ 
+     if ((dict == NULL) || (name == NULL))
+ 	return(NULL);
+ 
+     if (len < 0)
+-        len = strlen((const char *) name);
++        l = strlen((const char *) name);
++    else
++        l = len;
++
++    if (((dict->limit > 0) && (l >= dict->limit)) ||
++        (l > INT_MAX / 2))
++        return(NULL);
+ 
+     /*
+      * Check for duplicate and insertion location.
+      */
+-    okey = xmlDictComputeKey(dict, name, len);
++    okey = xmlDictComputeKey(dict, name, l);
+     key = okey % dict->size;
+     if (dict->dict[key].valid == 0) {
+ 	insert = NULL;
+@@ -780,25 +803,25 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	for (insert = &(dict->dict[key]); insert->next != NULL;
+ 	     insert = insert->next) {
+ #ifdef __GNUC__
+-	    if ((insert->okey == okey) && (insert->len == len)) {
+-		if (!memcmp(insert->name, name, len))
++	    if ((insert->okey == okey) && (insert->len == l)) {
++		if (!memcmp(insert->name, name, l))
+ 		    return(insert->name);
+ 	    }
+ #else
+-	    if ((insert->okey == okey) && (insert->len == len) &&
+-	        (!xmlStrncmp(insert->name, name, len)))
++	    if ((insert->okey == okey) && (insert->l == l) &&
++	        (!xmlStrncmp(insert->name, name, l)))
+ 		return(insert->name);
+ #endif
+ 	    nbi++;
+ 	}
+ #ifdef __GNUC__
+-	if ((insert->okey == okey) && (insert->len == len)) {
+-	    if (!memcmp(insert->name, name, len))
++	if ((insert->okey == okey) && (insert->len == l)) {
++	    if (!memcmp(insert->name, name, l))
+ 		return(insert->name);
+ 	}
+ #else
+-	if ((insert->okey == okey) && (insert->len == len) &&
+-	    (!xmlStrncmp(insert->name, name, len)))
++	if ((insert->okey == okey) && (insert->len == l) &&
++	    (!xmlStrncmp(insert->name, name, l)))
+ 	    return(insert->name);
+ #endif
+     }
+@@ -811,7 +834,7 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	     (dict->subdict->size != MIN_DICT_SIZE)) ||
+             ((dict->size != MIN_DICT_SIZE) &&
+ 	     (dict->subdict->size == MIN_DICT_SIZE)))
+-	    skey = xmlDictComputeKey(dict->subdict, name, len);
++	    skey = xmlDictComputeKey(dict->subdict, name, l);
+ 	else
+ 	    skey = okey;
+ 
+@@ -822,32 +845,32 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	    for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
+ 		 tmp = tmp->next) {
+ #ifdef __GNUC__
+-		if ((tmp->okey == skey) && (tmp->len == len)) {
+-		    if (!memcmp(tmp->name, name, len))
++		if ((tmp->okey == skey) && (tmp->len == l)) {
++		    if (!memcmp(tmp->name, name, l))
+ 			return(tmp->name);
+ 		}
+ #else
+-		if ((tmp->okey == skey) && (tmp->len == len) &&
+-		    (!xmlStrncmp(tmp->name, name, len)))
++		if ((tmp->okey == skey) && (tmp->len == l) &&
++		    (!xmlStrncmp(tmp->name, name, l)))
+ 		    return(tmp->name);
+ #endif
+ 		nbi++;
+ 	    }
+ #ifdef __GNUC__
+-	    if ((tmp->okey == skey) && (tmp->len == len)) {
+-		if (!memcmp(tmp->name, name, len))
++	    if ((tmp->okey == skey) && (tmp->len == l)) {
++		if (!memcmp(tmp->name, name, l))
+ 		    return(tmp->name);
+ 	    }
+ #else
+-	    if ((tmp->okey == skey) && (tmp->len == len) &&
+-		(!xmlStrncmp(tmp->name, name, len)))
++	    if ((tmp->okey == skey) && (tmp->len == l) &&
++		(!xmlStrncmp(tmp->name, name, l)))
+ 		return(tmp->name);
+ #endif
+ 	}
+ 	key = okey % dict->size;
+     }
+ 
+-    ret = xmlDictAddString(dict, name, len);
++    ret = xmlDictAddString(dict, name, l);
+     if (ret == NULL)
+         return(NULL);
+     if (insert == NULL) {
+@@ -858,13 +881,13 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	     return(NULL);
+     }
+     entry->name = ret;
+-    entry->len = len;
++    entry->len = l;
+     entry->next = NULL;
+     entry->valid = 1;
+     entry->okey = okey;
+ 
+ 
+-    if (insert != NULL) 
++    if (insert != NULL)
+ 	insert->next = entry;
+ 
+     dict->nbElems++;
+@@ -893,17 +916,23 @@ const xmlChar *
+ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+     unsigned long key, okey, nbi = 0;
+     xmlDictEntryPtr insert;
++    unsigned int l;
+ 
+     if ((dict == NULL) || (name == NULL))
+ 	return(NULL);
+ 
+     if (len < 0)
+-        len = strlen((const char *) name);
++        l = strlen((const char *) name);
++    else
++        l = len;
++    if (((dict->limit > 0) && (l >= dict->limit)) ||
++        (l > INT_MAX / 2))
++        return(NULL);
+ 
+     /*
+      * Check for duplicate and insertion location.
+      */
+-    okey = xmlDictComputeKey(dict, name, len);
++    okey = xmlDictComputeKey(dict, name, l);
+     key = okey % dict->size;
+     if (dict->dict[key].valid == 0) {
+ 	insert = NULL;
+@@ -911,25 +940,25 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	for (insert = &(dict->dict[key]); insert->next != NULL;
+ 	     insert = insert->next) {
+ #ifdef __GNUC__
+-	    if ((insert->okey == okey) && (insert->len == len)) {
+-		if (!memcmp(insert->name, name, len))
++	    if ((insert->okey == okey) && (insert->len == l)) {
++		if (!memcmp(insert->name, name, l))
+ 		    return(insert->name);
+ 	    }
+ #else
+-	    if ((insert->okey == okey) && (insert->len == len) &&
+-	        (!xmlStrncmp(insert->name, name, len)))
++	    if ((insert->okey == okey) && (insert->len == l) &&
++	        (!xmlStrncmp(insert->name, name, l)))
+ 		return(insert->name);
+ #endif
+ 	    nbi++;
+ 	}
+ #ifdef __GNUC__
+-	if ((insert->okey == okey) && (insert->len == len)) {
+-	    if (!memcmp(insert->name, name, len))
++	if ((insert->okey == okey) && (insert->len == l)) {
++	    if (!memcmp(insert->name, name, l))
+ 		return(insert->name);
+ 	}
+ #else
+-	if ((insert->okey == okey) && (insert->len == len) &&
+-	    (!xmlStrncmp(insert->name, name, len)))
++	if ((insert->okey == okey) && (insert->len == l) &&
++	    (!xmlStrncmp(insert->name, name, l)))
+ 	    return(insert->name);
+ #endif
+     }
+@@ -942,7 +971,7 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	     (dict->subdict->size != MIN_DICT_SIZE)) ||
+             ((dict->size != MIN_DICT_SIZE) &&
+ 	     (dict->subdict->size == MIN_DICT_SIZE)))
+-	    skey = xmlDictComputeKey(dict->subdict, name, len);
++	    skey = xmlDictComputeKey(dict->subdict, name, l);
+ 	else
+ 	    skey = okey;
+ 
+@@ -953,25 +982,25 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+ 	    for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
+ 		 tmp = tmp->next) {
+ #ifdef __GNUC__
+-		if ((tmp->okey == skey) && (tmp->len == len)) {
+-		    if (!memcmp(tmp->name, name, len))
++		if ((tmp->okey == skey) && (tmp->len == l)) {
++		    if (!memcmp(tmp->name, name, l))
+ 			return(tmp->name);
+ 		}
+ #else
+-		if ((tmp->okey == skey) && (tmp->len == len) &&
+-		    (!xmlStrncmp(tmp->name, name, len)))
++		if ((tmp->okey == skey) && (tmp->len == l) &&
++		    (!xmlStrncmp(tmp->name, name, l)))
+ 		    return(tmp->name);
+ #endif
+ 		nbi++;
+ 	    }
+ #ifdef __GNUC__
+-	    if ((tmp->okey == skey) && (tmp->len == len)) {
+-		if (!memcmp(tmp->name, name, len))
++	    if ((tmp->okey == skey) && (tmp->len == l)) {
++		if (!memcmp(tmp->name, name, l))
+ 		    return(tmp->name);
+ 	    }
+ #else
+-	    if ((tmp->okey == skey) && (tmp->len == len) &&
+-		(!xmlStrncmp(tmp->name, name, len)))
++	    if ((tmp->okey == skey) && (tmp->len == l) &&
++		(!xmlStrncmp(tmp->name, name, l)))
+ 		return(tmp->name);
+ #endif
+ 	}
+@@ -997,7 +1026,7 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
+     xmlDictEntryPtr entry;
+     xmlDictEntryPtr insert;
+     const xmlChar *ret;
+-    int len, plen, l;
++    unsigned int len, plen, l;
+ 
+     if ((dict == NULL) || (name == NULL))
+ 	return(NULL);
+@@ -1073,7 +1102,7 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
+     entry->valid = 1;
+     entry->okey = okey;
+ 
+-    if (insert != NULL) 
++    if (insert != NULL)
+ 	insert->next = entry;
+ 
+     dict->nbElems++;
+@@ -1131,6 +1160,50 @@ xmlDictSize(xmlDictPtr dict) {
+     return(dict->nbElems);
+ }
+ 
++/**
++ * xmlDictSetLimit:
++ * @dict: the dictionnary
++ * @limit: the limit in bytes
++ *
++ * Set a size limit for the dictionary
++ * Added in 2.9.0
++ *
++ * Returns the previous limit of the dictionary or 0
++ */
++size_t
++xmlDictSetLimit(xmlDictPtr dict, size_t limit) {
++    size_t ret;
++
++    if (dict == NULL)
++	return(0);
++    ret = dict->limit;
++    dict->limit = limit;
++    return(ret);
++}
++
++/**
++ * xmlDictGetUsage:
++ * @dict: the dictionnary
++ *
++ * Get how much memory is used by a dictionary for strings
++ * Added in 2.9.0
++ *
++ * Returns the amount of strings allocated
++ */
++size_t
++xmlDictGetUsage(xmlDictPtr dict) {
++    xmlDictStringsPtr pool;
++    size_t limit = 0;
++
++    if (dict == NULL)
++	return(0);
++    pool = dict->strings;
++    while (pool != NULL) {
++        limit += pool->size;
++	pool = pool->next;
++    }
++    return(limit);
++}
+ 
+ #define bottom_dict
+ #include "elfgcchack.h"
+diff --git a/include/libxml/dict.h b/include/libxml/dict.h
+index abb8339..4945be3 100644
+--- a/include/libxml/dict.h
++++ b/include/libxml/dict.h
+@@ -11,6 +11,7 @@
+ #ifndef __XML_DICT_H__
+ #define __XML_DICT_H__
+ 
++#include <limits.h>
+ #include <libxml/xmlversion.h>
+ #include <libxml/tree.h>
+ 
+@@ -29,6 +30,11 @@ typedef xmlDict *xmlDictPtr;
+  */
+ XMLPUBFUN xmlDictPtr XMLCALL
+ 			xmlDictCreate	(void);
++XMLPUBFUN size_t XMLCALL
++			xmlDictSetLimit	(xmlDictPtr dict,
++                                         size_t limit);
++XMLPUBFUN size_t XMLCALL
++			xmlDictGetUsage (xmlDictPtr dict);
+ XMLPUBFUN xmlDictPtr XMLCALL
+ 			xmlDictCreateSub(xmlDictPtr sub);
+ XMLPUBFUN int XMLCALL
+-- 
+1.7.11.4
+
diff --git a/libxml2-Do-not-fetch-external-parsed-entities.patch b/libxml2-Do-not-fetch-external-parsed-entities.patch
new file mode 100644
index 0000000..b9eb759
--- /dev/null
+++ b/libxml2-Do-not-fetch-external-parsed-entities.patch
@@ -0,0 +1,71 @@
+From 1928888cf378b7c670f3ef173c19c7bc5a04c624 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 23 Jul 2012 14:15:40 +0800
+Subject: [PATCH] Do not fetch external parsed entities
+To: libvir-list at redhat.com
+
+Unless explicietely asked for when validating or replacing entities
+with their value. Problem pointed out by Tom Lane <tgl at redhat.com>
+
+* parser.c: do not load external parsed entities unless needed
+* test/errors/extparsedent.xml result/errors/extparsedent.xml*:
+  add a regression test to avoid change of the behaviour in the future
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c                       | 11 +++++++++--
+ result/errors/extparsedent.xml |  5 +++++
+ test/errors/extparsedent.xml   |  5 +++++
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+ create mode 100644 result/errors/extparsedent.xml
+ create mode 100644 result/errors/extparsedent.xml.err
+ create mode 100644 result/errors/extparsedent.xml.str
+ create mode 100644 test/errors/extparsedent.xml
+
+diff --git a/parser.c b/parser.c
+index aa703aa..4303527 100644
+--- a/parser.c
++++ b/parser.c
+@@ -6917,8 +6917,15 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
+      * The first reference to the entity trigger a parsing phase
+      * where the ent->children is filled with the result from
+      * the parsing.
+-     */
+-    if (ent->checked == 0) {
++     * Note: external parsed entities will not be loaded, it is not
++     * required for a non-validating parser, unless the parsing option
++     * of validating, or substituting entities were given. Doing so is
++     * far more secure as the parser will only process data coming from
++     * the document entity by default.
++     */
++    if ((ent->checked == 0) &&
++        ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
++         (ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
+ 	unsigned long oldnbent = ctxt->nbentities;
+ 
+ 	/*
+diff --git a/result/errors/extparsedent.xml b/result/errors/extparsedent.xml
+new file mode 100644
+index 0000000..07e4c54
+--- /dev/null
++++ b/result/errors/extparsedent.xml
+@@ -0,0 +1,5 @@
++<?xml version="1.0"?>
++<!DOCTYPE foo [
++<!ENTITY c PUBLIC "bar" "/etc/doesnotexist">
++]>
++<root>&c;</root>
+diff --git a/test/errors/extparsedent.xml b/test/errors/extparsedent.xml
+new file mode 100644
+index 0000000..07e4c54
+--- /dev/null
++++ b/test/errors/extparsedent.xml
+@@ -0,0 +1,5 @@
++<?xml version="1.0"?>
++<!DOCTYPE foo [
++<!ENTITY c PUBLIC "bar" "/etc/doesnotexist">
++]>
++<root>&c;</root>
+-- 
+1.7.11.4
+
diff --git a/libxml2-Enforce-XML_PARSER_EOF-state-handling-through-the-parser.patch b/libxml2-Enforce-XML_PARSER_EOF-state-handling-through-the-parser.patch
new file mode 100644
index 0000000..74c05ba
--- /dev/null
+++ b/libxml2-Enforce-XML_PARSER_EOF-state-handling-through-the-parser.patch
@@ -0,0 +1,481 @@
+From 310b309fbdbc85fc7498235b62d911fe90dce942 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 30 Jul 2012 16:16:04 +0800
+Subject: [PATCH] Enforce XML_PARSER_EOF state handling through the parser
+To: libvir-list at redhat.com
+
+That condition is one raised when the parser should positively stop
+processing further even to report errors. Best is to test is after
+most GROW call especially within loops
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 110 insertions(+), 21 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 2e633d5..78ae09b 100644
+--- a/parser.c
++++ b/parser.c
+@@ -2145,6 +2145,8 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) {
+ 		"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur);
+     }
+     ret = inputPush(ctxt, input);
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(-1);
+     GROW;
+     return(ret);
+ }
+@@ -2181,6 +2183,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
+ 	    if (count++ > 20) {
+ 		count = 0;
+ 		GROW;
++                if (ctxt->instate == XML_PARSER_EOF)
++                    return(0);
+ 	    }
+ 	    if ((RAW >= '0') && (RAW <= '9')) 
+ 	        val = val * 16 + (CUR - '0');
+@@ -2212,6 +2216,8 @@ xmlParseCharRef(xmlParserCtxtPtr ctxt) {
+ 	    if (count++ > 20) {
+ 		count = 0;
+ 		GROW;
++                if (ctxt->instate == XML_PARSER_EOF)
++                    return(0);
+ 	    }
+ 	    if ((RAW >= '0') && (RAW <= '9')) 
+ 	        val = val * 10 + (CUR - '0');
+@@ -2560,6 +2566,8 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
+ 		     * the amount of data in the buffer.
+ 		     */
+ 		    GROW
++                    if (ctxt->instate == XML_PARSER_EOF)
++                        return;
+ 		    if ((ctxt->input->end - ctxt->input->cur)>=4) {
+ 			start[0] = RAW;
+ 			start[1] = NXT(1);
+@@ -3178,6 +3186,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+      * Handler for more complex cases
+      */
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(NULL);
+     c = CUR_CHAR(l);
+     if ((ctxt->options & XML_PARSE_OLD10) == 0) {
+         /*
+@@ -3229,6 +3239,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ 	    if (count++ > 100) {
+ 		count = 0;
+ 		GROW;
++                if (ctxt->instate == XML_PARSER_EOF)
++                    return(NULL);
+ 	    }
+ 	    len += l;
+ 	    NEXTL(l);
+@@ -3253,6 +3265,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ 	    if (count++ > 100) {
+ 		count = 0;
+ 		GROW;
++                if (ctxt->instate == XML_PARSER_EOF)
++                    return(NULL);
+ 	    }
+ 	    len += l;
+ 	    NEXTL(l);
+@@ -3361,6 +3375,8 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+             }
+ 	    count = 0;
+ 	    GROW;
++            if (ctxt->instate == XML_PARSER_EOF)
++                return(NULL);
+ 	}
+ 	len += l;
+ 	NEXTL(l);
+@@ -3451,6 +3467,8 @@ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
+     const xmlChar *ret;
+ 
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(NULL);
+ 
+     in = ctxt->input->cur;
+     while (*in != 0 && *in == *cmp) {
+@@ -3590,6 +3608,8 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ #endif
+ 
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(NULL);
+     c = CUR_CHAR(l);
+ 
+     while (xmlIsNameChar(ctxt, c)) {
+@@ -3618,6 +3638,10 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ 		if (count++ > 100) {
+ 		    count = 0;
+ 		    GROW;
++                    if (ctxt->instate == XML_PARSER_EOF) {
++                        xmlFree(buffer);
++                        return(NULL);
++                    }
+ 		}
+ 		if (len + 10 > max) {
+ 		    xmlChar *tmp;
+@@ -3699,6 +3723,10 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+     ctxt->instate = XML_PARSER_ENTITY_VALUE;
+     input = ctxt->input;
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF) {
++        xmlFree(buf);
++        return(NULL);
++    }
+     NEXT;
+     c = CUR_CHAR(l);
+     /*
+@@ -3710,8 +3738,8 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+      * In practice it means we stop the loop only when back at parsing
+      * the initial entity and the quote is found
+      */
+-    while ((IS_CHAR(c)) && ((c != stop) || /* checked */
+-	   (ctxt->input != input))) {
++    while (((IS_CHAR(c)) && ((c != stop) || /* checked */
++	    (ctxt->input != input))) && (ctxt->instate != XML_PARSER_EOF)) {
+ 	if (len + 5 >= size) {
+ 	    xmlChar *tmp;
+ 
+@@ -3740,6 +3768,10 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+ 	}
+     }
+     buf[len] = 0;
++    if (ctxt->instate == XML_PARSER_EOF) {
++        xmlFree(buf);
++        return(NULL);
++    }
+ 
+     /*
+      * Raise problem w.r.t. '&' and '%' being used in non-entities
+@@ -3787,12 +3819,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+ 	 */
+ 	ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
+ 				      0, 0, 0);
+-	if (orig != NULL) 
++	if (orig != NULL)
+ 	    *orig = buf;
+ 	else
+ 	    xmlFree(buf);
+     }
+-    
++
+     return(ret);
+ }
+ 
+@@ -3843,8 +3875,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+      * OK loop until we reach one of the ending char or a size limit.
+      */
+     c = CUR_CHAR(l);
+-    while ((NXT(0) != limit) && /* checked */
+-           (IS_CHAR(c)) && (c != '<')) {
++    while (((NXT(0) != limit) && /* checked */
++            (IS_CHAR(c)) && (c != '<')) &&
++            (ctxt->instate != XML_PARSER_EOF)) {
+         /*
+          * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
+          * special option is given
+@@ -3989,6 +4022,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 	GROW;
+ 	c = CUR_CHAR(l);
+     }
++    if (ctxt->instate == XML_PARSER_EOF)
++        goto error;
++
+     if ((in_space) && (normalize)) {
+         while (buf[len - 1] == 0x20) len--;
+     }
+@@ -4021,6 +4057,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 
+ mem_error:
+     xmlErrMemory(ctxt, NULL);
++error:
+     if (buf != NULL)
+         xmlFree(buf);
+     if (rep != NULL)
+@@ -4133,6 +4170,10 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ 	if (count > 50) {
+ 	    GROW;
+ 	    count = 0;
++            if (ctxt->instate == XML_PARSER_EOF) {
++	        xmlFree(buf);
++		return(NULL);
++            }
+ 	}
+ 	COPY_BUF(l,buf,len,cur);
+ 	NEXTL(l);
+@@ -4216,6 +4257,10 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ 	if (count > 50) {
+ 	    GROW;
+ 	    count = 0;
++            if (ctxt->instate == XML_PARSER_EOF) {
++		xmlFree(buf);
++		return(NULL);
++            }
+ 	}
+ 	NEXT;
+ 	cur = CUR;
+@@ -4422,6 +4467,8 @@ get_more:
+ 	    }
+ 	    SHRINK;
+ 	    GROW;
++            if (ctxt->instate == XML_PARSER_EOF)
++		return;
+ 	    in = ctxt->input->cur;
+ 	} while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09));
+ 	nbchar = 0;
+@@ -4490,6 +4537,8 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
+ 	if (count > 50) {
+ 	    GROW;
+ 	    count = 0;
++            if (ctxt->instate == XML_PARSER_EOF)
++		return;
+ 	}
+ 	NEXTL(l);
+ 	cur = CUR_CHAR(l);
+@@ -4701,6 +4750,10 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
+ 	if (count > 50) {
+ 	    GROW;
+ 	    count = 0;
++            if (ctxt->instate == XML_PARSER_EOF) {
++		xmlFree(buf);
++		return;
++            }
+ 	}
+ 	NEXTL(l);
+ 	cur = CUR_CHAR(l);
+@@ -4859,6 +4912,10 @@ get_more:
+ 	}
+ 	SHRINK;
+ 	GROW;
++        if (ctxt->instate == XML_PARSER_EOF) {
++            xmlFree(buf);
++            return;
++        }
+ 	in = ctxt->input->cur;
+ 	if (*in == '-') {
+ 	    if (in[1] == '-') {
+@@ -5095,6 +5152,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 		count++;
+ 		if (count > 50) {
+ 		    GROW;
++                    if (ctxt->instate == XML_PARSER_EOF) {
++                        xmlFree(buf);
++                        return;
++                    }
+ 		    count = 0;
+                     if ((len > XML_MAX_TEXT_LENGTH) &&
+                         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+@@ -5851,7 +5912,7 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) {
+ 	}
+ 	SKIP_BLANKS;
+ 	GROW;
+-	while (RAW != '>') {
++	while ((RAW != '>') && (ctxt->instate != XML_PARSER_EOF)) {
+ 	    const xmlChar *check = CUR_PTR;
+ 	    int type;
+ 	    int def;
+@@ -6000,7 +6061,7 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
+ 	    ret = cur = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA);
+ 	    if (ret == NULL) return(NULL);
+ 	}
+-	while (RAW == '|') {
++	while ((RAW == '|') && (ctxt->instate != XML_PARSER_EOF)) {
+ 	    NEXT;
+ 	    if (elem == NULL) {
+ 	        ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_OR);
+@@ -6144,7 +6205,7 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
+     }
+     SKIP_BLANKS;
+     SHRINK;
+-    while (RAW != ')') {
++    while ((RAW != ')') && (ctxt->instate != XML_PARSER_EOF)) {
+         /*
+ 	 * Each loop we parse one separator and one element.
+ 	 */
+@@ -6423,6 +6484,8 @@ xmlParseElementContentDecl(xmlParserCtxtPtr ctxt, const xmlChar *name,
+     }
+     NEXT;
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(-1);
+     SKIP_BLANKS;
+     if (CMP7(CUR_PTR, '#', 'P', 'C', 'D', 'A', 'T', 'A')) {
+         tree = xmlParseElementMixedContentDecl(ctxt, inputid);
+@@ -6590,8 +6653,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
+ 		    "Entering INCLUDE Conditional Section\n");
+ 	}
+ 
+-	while ((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
+-	       (NXT(2) != '>'))) {
++	while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') ||
++	        (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) {
+ 	    const xmlChar *check = CUR_PTR;
+ 	    unsigned int cons = ctxt->input->consumed;
+ 
+@@ -6659,7 +6722,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
+ 	if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+ 	ctxt->instate = XML_PARSER_IGNORE;
+ 
+-	while ((depth >= 0) && (RAW != 0)) {
++	while (((depth >= 0) && (RAW != 0)) &&
++               (ctxt->instate != XML_PARSER_EOF)) {
+ 	  if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
+ 	    depth++;
+ 	    SKIP(3);
+@@ -6930,7 +6994,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
+ 	    break;
+ 	}
+     }
+-    
++
+     if (RAW != 0) {
+ 	xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+     }
+@@ -7383,6 +7447,8 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
+     xmlEntityPtr ent = NULL;
+ 
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(NULL);
+ 
+     if (RAW != '&')
+         return(NULL);
+@@ -7913,6 +7979,10 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+ 	if (count++ > 100) {
+ 	    count = 0;
+ 	    GROW;
++            if (ctxt->instate == XML_PARSER_EOF) {
++                xmlBufferFree(buf);
++                return(-1);
++            }
+ 	}
+ 	NEXTL(l);
+ 	c = CUR_CHAR(l);
+@@ -8146,7 +8216,7 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
+ 	 * PEReferences.
+ 	 * Subsequence (markupdecl | PEReference | S)*
+ 	 */
+-	while (RAW != ']') {
++	while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) {
+ 	    const xmlChar *check = CUR_PTR;
+ 	    unsigned int cons = ctxt->input->consumed;
+ 
+@@ -8332,9 +8402,9 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
+     SKIP_BLANKS;
+     GROW;
+ 
+-    while ((RAW != '>') && 
++    while (((RAW != '>') && 
+ 	   ((RAW != '/') || (NXT(1) != '>')) &&
+-	   (IS_BYTE_CHAR(RAW))) {
++	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
+ 	const xmlChar *q = CUR_PTR;
+ 	unsigned int cons = ctxt->input->consumed;
+ 
+@@ -8758,6 +8828,8 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    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;
+@@ -8778,6 +8850,8 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    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;
+@@ -8804,6 +8878,8 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    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;
+@@ -8833,6 +8909,8 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 	    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;
+@@ -9076,9 +9154,9 @@ reparse:
+     GROW;
+     if (ctxt->input->base != base) goto base_changed;
+ 
+-    while ((RAW != '>') && 
++    while (((RAW != '>') &&
+ 	   ((RAW != '/') || (NXT(1) != '>')) &&
+-	   (IS_BYTE_CHAR(RAW))) {
++	   (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
+ 	const xmlChar *q = CUR_PTR;
+ 	unsigned int cons = ctxt->input->consumed;
+ 	int len = -1, alloc = 0;
+@@ -9249,6 +9327,8 @@ skip_ns:
+ failed:
+ 
+ 	GROW
++        if (ctxt->instate == XML_PARSER_EOF)
++            break;
+ 	if (ctxt->input->base != base) goto base_changed;
+ 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+ 	    break;
+@@ -9486,6 +9566,8 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
+      * We should definitely be at the ending "S? '>'" part
+      */
+     GROW;
++    if (ctxt->instate == XML_PARSER_EOF)
++        return;
+     SKIP_BLANKS;
+     if ((!IS_BYTE_CHAR(RAW)) || (RAW != '>')) {
+ 	xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL);
+@@ -9601,6 +9683,10 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ 	count++;
+ 	if (count > 50) {
+ 	    GROW;
++            if (ctxt->instate == XML_PARSER_EOF) {
++		xmlFree(buf);
++		return;
++            }
+ 	    count = 0;
+ 	}
+ 	NEXTL(l);
+@@ -10364,9 +10450,10 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
+ 
+ void
+ xmlParseMisc(xmlParserCtxtPtr ctxt) {
+-    while (((RAW == '<') && (NXT(1) == '?')) ||
+-           (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
+-           IS_BLANK_CH(CUR)) {
++    while ((ctxt->instate != XML_PARSER_EOF) &&
++           (((RAW == '<') && (NXT(1) == '?')) ||
++            (CMP4(CUR_PTR, '<', '!', '-', '-')) ||
++            IS_BLANK_CH(CUR))) {
+         if ((RAW == '<') && (NXT(1) == '?')) {
+ 	    xmlParsePI(ctxt);
+ 	} else if (IS_BLANK_CH(CUR)) {
+@@ -11836,6 +11923,8 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
+         return(XML_ERR_INTERNAL_ERROR);
+     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+         return(ctxt->errNo);
++    if (ctxt->instate == XML_PARSER_EOF)
++        return(-1);
+     if (ctxt->instate == XML_PARSER_START)
+         xmlDetectSAX2(ctxt);
+     if ((size > 0) && (chunk != NULL) && (!terminate) &&
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-a-failure-to-report-xmlreader-parsing-failures.patch b/libxml2-Fix-a-failure-to-report-xmlreader-parsing-failures.patch
new file mode 100644
index 0000000..5030cc0
--- /dev/null
+++ b/libxml2-Fix-a-failure-to-report-xmlreader-parsing-failures.patch
@@ -0,0 +1,37 @@
+From 4dae20fb28932b14b47d7cb0e8cd278270887a52 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Wed, 18 Jul 2012 17:39:56 +0800
+Subject: [PATCH] Fix a failure to report xmlreader parsing failures
+To: libvir-list at redhat.com
+
+Related to https://bugzilla.gnome.org/show_bug.cgi?id=654567
+the problem is that the provided patch failed to raise an error
+on xmlTextReaderRead() return when an actual parsing error occured
+
+Conflicts:
+	xmlreader.c: context change
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xmlreader.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/xmlreader.c b/xmlreader.c
+index 97c71ab..12b777f 100644
+--- a/xmlreader.c
++++ b/xmlreader.c
+@@ -900,6 +900,11 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
+ 	}
+     }
+     reader->state = oldstate;
++    if (reader->ctxt->wellFormed == 0) {
++	reader->mode = XML_TEXTREADER_MODE_EOF;
++        return(-1);
++    }
++
+     return(0);
+ }
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-a-potential-freeing-error-in-XPath.patch b/libxml2-Fix-a-potential-freeing-error-in-XPath.patch
new file mode 100644
index 0000000..707ad1a
--- /dev/null
+++ b/libxml2-Fix-a-potential-freeing-error-in-XPath.patch
@@ -0,0 +1,38 @@
+From 0817eafbc02dfb113f0ca9d3b99dd9ef72a37ed8 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Wed, 17 Nov 2010 14:12:14 +0100
+Subject: [PATCH] Fix a potential freeing error in XPath
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpath.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/xpath.c b/xpath.c
+index 4d6826d..5474849 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -11763,11 +11763,15 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 
+ 	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
+ 	        xmlXPathObjectPtr tmp;
+-		/* pop the result */
++		/* pop the result if any */
+ 		tmp = valuePop(ctxt);
+-		xmlXPathReleaseObject(xpctxt, tmp);
+-		/* then pop off contextObj, which will be freed later */
+-		valuePop(ctxt);
++                if (tmp != contextObj)
++                    /*
++                     * Free up the result
++                     * then pop off contextObj, which will be freed later
++                     */
++                    xmlXPathReleaseObject(xpctxt, tmp);
++                    valuePop(ctxt);
+ 		goto evaluation_error;
+ 	    }
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-a-segfault-on-XSD-validation-on-pattern-error.patch b/libxml2-Fix-a-segfault-on-XSD-validation-on-pattern-error.patch
new file mode 100644
index 0000000..4f0263a
--- /dev/null
+++ b/libxml2-Fix-a-segfault-on-XSD-validation-on-pattern-error.patch
@@ -0,0 +1,56 @@
+From 525b6f62bc3727a5297e202291b3cc171a6b68b2 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Fri, 17 Aug 2012 20:34:05 +0800
+Subject: [PATCH] Fix a segfault on XSD validation on pattern error
+To: libvir-list at redhat.com
+
+As reported by Sven <sven at e7o.de>:
+The following pattern will cause a segmentation fault in my
+Apache (using PHP5 to validate a XML against a XSD):
+
+<xs:pattern value="(.*)|"/>
+
+Fix a cascade of error handling failures which led to the
+crash in that scenario.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xmlregexp.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/xmlregexp.c b/xmlregexp.c
+index aaff33e..c574ad3 100644
+--- a/xmlregexp.c
++++ b/xmlregexp.c
+@@ -3199,7 +3199,7 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
+         memset(exec->counts, 0, comp->nbCounters * sizeof(int));
+     } else
+ 	exec->counts = NULL;
+-    while ((exec->status == 0) &&
++    while ((exec->status == 0) && (exec->state != NULL) &&
+ 	   ((exec->inputString[exec->index] != 0) ||
+ 	    ((exec->state != NULL) &&
+ 	     (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
+@@ -3453,6 +3453,8 @@ error:
+ 	}
+ 	xmlFree(exec->rollbacks);
+     }
++    if (exec->state == NULL)
++        return(-1);
+     if (exec->counts != NULL)
+ 	xmlFree(exec->counts);
+     if (exec->status == 0)
+@@ -5370,6 +5372,10 @@ xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
+     end = ctxt->state;
+     while ((CUR == '|') && (ctxt->error == 0)) {
+ 	NEXT;
++	if (CUR == 0) {
++	    ERROR("expecting a branch after |")
++	    return;
++	}
+ 	ctxt->state = start;
+ 	ctxt->end = NULL;
+ 	xmlFAParseBranch(ctxt, end);
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-an-allocation-error-when-copying-entities.patch b/libxml2-Fix-an-allocation-error-when-copying-entities.patch
new file mode 100644
index 0000000..886e697
--- /dev/null
+++ b/libxml2-Fix-an-allocation-error-when-copying-entities.patch
@@ -0,0 +1,27 @@
+From bc55cdaa736850127c08b557df01fbee77c82824 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Fri, 16 Dec 2011 18:53:35 +0800
+Subject: [PATCH] Fix an allocation error when copying entities
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/parser.c b/parser.c
+index ef00f42..7743d20 100644
+--- a/parser.c
++++ b/parser.c
+@@ -2709,7 +2709,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 
+ 		buffer[nbchars++] = '&';
+ 		if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
+-		    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
++		    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
+ 		}
+ 		for (;i > 0;i--)
+ 		    buffer[nbchars++] = *cur++;
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-an-error-in-previous-commit.patch b/libxml2-Fix-an-error-in-previous-commit.patch
new file mode 100644
index 0000000..323a2b5
--- /dev/null
+++ b/libxml2-Fix-an-error-in-previous-commit.patch
@@ -0,0 +1,27 @@
+From 9ab7a91a2e1c37bc8d98cd165d62c479b032143e Mon Sep 17 00:00:00 2001
+From: Aron Xu <happyaron.xu at gmail.com>
+Date: Fri, 20 Jul 2012 15:41:34 +0800
+Subject: [PATCH] Fix an error in previous commit
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ entities.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/entities.c b/entities.c
+index 859ec3b..7d06820 100644
+--- a/entities.c
++++ b/entities.c
+@@ -529,7 +529,7 @@ xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
+  */
+ #define growBufferReentrant() {						\
+     xmlChar *tmp;                                                       \
+-    size_t new_size = buffer_size *= 2;                                 \
++    size_t new_size = buffer_size * 2;                                  \
+     if (new_size < buffer_size) goto mem_error;                         \
+     tmp = (xmlChar *) xmlRealloc(buffer, new_size);	                \
+     if (tmp == NULL) goto mem_error;                                    \
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-an-off-by-one-error-in-encoding.patch b/libxml2-Fix-an-off-by-one-error-in-encoding.patch
new file mode 100644
index 0000000..c4dcc6e
--- /dev/null
+++ b/libxml2-Fix-an-off-by-one-error-in-encoding.patch
@@ -0,0 +1,39 @@
+From 463fd3346a04d6d0c6ec4820fc701d9a1c160458 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Fri, 19 Aug 2011 11:05:04 +0800
+Subject: [PATCH] Fix an off by one error in encoding
+To: libvir-list at redhat.com
+
+this off by one error doesn't seems to reproduce on linux
+but the error is real.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ encoding.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/encoding.c b/encoding.c
+index d1140bf..fb0c38a 100644
+--- a/encoding.c
++++ b/encoding.c
+@@ -1928,7 +1928,7 @@ xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+     if (in == NULL) return(-1);
+ 
+     /* calculate space available */
+-    written = out->size - out->use;
++    written = out->size - out->use - 1; /* count '\0' */
+     toconv = in->use;
+     /*
+      * echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
+@@ -2059,7 +2059,7 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
+     toconv = in->use;
+     if (toconv == 0)
+         return (0);
+-    written = out->size - out->use;
++    written = out->size - out->use -1; /* count '\0' */
+     if (toconv * 2 >= written) {
+         xmlBufferGrow(out, out->size + toconv * 2);
+         written = out->size - out->use - 1;
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-an-off-by-one-pointer-access.patch b/libxml2-Fix-an-off-by-one-pointer-access.patch
new file mode 100644
index 0000000..e7e2413
--- /dev/null
+++ b/libxml2-Fix-an-off-by-one-pointer-access.patch
@@ -0,0 +1,46 @@
+From 15f9281daa9fa8389ede04085ff3941883d2c3a6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=BCri=20Aedla?= <asd at ut.ee>
+Date: Mon, 7 May 2012 15:06:56 +0800
+Subject: [PATCH] Fix an off by one pointer access
+To: libvir-list at redhat.com
+
+getting out of the range of memory allocated for xpointer decoding
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpointer.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/xpointer.c b/xpointer.c
+index 37afa3a..0b463dd 100644
+--- a/xpointer.c
++++ b/xpointer.c
+@@ -1007,21 +1007,14 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
+ 		NEXT;
+ 		break;
+ 	    }
+-	    *cur++ = CUR;
+ 	} else if (CUR == '(') {
+ 	    level++;
+-	    *cur++ = CUR;
+ 	} else if (CUR == '^') {
+-	    NEXT;
+-	    if ((CUR == ')') || (CUR == '(') || (CUR == '^')) {
+-		*cur++ = CUR;
+-	    } else {
+-		*cur++ = '^';
+-		*cur++ = CUR;
+-	    }
+-	} else {
+-	    *cur++ = CUR;
++            if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) {
++                NEXT;
++            }
+ 	}
++        *cur++ = CUR;
+ 	NEXT;
+     }
+     *cur = 0;
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-an-unimplemented-part-in-RNG-value-validation.patch b/libxml2-Fix-an-unimplemented-part-in-RNG-value-validation.patch
new file mode 100644
index 0000000..d1fe048
--- /dev/null
+++ b/libxml2-Fix-an-unimplemented-part-in-RNG-value-validation.patch
@@ -0,0 +1,67 @@
+From 5974c1e350fddbced412b9442eaf5cfbb012bfc2 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 10 Nov 2011 18:08:33 +0800
+Subject: [PATCH] Fix an unimplemented part in RNG value validation
+To: libvir-list at redhat.com
+
+Forgot to implement <optional> this was raised again
+in https://bugzilla.redhat.com/show_bug.cgi?id=752393
+as this make libxml2 fail to validate against ODF RNGs
+
+Daniel
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ relaxng.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/relaxng.c b/relaxng.c
+index 6dbc499..c0ac3b7 100644
+--- a/relaxng.c
++++ b/relaxng.c
+@@ -8884,6 +8884,11 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
+         case XML_RELAXNG_ZEROORMORE:{
+                 xmlChar *cur, *temp;
+ 
++                if ((ctxt->state->value == NULL) ||
++                    (*ctxt->state->value == 0)) {
++                    ret = 0;
++                    break;
++                }
+                 oldflags = ctxt->flags;
+                 ctxt->flags |= FLAGS_IGNORABLE;
+                 cur = ctxt->state->value;
+@@ -8905,6 +8910,30 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
+ 		    xmlRelaxNGPopErrors(ctxt, 0);
+                 break;
+             }
++        case XML_RELAXNG_OPTIONAL:{
++                xmlChar *temp;
++
++                if ((ctxt->state->value == NULL) ||
++                    (*ctxt->state->value == 0)) {
++                    ret = 0;
++                    break;
++                }
++                oldflags = ctxt->flags;
++                ctxt->flags |= FLAGS_IGNORABLE;
++                temp = ctxt->state->value;
++                ret = xmlRelaxNGValidateValue(ctxt, define->content);
++                ctxt->flags = oldflags;
++                if (ret != 0) {
++                    ctxt->state->value = temp;
++                    if (ctxt->errNr > 0)
++                        xmlRelaxNGPopErrors(ctxt, 0);
++                    ret = 0;
++                    break;
++                }
++		if (ctxt->errNr > 0)
++		    xmlRelaxNGPopErrors(ctxt, 0);
++                break;
++            }
+         case XML_RELAXNG_EXCEPT:{
+                 xmlRelaxNGDefinePtr list;
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-entities-local-buffers-size-problems.patch b/libxml2-Fix-entities-local-buffers-size-problems.patch
new file mode 100644
index 0000000..0aa048b
--- /dev/null
+++ b/libxml2-Fix-entities-local-buffers-size-problems.patch
@@ -0,0 +1,103 @@
+From da2b4fffc2854d8d66f98beb09354543881c9f40 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Wed, 18 Jul 2012 11:38:17 +0800
+Subject: [PATCH] Fix entities local buffers size problems
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ entities.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/entities.c b/entities.c
+index 6aef49f..859ec3b 100644
+--- a/entities.c
++++ b/entities.c
+@@ -528,13 +528,13 @@ xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
+  * Macro used to grow the current buffer.
+  */
+ #define growBufferReentrant() {						\
+-    buffer_size *= 2;							\
+-    buffer = (xmlChar *)						\
+-    		xmlRealloc(buffer, buffer_size * sizeof(xmlChar));	\
+-    if (buffer == NULL) {						\
+-        xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");\
+-	return(NULL);							\
+-    }									\
++    xmlChar *tmp;                                                       \
++    size_t new_size = buffer_size *= 2;                                 \
++    if (new_size < buffer_size) goto mem_error;                         \
++    tmp = (xmlChar *) xmlRealloc(buffer, new_size);	                \
++    if (tmp == NULL) goto mem_error;                                    \
++    buffer = tmp;							\
++    buffer_size = new_size;						\
+ }
+ 
+ 
+@@ -555,7 +555,7 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
+     const xmlChar *cur = input;
+     xmlChar *buffer = NULL;
+     xmlChar *out = NULL;
+-    int buffer_size = 0;
++    size_t buffer_size = 0;
+     int html = 0;
+ 
+     if (input == NULL) return(NULL);
+@@ -574,8 +574,8 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
+     out = buffer;
+ 
+     while (*cur != '\0') {
+-        if (out - buffer > buffer_size - 100) {
+-	    int indx = out - buffer;
++        size_t indx = out - buffer;
++        if (indx + 100 > buffer_size) {
+ 
+ 	    growBufferReentrant();
+ 	    out = &buffer[indx];
+@@ -692,6 +692,11 @@ xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) {
+     }
+     *out = 0;
+     return(buffer);
++
++mem_error:
++    xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");
++    xmlFree(buffer);
++    return(NULL);
+ }
+ 
+ /**
+@@ -709,7 +714,7 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+     const xmlChar *cur = input;
+     xmlChar *buffer = NULL;
+     xmlChar *out = NULL;
+-    int buffer_size = 0;
++    size_t buffer_size = 0;
+     if (input == NULL) return(NULL);
+ 
+     /*
+@@ -724,8 +729,8 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+     out = buffer;
+ 
+     while (*cur != '\0') {
+-        if (out - buffer > buffer_size - 10) {
+-	    int indx = out - buffer;
++        size_t indx = out - buffer;
++        if (indx + 10 > buffer_size) {
+ 
+ 	    growBufferReentrant();
+ 	    out = &buffer[indx];
+@@ -774,6 +779,11 @@ xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+     }
+     *out = 0;
+     return(buffer);
++
++mem_error:
++    xmlEntitiesErrMemory("xmlEncodeSpecialChars: realloc failed");
++    xmlFree(buffer);
++    return(NULL);
+ }
+ 
+ /**
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-missing-error-status-in-XPath-evaluation.patch b/libxml2-Fix-missing-error-status-in-XPath-evaluation.patch
new file mode 100644
index 0000000..3627be1
--- /dev/null
+++ b/libxml2-Fix-missing-error-status-in-XPath-evaluation.patch
@@ -0,0 +1,69 @@
+From accdfd7edc118f8c6a92747977bb301da6ca6c2e Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 11 Oct 2011 16:34:34 +0800
+Subject: [PATCH] Fix missing error status in XPath evaluation
+To: libvir-list at redhat.com
+
+Started by Chris Evans, I added a few more place where the
+error should have been set in the evaluation context.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpath.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/xpath.c b/xpath.c
+index bf425ee..713b43c 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -2485,6 +2485,7 @@ valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
+                                              sizeof(ctxt->valueTab[0]));
+         if (tmp == NULL) {
+             xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
++            ctxt->error = XPATH_MEMORY_ERROR;
+             return (0);
+         }
+         ctxt->valueMax *= 2;
+@@ -9340,6 +9341,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+ 		if ( (ch & 0xc0) != 0xc0 ) {
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			"xmlXPathTranslateFunction: Invalid UTF8 string\n");
++                    /* not asserting an XPath error is probably better */
+ 		    break;
+ 		}
+ 		/* then skip over remaining bytes for this char */
+@@ -9347,6 +9349,7 @@ xmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+ 		    if ( (*cptr++ & 0xc0) != 0x80 ) {
+ 			xmlGenericError(xmlGenericErrorContext,
+ 			    "xmlXPathTranslateFunction: Invalid UTF8 string\n");
++                        /* not asserting an XPath error is probably better */
+ 			break;
+ 		    }
+ 		if (ch & 0x80) /* must have had error encountered */
+@@ -13411,6 +13414,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+                         xmlGenericError(xmlGenericErrorContext,
+             "xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
+                                     (char *) op->value4, (char *)op->value5);
++                        ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
+                         return (total);
+                     }
+ 		    val = xmlXPathVariableLookupNS(ctxt->context,
+@@ -13465,6 +13469,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+             "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
+                                     (char *)op->value4, (char *)op->value5);
+                             xmlXPathPopFrame(ctxt, frame);
++                            ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
+                             return (total);
+                         }
+                         func = xmlXPathFunctionLookupNS(ctxt->context,
+@@ -14043,6 +14048,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+     }
+     xmlGenericError(xmlGenericErrorContext,
+                     "XPath: unknown precompiled operation %d\n", op->op);
++    ctxt->error = XPATH_INVALID_OPERAND;
+     return (total);
+ }
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-parser-local-buffers-size-problems.patch b/libxml2-Fix-parser-local-buffers-size-problems.patch
new file mode 100644
index 0000000..d6288c0
--- /dev/null
+++ b/libxml2-Fix-parser-local-buffers-size-problems.patch
@@ -0,0 +1,269 @@
+From 03c10b4b4cfcc2d25b78106b65ed24a968113e2b Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 17 Jul 2012 16:19:17 +0800
+Subject: [PATCH] Fix parser local buffers size problems
+To: libvir-list at redhat.com
+
+Conflicts:
+	parser.c: context changes
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 74 +++++++++++++++++++++++++++++++++++++---------------------------
+ 1 file changed, 43 insertions(+), 31 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 7743d20..aa703aa 100644
+--- a/parser.c
++++ b/parser.c
+@@ -40,6 +40,7 @@
+ #endif
+ 
+ #include <stdlib.h>
++#include <limits.h>
+ #include <string.h>
+ #include <stdarg.h>
+ #include <libxml/xmlmemory.h>
+@@ -114,10 +115,10 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+  * parser option.
+  */
+ static int
+-xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long size,
++xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
+                      xmlEntityPtr ent)
+ {
+-    unsigned long consumed = 0;
++    size_t consumed = 0;
+ 
+     if ((ctxt == NULL) || (ctxt->options & XML_PARSE_HUGE))
+         return (0);
+@@ -2580,15 +2581,17 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
+ 
+ /*
+  * Macro used to grow the current buffer.
++ * buffer##_size is expected to be a size_t
++ * mem_error: is expected to handle memory allocation failures
+  */
+ #define growBuffer(buffer, n) {						\
+     xmlChar *tmp;							\
+-    buffer##_size *= 2;							\
+-    buffer##_size += n;							\
+-    tmp = (xmlChar *)							\
+-		xmlRealloc(buffer, buffer##_size * sizeof(xmlChar));	\
++    size_t new_size = buffer##_size * 2 + n;                            \
++    if (new_size < buffer##_size) goto mem_error;                       \
++    tmp = (xmlChar *) xmlRealloc(buffer, new_size);                     \
+     if (tmp == NULL) goto mem_error;					\
+     buffer = tmp;							\
++    buffer##_size = new_size;                                           \
+ }
+ 
+ /**
+@@ -2614,14 +2617,14 @@ xmlChar *
+ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 		      int what, xmlChar end, xmlChar  end2, xmlChar end3) {
+     xmlChar *buffer = NULL;
+-    int buffer_size = 0;
++    size_t buffer_size = 0;
++    size_t nbchars = 0;
+ 
+     xmlChar *current = NULL;
+     xmlChar *rep = NULL;
+     const xmlChar *last;
+     xmlEntityPtr ent;
+     int c,l;
+-    int nbchars = 0;
+ 
+     if ((ctxt == NULL) || (str == NULL) || (len < 0))
+ 	return(NULL);
+@@ -2638,7 +2641,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+      * allocate a translation buffer.
+      */
+     buffer_size = XML_PARSER_BIG_BUFFER_SIZE;
+-    buffer = (xmlChar *) xmlMallocAtomic(buffer_size * sizeof(xmlChar));
++    buffer = (xmlChar *) xmlMallocAtomic(buffer_size);
+     if (buffer == NULL) goto mem_error;
+ 
+     /*
+@@ -2658,7 +2661,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 	    if (val != 0) {
+ 		COPY_BUF(0,buffer,nbchars,val);
+ 	    }
+-	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
++	    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+ 	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+ 	    }
+ 	} else if ((c == '&') && (what & XML_SUBSTITUTE_REF)) {
+@@ -2676,7 +2679,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 		(ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+ 		if (ent->content != NULL) {
+ 		    COPY_BUF(0,buffer,nbchars,ent->content[0]);
+-		    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
++		    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+ 			growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+ 		    }
+ 		} else {
+@@ -2693,8 +2696,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 		    current = rep;
+ 		    while (*current != 0) { /* non input consuming loop */
+ 			buffer[nbchars++] = *current++;
+-			if (nbchars >
+-		            buffer_size - XML_PARSER_BUFFER_SIZE) {
++			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+ 			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
+ 				goto int_error;
+ 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+@@ -2708,7 +2710,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 		const xmlChar *cur = ent->name;
+ 
+ 		buffer[nbchars++] = '&';
+-		if (nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE) {
++		if (nbchars + i + XML_PARSER_BUFFER_SIZE > buffer_size) {
+ 		    growBuffer(buffer, i + XML_PARSER_BUFFER_SIZE);
+ 		}
+ 		for (;i > 0;i--)
+@@ -2736,8 +2738,7 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 		    current = rep;
+ 		    while (*current != 0) { /* non input consuming loop */
+ 			buffer[nbchars++] = *current++;
+-			if (nbchars >
+-		            buffer_size - XML_PARSER_BUFFER_SIZE) {
++			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
+ 			    if (xmlParserEntityCheck(ctxt, nbchars, ent))
+ 			        goto int_error;
+ 			    growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+@@ -2750,8 +2751,8 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
+ 	} else {
+ 	    COPY_BUF(l,buffer,nbchars,c);
+ 	    str += l;
+-	    if (nbchars > buffer_size - XML_PARSER_BUFFER_SIZE) {
+-	      growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
++	    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
++	        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
+ 	    }
+ 	}
+ 	if (str < last)
+@@ -3755,8 +3756,8 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+     xmlChar limit = 0;
+     xmlChar *buf = NULL;
+     xmlChar *rep = NULL;
+-    int len = 0;
+-    int buf_size = 0;
++    size_t len = 0;
++    size_t buf_size = 0;
+     int c, l, in_space = 0;
+     xmlChar *current = NULL;
+     xmlEntityPtr ent;
+@@ -3778,7 +3779,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+      * allocate a translation buffer.
+      */
+     buf_size = XML_PARSER_BUFFER_SIZE;
+-    buf = (xmlChar *) xmlMallocAtomic(buf_size * sizeof(xmlChar));
++    buf = (xmlChar *) xmlMallocAtomic(buf_size);
+     if (buf == NULL) goto mem_error;
+ 
+     /*
+@@ -3795,7 +3796,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 
+ 		if (val == '&') {
+ 		    if (ctxt->replaceEntities) {
+-			if (len > buf_size - 10) {
++			if (len + 10 > buf_size) {
+ 			    growBuffer(buf, 10);
+ 			}
+ 			buf[len++] = '&';
+@@ -3804,7 +3805,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 			 * The reparsing will be done in xmlStringGetNodeList()
+ 			 * called by the attribute() function in SAX.c
+ 			 */
+-			if (len > buf_size - 10) {
++			if (len + 10 > buf_size) {
+ 			    growBuffer(buf, 10);
+ 			}
+ 			buf[len++] = '&';
+@@ -3814,7 +3815,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 			buf[len++] = ';';
+ 		    }
+ 		} else if (val != 0) {
+-		    if (len > buf_size - 10) {
++		    if (len + 10 > buf_size) {
+ 			growBuffer(buf, 10);
+ 		    }
+ 		    len += xmlCopyChar(0, &buf[len], val);
+@@ -3826,7 +3827,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 		    ctxt->nbentities += ent->owner;
+ 		if ((ent != NULL) &&
+ 		    (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
+-		    if (len > buf_size - 10) {
++		    if (len + 10 > buf_size) {
+ 			growBuffer(buf, 10);
+ 		    }
+ 		    if ((ctxt->replaceEntities == 0) &&
+@@ -3854,7 +3855,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+                                     current++;
+                                 } else
+                                     buf[len++] = *current++;
+-				if (len > buf_size - 10) {
++				if (len + 10 > buf_size) {
+ 				    growBuffer(buf, 10);
+ 				}
+ 			    }
+@@ -3862,7 +3863,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 			    rep = NULL;
+ 			}
+ 		    } else {
+-			if (len > buf_size - 10) {
++			if (len + 10 > buf_size) {
+ 			    growBuffer(buf, 10);
+ 			}
+ 			if (ent->content != NULL)
+@@ -3890,7 +3891,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 		     * Just output the reference
+ 		     */
+ 		    buf[len++] = '&';
+-		    while (len > buf_size - i - 10) {
++		    while (len + i + 10 > buf_size) {
+ 			growBuffer(buf, i + 10);
+ 		    }
+ 		    for (;i > 0;i--)
+@@ -3903,7 +3904,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 	        if ((len != 0) || (!normalize)) {
+ 		    if ((!normalize) || (!in_space)) {
+ 			COPY_BUF(l,buf,len,0x20);
+-			while (len > buf_size - 10) {
++			while (len + 10 > buf_size) {
+ 			    growBuffer(buf, 10);
+ 			}
+ 		    }
+@@ -3912,7 +3913,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ 	    } else {
+ 	        in_space = 0;
+ 		COPY_BUF(l,buf,len,c);
+-		if (len > buf_size - 10) {
++		if (len + 10 > buf_size) {
+ 		    growBuffer(buf, 10);
+ 		}
+ 	    }
+@@ -3937,7 +3938,18 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+         }
+     } else
+ 	NEXT;
+-    if (attlen != NULL) *attlen = len;
++
++    /*
++     * There we potentially risk an overflow, don't allow attribute value of
++     * lenght more than INT_MAX it is a very reasonnable assumption !
++     */
++    if (len >= INT_MAX) {
++        xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                       "AttValue lenght too long\n");
++        goto mem_error;
++    }
++
++    if (attlen != NULL) *attlen = (int) len;
+     return(buf);
+ 
+ mem_error:
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fix-some-potential-problems-on-reallocation-failures.patch b/libxml2-Fix-some-potential-problems-on-reallocation-failures.patch
new file mode 100644
index 0000000..8d894e7
--- /dev/null
+++ b/libxml2-Fix-some-potential-problems-on-reallocation-failures.patch
@@ -0,0 +1,108 @@
+From e4f7cd441de5804a989bff3ab4993f2f62751a89 Mon Sep 17 00:00:00 2001
+From: Chris Evans <scarybeasts at gmail.com>
+Date: Wed, 23 Mar 2011 08:13:06 +0800
+Subject: [PATCH] Fix some potential problems on reallocation failures
+To: libvir-list at redhat.com
+
+The count was incremented before the allocation
+and not fixed in case of failure
+* xpath.c: corrects a few instances where the available count of some
+           structure is updated before we know the allocation actually
+           succeeds
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpath.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/xpath.c b/xpath.c
+index eef69f7..756220b 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -3522,13 +3522,13 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+     } else if (cur->nodeNr == cur->nodeMax) {
+         xmlNodePtr *temp;
+ 
+-        cur->nodeMax *= 2;
+-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
++	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+ 	    return;
+ 	}
++        cur->nodeMax *= 2;
+ 	cur->nodeTab = temp;
+     }
+     cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
+@@ -3627,14 +3627,14 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+     } else if (cur->nodeNr == cur->nodeMax) {
+         xmlNodePtr *temp;
+ 
+-        cur->nodeMax *= 2;
+-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
++	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+ 	    return;
+ 	}
+ 	cur->nodeTab = temp;
++        cur->nodeMax *= 2;
+     }
+     if (val->type == XML_NAMESPACE_DECL) {
+ 	xmlNsPtr ns = (xmlNsPtr) val;
+@@ -3738,14 +3738,14 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+ 	} else if (val1->nodeNr == val1->nodeMax) {
+ 	    xmlNodePtr *temp;
+ 
+-	    val1->nodeMax *= 2;
+-	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
++	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
+ 					     sizeof(xmlNodePtr));
+ 	    if (temp == NULL) {
+ 	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+ 		return(NULL);
+ 	    }
+ 	    val1->nodeTab = temp;
++	    val1->nodeMax *= 2;
+ 	}
+ 	if (n2->type == XML_NAMESPACE_DECL) {
+ 	    xmlNsPtr ns = (xmlNsPtr) n2;
+@@ -3907,14 +3907,14 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+ 	    } else if (set1->nodeNr >= set1->nodeMax) {
+ 		xmlNodePtr *temp;
+ 
+-		set1->nodeMax *= 2;
+ 		temp = (xmlNodePtr *) xmlRealloc(
+-		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
++		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
+ 		if (temp == NULL) {
+ 		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+ 		    return(NULL);
+ 		}
+ 		set1->nodeTab = temp;
++		set1->nodeMax *= 2;
+ 	    }
+ 	    if (n2->type == XML_NAMESPACE_DECL) {
+ 		xmlNsPtr ns = (xmlNsPtr) n2;
+@@ -3991,14 +3991,14 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+ 	    } else if (set1->nodeNr >= set1->nodeMax) {
+ 		xmlNodePtr *temp;
+ 
+-		set1->nodeMax *= 2;
+ 		temp = (xmlNodePtr *) xmlRealloc(
+-		    set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
++		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
+ 		if (temp == NULL) {
+ 		    xmlXPathErrMemory(NULL, "merging nodeset\n");
+ 		    return(NULL);
+ 		}
+ 		set1->nodeTab = temp;
++		set1->nodeMax *= 2;
+ 	    }
+ 	    set1->nodeTab[set1->nodeNr++] = n2;
+ 	}
+-- 
+1.7.11.4
+
diff --git a/libxml2-Fixup-limits-parser.patch b/libxml2-Fixup-limits-parser.patch
new file mode 100644
index 0000000..be1c2bb
--- /dev/null
+++ b/libxml2-Fixup-limits-parser.patch
@@ -0,0 +1,26 @@
+From c1356d70aa478f6a3d4dbab86b9e8b849a13323c Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 30 Jul 2012 15:41:10 +0800
+Subject: [PATCH] Fixup limits parser
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/parser.c b/parser.c
+index b54fbc4..2e633d5 100644
+--- a/parser.c
++++ b/parser.c
+@@ -1999,6 +1999,7 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
+          ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
+         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+         xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
++        ctxt->instate = XML_PARSER_EOF;
+     }
+     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
+-- 
+1.7.11.4
+
diff --git a/libxml2-Hardening-of-XPath-evaluation.patch b/libxml2-Hardening-of-XPath-evaluation.patch
new file mode 100644
index 0000000..3f82664
--- /dev/null
+++ b/libxml2-Hardening-of-XPath-evaluation.patch
@@ -0,0 +1,233 @@
+From e9bbfe6e96d6c36f013612b1d90cf14a489d451a Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 18 Aug 2011 17:10:13 +0800
+Subject: [PATCH] Hardening of XPath evaluation
+To: libvir-list at redhat.com
+
+Add a mechanism of frame for XPath evaluation when entering a function
+or a scoped evaluation, also fix a potential problem in predicate
+evaluation.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ include/libxml/xpath.h |  5 +++-
+ xpath.c                | 69 +++++++++++++++++++++++++++++++++++++++++++++-----
+ xpointer.c             |  1 +
+ 3 files changed, 68 insertions(+), 7 deletions(-)
+
+diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
+index 1a9e30e..ddd9dd8 100644
+--- a/include/libxml/xpath.h
++++ b/include/libxml/xpath.h
+@@ -68,7 +68,8 @@ typedef enum {
+     XPATH_UNDEF_PREFIX_ERROR,
+     XPATH_ENCODING_ERROR,
+     XPATH_INVALID_CHAR_ERROR,
+-    XPATH_INVALID_CTXT
++    XPATH_INVALID_CTXT,
++    XPATH_STACK_ERROR
+ } xmlXPathError;
+ 
+ /*
+@@ -380,6 +381,8 @@ struct _xmlXPathParserContext {
+     xmlXPathCompExprPtr comp;		/* the precompiled expression */
+     int xptr;				/* it this an XPointer expression */
+     xmlNodePtr         ancestor;	/* used for walking preceding axis */
++
++    int              valueFrame;        /* used to limit Pop on the stack */
+ };
+ 
+ /************************************************************************
+diff --git a/xpath.c b/xpath.c
+index 756220b..bf425ee 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -252,6 +252,7 @@ static const char *xmlXPathErrorMessages[] = {
+     "Encoding error\n",
+     "Char out of XML range\n",
+     "Invalid or incomplete context\n",
++    "Stack usage errror\n",
+     "?? Unknown error ??\n"	/* Must be last in the list! */
+ };
+ #define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) /	\
+@@ -2398,6 +2399,42 @@ xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
+  ************************************************************************/
+ 
+ /**
++ * xmlXPathSetFrame:
++ * @ctxt: an XPath parser context
++ *
++ * Set the callee evaluation frame
++ *
++ * Returns the previous frame value to be restored once done
++ */
++static int
++xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
++    int ret;
++
++    if (ctxt == NULL)
++        return(0);
++    ret = ctxt->valueFrame;
++    ctxt->valueFrame = ctxt->valueNr;
++    return(ret);
++}
++
++/**
++ * xmlXPathPopFrame:
++ * @ctxt: an XPath parser context
++ * @frame: the previous frame value
++ *
++ * Remove the callee evaluation frame
++ */
++static void
++xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
++    if (ctxt == NULL)
++        return;
++    if (ctxt->valueNr < ctxt->valueFrame) {
++        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
++    }
++    ctxt->valueFrame = frame;
++}
++
++/**
+  * valuePop:
+  * @ctxt: an XPath evaluation context
+  *
+@@ -2412,6 +2449,12 @@ valuePop(xmlXPathParserContextPtr ctxt)
+ 
+     if ((ctxt == NULL) || (ctxt->valueNr <= 0))
+         return (NULL);
++
++    if (ctxt->valueNr <= ctxt->valueFrame) {
++        xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
++        return (NULL);
++    }
++
+     ctxt->valueNr--;
+     if (ctxt->valueNr > 0)
+         ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
+@@ -6154,6 +6197,7 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
+     ret->valueNr = 0;
+     ret->valueMax = 10;
+     ret->value = NULL;
++    ret->valueFrame = 0;
+ 
+     ret->context = ctxt;
+     ret->comp = comp;
+@@ -11712,6 +11756,7 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 	xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
+ 	xmlNodePtr oldContextNode, contextNode = NULL;
+ 	xmlXPathContextPtr xpctxt = ctxt->context;
++        int frame;
+ 
+ #ifdef LIBXML_XPTR_ENABLED
+ 	    /*
+@@ -11731,6 +11776,8 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 	*/
+ 	exprOp = &ctxt->comp->steps[op->ch2];
+ 	for (i = 0; i < set->nodeNr; i++) {
++            xmlXPathObjectPtr tmp;
++
+ 	    if (set->nodeTab[i] == NULL)
+ 		continue;
+ 
+@@ -11758,23 +11805,25 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 		xmlXPathNodeSetAddUnique(contextObj->nodesetval,
+ 		    contextNode);
+ 
++            frame = xmlXPathSetFrame(ctxt);
+ 	    valuePush(ctxt, contextObj);
+ 	    res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
++            tmp = valuePop(ctxt);
++            xmlXPathPopFrame(ctxt, frame);
+ 
+ 	    if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
+-	        xmlXPathObjectPtr tmp;
+-		/* pop the result if any */
+-		tmp = valuePop(ctxt);
+-                if (tmp != contextObj) {
++                while (tmp != contextObj) {
+                     /*
+                      * Free up the result
+                      * then pop off contextObj, which will be freed later
+                      */
+                     xmlXPathReleaseObject(xpctxt, tmp);
+-                    valuePop(ctxt);
++                    tmp = valuePop(ctxt);
+                 }
+ 		goto evaluation_error;
+ 	    }
++            /* push the result back onto the stack */
++            valuePush(ctxt, tmp);
+ 
+ 	    if (res)
+ 		pos++;
+@@ -13378,7 +13427,9 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+                 xmlXPathFunction func;
+                 const xmlChar *oldFunc, *oldFuncURI;
+ 		int i;
++                int frame;
+ 
++                frame = xmlXPathSetFrame(ctxt);
+                 if (op->ch1 != -1)
+                     total +=
+                         xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
+@@ -13386,15 +13437,18 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "xmlXPathCompOpEval: parameter error\n");
+ 		    ctxt->error = XPATH_INVALID_OPERAND;
++                    xmlXPathPopFrame(ctxt, frame);
+ 		    return (total);
+ 		}
+-		for (i = 0; i < op->value; i++)
++		for (i = 0; i < op->value; i++) {
+ 		    if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
+ 			xmlGenericError(xmlGenericErrorContext,
+ 				"xmlXPathCompOpEval: parameter error\n");
+ 			ctxt->error = XPATH_INVALID_OPERAND;
++                        xmlXPathPopFrame(ctxt, frame);
+ 			return (total);
+ 		    }
++                }
+                 if (op->cache != NULL)
+                     XML_CAST_FPTR(func) = op->cache;
+                 else {
+@@ -13410,6 +13464,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+                             xmlGenericError(xmlGenericErrorContext,
+             "xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
+                                     (char *)op->value4, (char *)op->value5);
++                            xmlXPathPopFrame(ctxt, frame);
+                             return (total);
+                         }
+                         func = xmlXPathFunctionLookupNS(ctxt->context,
+@@ -13431,6 +13486,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
+                 func(ctxt, op->value);
+                 ctxt->context->function = oldFunc;
+                 ctxt->context->functionURI = oldFuncURI;
++                xmlXPathPopFrame(ctxt, frame);
+                 return (total);
+             }
+         case XPATH_OP_ARG:
+@@ -14334,6 +14390,7 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
+ 	ctxt->valueNr = 0;
+ 	ctxt->valueMax = 10;
+ 	ctxt->value = NULL;
++        ctxt->valueFrame = 0;
+     }
+ #ifdef XPATH_STREAMING
+     if (ctxt->comp->stream) {
+diff --git a/xpointer.c b/xpointer.c
+index 7a42d02..37afa3a 100644
+--- a/xpointer.c
++++ b/xpointer.c
+@@ -1269,6 +1269,7 @@ xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
+ 	ctxt->valueNr = 0;
+ 	ctxt->valueMax = 10;
+ 	ctxt->value = NULL;
++	ctxt->valueFrame = 0;
+     }
+     SKIP_BLANKS;
+     if (CUR == '/') {
+-- 
+1.7.11.4
+
diff --git a/libxml2-Implement-some-default-limits-in-the-XPath-module.patch b/libxml2-Implement-some-default-limits-in-the-XPath-module.patch
new file mode 100644
index 0000000..1cf58eb
--- /dev/null
+++ b/libxml2-Implement-some-default-limits-in-the-XPath-module.patch
@@ -0,0 +1,328 @@
+From 7f999c167a0a41a20c9cae84a0f06d89c00d8e0b Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 30 Jul 2012 10:12:18 +0800
+Subject: [PATCH] Implement some default limits in the XPath module
+To: libvir-list at redhat.com
+
+This adds some internal limitationson XPath expression complexity,
+and limits at runtime like depth of the stack and maximum size
+for nodeset.
+* xpath.c: implement the above as well as the maximum Name lenght
+
+Conflicts:
+	xpath.c: some context change
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpath.c | 163 +++++++++++++++++++++++++++++++++-------------------------------
+ 1 file changed, 83 insertions(+), 80 deletions(-)
+
+diff --git a/xpath.c b/xpath.c
+index 713b43c..a983f41 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -90,6 +90,34 @@
+ /* #define XP_DEBUG_OBJ_USAGE */
+ 
+ /*
++ * XPATH_MAX_STEPS:
++ * when compiling an XPath expression we arbitrary limit the maximum
++ * number of step operation in the compiled expression. 1000000 is
++ * an insanely large value which should never be reached under normal
++ * circumstances
++ */
++#define XPATH_MAX_STEPS 1000000
++
++/*
++ * XPATH_MAX_STACK_DEPTH:
++ * when evaluating an XPath expression we arbitrary limit the maximum
++ * number of object allowed to be pushed on the stack. 1000000 is
++ * an insanely large value which should never be reached under normal
++ * circumstances
++ */
++#define XPATH_MAX_STACK_DEPTH 1000000
++
++/*
++ * XPATH_MAX_NODESET_LENGTH:
++ * when evaluating an XPath expression nodesets are created and we
++ * arbitrary limit the maximum length of those node set. 10000000 is
++ * an insanely large value which should never be reached under normal
++ * circumstances, one would first need to construct an in memory tree
++ * with more than 10 millions nodes.
++ */
++#define XPATH_MAX_NODESET_LENGTH 10000000
++
++/*
+  * TODO:
+  * There are a few spots where some tests are done which depend upon ascii
+  * data.  These should be enhanced for full UTF8 support (see particularly
+@@ -420,8 +448,7 @@ xmlPointerListAddSize(xmlPointerListPtr list,
+     if (list->items == NULL) {
+ 	if (initialSize <= 0)
+ 	    initialSize = 1;
+-	list->items = (void **) xmlMalloc(
+-	    initialSize * sizeof(void *));
++	list->items = (void **) xmlMalloc(initialSize * sizeof(void *));
+ 	if (list->items == NULL) {
+ 	    xmlXPathErrMemory(NULL,
+ 		"xmlPointerListCreate: allocating item\n");
+@@ -430,12 +457,17 @@ xmlPointerListAddSize(xmlPointerListPtr list,
+ 	list->number = 0;
+ 	list->size = initialSize;
+     } else if (list->size <= list->number) {
++        if (list->size > 50000000) {
++	    xmlXPathErrMemory(NULL,
++		"xmlPointerListAddSize: re-allocating item\n");
++            return(-1);
++        }
+ 	list->size *= 2;
+ 	list->items = (void **) xmlRealloc(list->items,
+ 	    list->size * sizeof(void *));
+ 	if (list->items == NULL) {
+ 	    xmlXPathErrMemory(NULL,
+-		"xmlPointerListCreate: re-allocating item\n");
++		"xmlPointerListAddSize: re-allocating item\n");
+ 	    list->size = 0;
+ 	    return(-1);
+ 	}
+@@ -723,6 +755,10 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
+     if (comp->nbStep >= comp->maxStep) {
+ 	xmlXPathStepOp *real;
+ 
++        if (comp->maxStep >= XPATH_MAX_STEPS) {
++	    xmlXPathErrMemory(NULL, "adding step\n");
++	    return(-1);
++        }
+ 	comp->maxStep *= 2;
+ 	real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
+ 		                      comp->maxStep * sizeof(xmlXPathStepOp));
+@@ -2480,11 +2516,16 @@ valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr value)
+     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);
++        }
+         tmp = (xmlXPathObjectPtr *) xmlRealloc(ctxt->valueTab,
+                                              2 * ctxt->valueMax *
+                                              sizeof(ctxt->valueTab[0]));
+         if (tmp == NULL) {
+-            xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
++            xmlXPathErrMemory(NULL, "pushing value\n");
+             ctxt->error = XPATH_MEMORY_ERROR;
+             return (0);
+         }
+@@ -3566,6 +3607,10 @@ xmlXPathNodeSetAddNs(xmlNodeSetPtr cur, xmlNodePtr node, xmlNsPtr ns) {
+     } else if (cur->nodeNr == cur->nodeMax) {
+         xmlNodePtr *temp;
+ 
++        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
++            return;
++        }
+ 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+@@ -3591,11 +3636,6 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+ 
+     if ((cur == NULL) || (val == NULL)) return;
+ 
+-#if 0
+-    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
+-	return;	/* an XSLT fake node */
+-#endif
+-
+     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+     /*
+      * prevent duplcates
+@@ -3619,13 +3659,17 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
+     } else if (cur->nodeNr == cur->nodeMax) {
+         xmlNodePtr *temp;
+ 
+-        cur->nodeMax *= 2;
+-	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+-				      sizeof(xmlNodePtr));
++        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
++            return;
++        }
++	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
++				         sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+ 	    xmlXPathErrMemory(NULL, "growing nodeset\n");
+ 	    return;
+ 	}
++        cur->nodeMax *= 2;
+ 	cur->nodeTab = temp;
+     }
+     if (val->type == XML_NAMESPACE_DECL) {
+@@ -3649,11 +3693,6 @@ void
+ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+     if ((cur == NULL) || (val == NULL)) return;
+ 
+-#if 0
+-    if ((val->type == XML_ELEMENT_NODE) && (val->name[0] == ' '))
+-	return;	/* an XSLT fake node */
+-#endif
+-
+     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+     /*
+      * grow the nodeTab if needed
+@@ -3671,6 +3710,10 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
+     } else if (cur->nodeNr == cur->nodeMax) {
+         xmlNodePtr *temp;
+ 
++        if (cur->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++            xmlXPathErrMemory(NULL, "growing nodeset hit limit\n");
++            return;
++        }
+ 	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
+ 				      sizeof(xmlNodePtr));
+ 	if (temp == NULL) {
+@@ -3782,6 +3825,10 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+ 	} else if (val1->nodeNr == val1->nodeMax) {
+ 	    xmlNodePtr *temp;
+ 
++            if (val1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++                xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
++                return(NULL);
++            }
+ 	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
+ 					     sizeof(xmlNodePtr));
+ 	    if (temp == NULL) {
+@@ -3803,68 +3850,6 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+     return(val1);
+ }
+ 
+-#if 0 /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
+-/**
+- * xmlXPathNodeSetMergeUnique:
+- * @val1:  the first NodeSet or NULL
+- * @val2:  the second NodeSet
+- *
+- * Merges two nodesets, all nodes from @val2 are added to @val1
+- * if @val1 is NULL, a new set is created and copied from @val2
+- *
+- * Returns @val1 once extended or NULL in case of error.
+- */
+-static xmlNodeSetPtr
+-xmlXPathNodeSetMergeUnique(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
+-    int i;
+-
+-    if (val2 == NULL) return(val1);
+-    if (val1 == NULL) {
+-	val1 = xmlXPathNodeSetCreate(NULL);
+-    }
+-    if (val1 == NULL)
+-        return (NULL);
+-
+-    /* @@ with_ns to check whether namespace nodes should be looked at @@ */
+-
+-    for (i = 0;i < val2->nodeNr;i++) {
+-	/*
+-	 * grow the nodeTab if needed
+-	 */
+-	if (val1->nodeMax == 0) {
+-	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
+-						    sizeof(xmlNodePtr));
+-	    if (val1->nodeTab == NULL) {
+-	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+-		return(NULL);
+-	    }
+-	    memset(val1->nodeTab, 0 ,
+-		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
+-	    val1->nodeMax = XML_NODESET_DEFAULT;
+-	} else if (val1->nodeNr == val1->nodeMax) {
+-	    xmlNodePtr *temp;
+-
+-	    val1->nodeMax *= 2;
+-	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+-					     sizeof(xmlNodePtr));
+-	    if (temp == NULL) {
+-	        xmlXPathErrMemory(NULL, "merging nodeset\n");
+-		return(NULL);
+-	    }
+-	    val1->nodeTab = temp;
+-	}
+-	if (val2->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+-	    xmlNsPtr ns = (xmlNsPtr) val2->nodeTab[i];
+-
+-	    val1->nodeTab[val1->nodeNr++] =
+-		xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns);
+-	} else
+-	    val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
+-    }
+-
+-    return(val1);
+-}
+-#endif /* xmlXPathNodeSetMergeUnique() is currently not used anymore */
+ 
+ /**
+  * xmlXPathNodeSetMergeAndClear:
+@@ -3951,6 +3936,10 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+ 	    } else if (set1->nodeNr >= set1->nodeMax) {
+ 		xmlNodePtr *temp;
+ 
++                if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++                    xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
++                    return(NULL);
++                }
+ 		temp = (xmlNodePtr *) xmlRealloc(
+ 		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
+ 		if (temp == NULL) {
+@@ -4035,6 +4024,10 @@ xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr set1, xmlNodeSetPtr set2,
+ 	    } else if (set1->nodeNr >= set1->nodeMax) {
+ 		xmlNodePtr *temp;
+ 
++                if (set1->nodeMax >= XPATH_MAX_NODESET_LENGTH) {
++                    xmlXPathErrMemory(NULL, "merging nodeset hit limit\n");
++                    return(NULL);
++                }
+ 		temp = (xmlNodePtr *) xmlRealloc(
+ 		    set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
+ 		if (temp == NULL) {
+@@ -9866,7 +9859,7 @@ xmlChar *
+ xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
+     const xmlChar *in;
+     xmlChar *ret;
+-    int count = 0;
++    size_t count = 0;
+ 
+     if ((ctxt == NULL) || (ctxt->cur == NULL)) return(NULL);
+     /*
+@@ -9885,6 +9878,10 @@ xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
+ 	    in++;
+ 	if ((*in > 0) && (*in < 0x80)) {
+ 	    count = in - ctxt->cur;
++            if (count > XML_MAX_NAME_LENGTH) {
++                ctxt->cur = in;
++                XP_ERRORNULL(XPATH_EXPR_ERROR);
++            }
+ 	    ret = xmlStrndup(ctxt->cur, count);
+ 	    ctxt->cur = in;
+ 	    return(ret);
+@@ -9928,6 +9925,9 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
+ 	    xmlChar *buffer;
+ 	    int max = len * 2;
+ 
++            if (len > XML_MAX_NAME_LENGTH) {
++                XP_ERRORNULL(XPATH_EXPR_ERROR);
++            }
+ 	    buffer = (xmlChar *) xmlMallocAtomic(max * sizeof(xmlChar));
+ 	    if (buffer == NULL) {
+ 		XP_ERRORNULL(XPATH_MEMORY_ERROR);
+@@ -9939,6 +9939,9 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
+ 		   (IS_COMBINING(c)) ||
+ 		   (IS_EXTENDER(c))) {
+ 		if (len + 10 > max) {
++                    if (max > XML_MAX_NAME_LENGTH) {
++                        XP_ERRORNULL(XPATH_EXPR_ERROR);
++                    }
+ 		    max *= 2;
+ 		    buffer = (xmlChar *) xmlRealloc(buffer,
+ 			                            max * sizeof(xmlChar));
+-- 
+1.7.11.4
+
diff --git a/libxml2-Impose-a-reasonable-limit-on-PI-size.patch b/libxml2-Impose-a-reasonable-limit-on-PI-size.patch
new file mode 100644
index 0000000..35ce9d9
--- /dev/null
+++ b/libxml2-Impose-a-reasonable-limit-on-PI-size.patch
@@ -0,0 +1,82 @@
+From 145a79c9427d526758ef45caa6daa9ddb229af7d Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 19 Jul 2012 20:34:26 +0800
+Subject: [PATCH]  Impose a reasonable limit on PI size
+To: libvir-list at redhat.com
+
+Unless the XML_PARSE_HUGE option is given to the parser,
+the value is XML_MAX_TEXT_LENGTH, i.e. the same than for a
+text node within content.
+Also cleanup some unsigned int used for memory size.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 7e5cef7..a78b0b1 100644
+--- a/parser.c
++++ b/parser.c
+@@ -4953,8 +4953,8 @@ error:
+ void
+ xmlParsePI(xmlParserCtxtPtr ctxt) {
+     xmlChar *buf = NULL;
+-    int len = 0;
+-    int size = XML_PARSER_BUFFER_SIZE;
++    size_t len = 0;
++    size_t size = XML_PARSER_BUFFER_SIZE;
+     int cur, l;
+     const xmlChar *target;
+     xmlParserInputState state;
+@@ -5011,9 +5011,8 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 		   ((cur != '?') || (NXT(1) != '>'))) {
+ 		if (len + 5 >= size) {
+ 		    xmlChar *tmp;
+-
+-		    size *= 2;
+-		    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
++                    size_t new_size = size * 2;
++		    tmp = (xmlChar *) xmlRealloc(buf, new_size);
+ 		    if (tmp == NULL) {
+ 			xmlErrMemory(ctxt, NULL);
+ 			xmlFree(buf);
+@@ -5021,11 +5020,20 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 			return;
+ 		    }
+ 		    buf = tmp;
++                    size = new_size;
+ 		}
+ 		count++;
+ 		if (count > 50) {
+ 		    GROW;
+ 		    count = 0;
++                    if ((len > XML_MAX_TEXT_LENGTH) &&
++                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                        xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
++                                          "PI %s too big found", target);
++                        xmlFree(buf);
++                        ctxt->instate = state;
++                        return;
++                    }
+ 		}
+ 		COPY_BUF(l,buf,len,cur);
+ 		NEXTL(l);
+@@ -5036,6 +5044,14 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 		    cur = CUR_CHAR(l);
+ 		}
+ 	    }
++            if ((len > XML_MAX_TEXT_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
++                                  "PI %s too big found", target);
++                xmlFree(buf);
++                ctxt->instate = state;
++                return;
++            }
+ 	    buf[len] = 0;
+ 	    if (cur != '?') {
+ 		xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
+-- 
+1.7.11.4
+
diff --git a/libxml2-Impose-a-reasonable-limit-on-attribute-size.patch b/libxml2-Impose-a-reasonable-limit-on-attribute-size.patch
new file mode 100644
index 0000000..9dbd823
--- /dev/null
+++ b/libxml2-Impose-a-reasonable-limit-on-attribute-size.patch
@@ -0,0 +1,110 @@
+From f0aec06ab836ab85cf925f0f8459c95a58e2d67b Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 19 Jul 2012 11:25:16 +0800
+Subject: [PATCH] Impose a reasonable limit on attribute size
+To: libvir-list at redhat.com
+
+Unless the XML_PARSE_HUGE option is given to the parser,
+the value is XML_MAX_TEXT_LENGTH, i.e. the same than for a
+text node within content.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 48 insertions(+), 2 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 4303527..fb5cb72 100644
+--- a/parser.c
++++ b/parser.c
+@@ -3788,6 +3788,16 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+     c = CUR_CHAR(l);
+     while ((NXT(0) != limit) && /* checked */
+            (IS_CHAR(c)) && (c != '<')) {
++        /*
++         * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
++         * special option is given
++         */
++        if ((len > XML_MAX_TEXT_LENGTH) &&
++            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                           "AttValue lenght too long\n");
++            goto mem_error;
++        }
+ 	if (c == 0) break;
+ 	if (c == '&') {
+ 	    in_space = 0;
+@@ -8649,6 +8659,12 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 		    in = in + delta;
+ 		}
+ 		end = ctxt->input->end;
++                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                                   "AttValue lenght too long\n");
++                    return(NULL);
++                }
+ 	    }
+ 	}
+ 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
+@@ -8663,6 +8679,12 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 		    in = in + delta;
+ 		}
+ 		end = ctxt->input->end;
++                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                                   "AttValue lenght too long\n");
++                    return(NULL);
++                }
+ 	    }
+ 	}
+ 	last = in;
+@@ -8684,8 +8706,20 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 		    last = last + delta;
+ 		}
+ 		end = ctxt->input->end;
+-	    }
+-	}
++                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                                   "AttValue lenght too long\n");
++                    return(NULL);
++                }
++	    }
++	}
++        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                           "AttValue lenght too long\n");
++            return(NULL);
++        }
+ 	if (*in != limit) goto need_complex;
+     } else {
+ 	while ((in < end) && (*in != limit) && (*in >= 0x20) &&
+@@ -8700,9 +8734,21 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ 		    in = in + delta;
+ 		}
+ 		end = ctxt->input->end;
++                if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++                    ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                    xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                                   "AttValue lenght too long\n");
++                    return(NULL);
++                }
+ 	    }
+ 	}
+ 	last = in;
++        if (((in - start) > XML_MAX_TEXT_LENGTH) &&
++            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++            xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++                           "AttValue lenght too long\n");
++            return(NULL);
++        }
+ 	if (*in != limit) goto need_complex;
+     }
+     in++;
+-- 
+1.7.11.4
+
diff --git a/libxml2-Impose-a-reasonable-limit-on-comment-size.patch b/libxml2-Impose-a-reasonable-limit-on-comment-size.patch
new file mode 100644
index 0000000..d52d95f
--- /dev/null
+++ b/libxml2-Impose-a-reasonable-limit-on-comment-size.patch
@@ -0,0 +1,97 @@
+From e3127872a59348cd637c8236aa2c2bad7f5ae439 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 19 Jul 2012 11:58:47 +0800
+Subject: [PATCH] Impose a reasonable limit on comment size
+To: libvir-list at redhat.com
+
+Unless the XML_PARSE_HUGE option is given to the parser,
+the value is XML_MAX_TEXT_LENGTH, i.e. the same than for a
+text node within content.
+Also cleanup some unsigned int used for memory size.
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 33 ++++++++++++++++++++++++++-------
+ 1 file changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index fb5cb72..7e5cef7 100644
+--- a/parser.c
++++ b/parser.c
+@@ -4549,11 +4549,12 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) {
+  * [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+  */
+ static void
+-xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
++xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
++                       size_t len, size_t size) {
+     int q, ql;
+     int r, rl;
+     int cur, l;
+-    int count = 0;
++    size_t count = 0;
+     int inputid;
+ 
+     inputid = ctxt->input->id;
+@@ -4599,16 +4600,26 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, int len, int size) {
+ 	if ((r == '-') && (q == '-')) {
+ 	    xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
+ 	}
++        if ((len > XML_MAX_TEXT_LENGTH) &&
++            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
++                         "Comment too big found", NULL);
++            xmlFree (buf);
++            return;
++        }
+ 	if (len + 5 >= size) {
+ 	    xmlChar *new_buf;
+-	    size *= 2;
+-	    new_buf = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
++            size_t new_size;
++
++	    new_size = size * 2;
++	    new_buf = (xmlChar *) xmlRealloc(buf, new_size);
+ 	    if (new_buf == NULL) {
+ 		xmlFree (buf);
+ 		xmlErrMemory(ctxt, NULL);
+ 		return;
+ 	    }
+ 	    buf = new_buf;
++            size = new_size;
+ 	}
+ 	COPY_BUF(ql,buf,len,q);
+ 	q = r;
+@@ -4669,11 +4680,12 @@ not_terminated:
+ void
+ xmlParseComment(xmlParserCtxtPtr ctxt) {
+     xmlChar *buf = NULL;
+-    int size = XML_PARSER_BUFFER_SIZE;
+-    int len = 0;
++    size_t size = XML_PARSER_BUFFER_SIZE;
++    size_t len = 0;
+     xmlParserInputState state;
+     const xmlChar *in;
+-    int nbchar = 0, ccol;
++    size_t nbchar = 0;
++    int ccol;
+     int inputid;
+ 
+     /*
+@@ -4753,6 +4765,13 @@ get_more:
+ 		buf[len] = 0;
+ 	    }
+ 	}
++        if ((len > XML_MAX_TEXT_LENGTH) &&
++            ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++            xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
++                         "Comment too big found", NULL);
++            xmlFree (buf);
++            return;
++        }
+ 	ctxt->input->cur = in;
+ 	if (*in == 0xA) {
+ 	    in++;
+-- 
+1.7.11.4
+
diff --git a/libxml2-Introduce-some-default-parser-limits.patch b/libxml2-Introduce-some-default-parser-limits.patch
new file mode 100644
index 0000000..b6b9566
--- /dev/null
+++ b/libxml2-Introduce-some-default-parser-limits.patch
@@ -0,0 +1,310 @@
+From b7e7e2b1d1975f400d6c81eb6c4ad6c683562ca3 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Mon, 30 Jul 2012 10:08:45 +0800
+Subject: [PATCH] Introduce some default parser limits
+To: libvir-list at redhat.com
+
+Those can be overrided by the XML_PARSE_HUGE option, they
+are just default limits for Name lenght, dictionary size limits
+and maximum amount of parser lookup.
+* include/libxml/parserInternals.h: define the limits
+* include/libxml/xmlerror.h: add a new error
+* parser.c parserInternals.c: implements the new limits
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ include/libxml/parserInternals.h | 35 ++++++++++++++++-
+ include/libxml/xmlerror.h        |  1 +
+ parser.c                         | 84 ++++++++++++++++++++++++++++++++++++++--
+ parserInternals.c                |  2 +
+ 4 files changed, 118 insertions(+), 4 deletions(-)
+
+diff --git a/include/libxml/parserInternals.h b/include/libxml/parserInternals.h
+index a5e75b5..d6dcb26 100644
+--- a/include/libxml/parserInternals.h
++++ b/include/libxml/parserInternals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Summary: internals routines exported by the parser.
++ * Summary: internals routines and limits exported by the parser.
+  * Description: this module exports a number of internal parsing routines
+  *              they are not really all intended for applications but
+  *              can prove useful doing low level processing.
+@@ -36,10 +36,43 @@ XMLPUBVAR unsigned int xmlParserMaxDepth;
+  * Maximum size allowed for a single text node when building a tree.
+  * This is not a limitation of the parser but a safety boundary feature,
+  * use XML_PARSE_HUGE option to override it.
++ * Introduced in 2.9.0
+  */
+ #define XML_MAX_TEXT_LENGTH 10000000
+ 
+ /**
++ * XML_MAX_NAME_LENGTH:
++ *
++ * Maximum size allowed for a markup identitier
++ * 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
++ * may result in more runtime memory usage in face of "unfriendly' content
++ * Introduced in 2.9.0
++ */
++#define XML_MAX_NAME_LENGTH 50000
++
++/**
++ * XML_MAX_DICTIONARY_LIMIT:
++ *
++ * Maximum size allowed by the parser for a dictionary by default
++ * This is not a limitation of the parser but a safety boundary feature,
++ * use XML_PARSE_HUGE option to override it.
++ * Introduced in 2.9.0
++ */
++#define XML_MAX_DICTIONARY_LIMIT 10000000
++
++/**
++ * XML_MAX_LOOKUP_LIMIT:
++ *
++ * Maximum size allowed by the parser for ahead lookup
++ * This is an upper boundary enforced by the parser to avoid bad
++ * behaviour on "unfriendly' content
++ * Introduced in 2.9.0
++ */
++#define XML_MAX_LOOKUP_LIMIT 10000000
++
++/**
+  * XML_MAX_NAMELEN:
+  *
+  * Identifiers can be longer, but this will be more costly
+diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
+index e924211..b5e8c77 100644
+--- a/include/libxml/xmlerror.h
++++ b/include/libxml/xmlerror.h
+@@ -205,6 +205,7 @@ typedef enum {
+     XML_WAR_ENTITY_REDEFINED, /* 107 */
+     XML_ERR_UNKNOWN_VERSION, /* 108 */
+     XML_ERR_VERSION_MISMATCH, /* 109 */
++    XML_ERR_NAME_TOO_LONG, /* 110 */
+     XML_NS_ERR_XML_NAMESPACE = 200,
+     XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
+     XML_NS_ERR_QNAME, /* 202 */
+diff --git a/parser.c b/parser.c
+index a78b0b1..b54fbc4 100644
+--- a/parser.c
++++ b/parser.c
+@@ -457,6 +457,9 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
+         case XML_ERR_VERSION_MISSING:
+             errmsg = "Malformed declaration expecting version\n";
+             break;
++        case XML_ERR_NAME_TOO_LONG:
++            errmsg = "Name too long use XML_PARSE_HUGE option\n";
++            break;
+ #if 0
+         case:
+             errmsg = "\n";
+@@ -1992,6 +1995,11 @@ static void xmlSHRINK (xmlParserCtxtPtr ctxt) {
+ 	xmlGROW (ctxt);
+ 
+ static void xmlGROW (xmlParserCtxtPtr ctxt) {
++    if ((((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
++         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
++    }
+     xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+     if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
+         (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
+@@ -3250,6 +3258,11 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ 	    c = CUR_CHAR(l);
+ 	}
+     }
++    if ((len > XML_MAX_NAME_LENGTH) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
++        return(NULL);
++    }
+     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
+         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
+     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+@@ -3299,6 +3312,11 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
+ 	    in++;
+ 	if ((*in > 0) && (*in < 0x80)) {
+ 	    count = in - ctxt->input->cur;
++            if ((count > XML_MAX_NAME_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
++                return(NULL);
++            }
+ 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+ 	    ctxt->input->cur = in;
+ 	    ctxt->nbChars += count;
+@@ -3335,6 +3353,11 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+ 	   (xmlIsNameChar(ctxt, c) && (c != ':'))) {
+ 	if (count++ > 100) {
++            if ((len > XML_MAX_NAME_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++                return(NULL);
++            }
+ 	    count = 0;
+ 	    GROW;
+ 	}
+@@ -3342,6 +3365,11 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+ 	NEXTL(l);
+ 	c = CUR_CHAR(l);
+     }
++    if ((len > XML_MAX_NAME_LENGTH) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++        return(NULL);
++    }
+     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+ }
+ 
+@@ -3386,6 +3414,11 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
+ 	    in++;
+ 	if ((*in > 0) && (*in < 0x80)) {
+ 	    count = in - ctxt->input->cur;
++            if ((count > XML_MAX_NAME_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++                return(NULL);
++            }
+ 	    ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+ 	    ctxt->input->cur = in;
+ 	    ctxt->nbChars += count;
+@@ -3496,6 +3529,13 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+ 	    while (xmlIsNameChar(ctxt, c)) {
+ 		if (len + 10 > max) {
+ 		    xmlChar *tmp;
++
++                    if ((len > XML_MAX_NAME_LENGTH) &&
++                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++			xmlFree(buffer);
++                        return(NULL);
++                    }
+ 		    max *= 2;
+ 		    tmp = (xmlChar *) xmlRealloc(buffer,
+ 			                            max * sizeof(xmlChar));
+@@ -3515,6 +3555,11 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+ 	    return(buffer);
+ 	}
+     }
++    if ((len > XML_MAX_NAME_LENGTH) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++        return(NULL);
++    }
+     *str = cur;
+     return(xmlStrndup(buf, len));
+ }
+@@ -3576,6 +3621,12 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ 		if (len + 10 > max) {
+ 		    xmlChar *tmp;
+ 
++                    if ((max > XML_MAX_NAME_LENGTH) &&
++                        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
++                        xmlFree(buffer);
++                        return(NULL);
++                    }
+ 		    max *= 2;
+ 		    tmp = (xmlChar *) xmlRealloc(buffer,
+ 			                            max * sizeof(xmlChar));
+@@ -3596,6 +3647,11 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+     }
+     if (len == 0)
+         return(NULL);
++    if ((len > XML_MAX_NAME_LENGTH) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
++        return(NULL);
++    }
+     return(xmlStrndup(buf, len));
+ }
+ 
+@@ -4055,6 +4111,13 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ 	if (len + 5 >= size) {
+ 	    xmlChar *tmp;
+ 
++            if ((size > XML_MAX_NAME_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
++                xmlFree(buf);
++		ctxt->instate = (xmlParserInputState) state;
++                return(NULL);
++            }
+ 	    size *= 2;
+ 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ 	    if (tmp == NULL) {
+@@ -4132,6 +4195,12 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ 	if (len + 1 >= size) {
+ 	    xmlChar *tmp;
+ 
++            if ((size > XML_MAX_NAME_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
++                xmlFree(buf);
++                return(NULL);
++            }
+ 	    size *= 2;
+ 	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ 	    if (tmp == NULL) {
+@@ -8322,7 +8391,7 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
+ 		xmlFree(attvalue);
+ 	}
+ 
+-failed:     
++failed:
+ 
+ 	GROW
+ 	if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
+@@ -9507,14 +9576,21 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ 	if (len + 5 >= size) {
+ 	    xmlChar *tmp;
+ 
+-	    size *= 2;
+-	    tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
++            if ((size > XML_MAX_TEXT_LENGTH) &&
++                ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++                xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
++                             "CData section too big found", NULL);
++                xmlFree (buf);
++                return;
++            }
++	    tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
+ 	    if (tmp == NULL) {
+ 	        xmlFree(buf);
+ 		xmlErrMemory(ctxt, NULL);
+ 		return;
+ 	    }
+ 	    buf = tmp;
++	    size *= 2;
+ 	}
+ 	COPY_BUF(rl,buf,len,r);
+ 	r = s;
+@@ -14663,6 +14739,8 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
+     if (options & XML_PARSE_HUGE) {
+ 	ctxt->options |= XML_PARSE_HUGE;
+         options -= XML_PARSE_HUGE;
++        if (ctxt->dict != NULL)
++            xmlDictSetLimit(ctxt->dict, 0);
+     }
+     if (options & XML_PARSE_OLDSAX) {
+ 	ctxt->options |= XML_PARSE_OLDSAX;
+diff --git a/parserInternals.c b/parserInternals.c
+index 2404ddf..5e5d06a 100644
+--- a/parserInternals.c
++++ b/parserInternals.c
+@@ -1618,6 +1618,8 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
+         xmlErrMemory(NULL, "cannot initialize parser context\n");
+ 	return(-1);
+     }
++    xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
++
+     if (ctxt->sax == NULL)
+ 	ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
+     if (ctxt->sax == NULL) {
+-- 
+1.7.11.4
+
diff --git a/libxml2-Make-sure-the-parser-returns-when-getting-a-Stop-order.patch b/libxml2-Make-sure-the-parser-returns-when-getting-a-Stop-order.patch
new file mode 100644
index 0000000..9236096
--- /dev/null
+++ b/libxml2-Make-sure-the-parser-returns-when-getting-a-Stop-order.patch
@@ -0,0 +1,69 @@
+From 4fc9f5dafff28ead4a75ba1bcb10feaea8370a3b Mon Sep 17 00:00:00 2001
+From: Chris Evans <scarybeasts at gmail.com>
+Date: Wed, 14 Dec 2011 16:18:25 +0800
+Subject: [PATCH] Make sure the parser returns when getting a Stop order
+To: libvir-list at redhat.com
+
+patch backported from chromiun bug fixes, assuming author is Chris
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index d1c7888..ef00f42 100644
+--- a/parser.c
++++ b/parser.c
+@@ -4949,7 +4949,8 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 		    (ctxt->sax->processingInstruction != NULL))
+ 		    ctxt->sax->processingInstruction(ctxt->userData,
+ 		                                     target, NULL);
+-		ctxt->instate = state;
++		if (ctxt->instate != XML_PARSER_EOF)
++		    ctxt->instate = state;
+ 		return;
+ 	    }
+ 	    buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
+@@ -5029,7 +5030,8 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ 	} else {
+ 	    xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
+ 	}
+-	ctxt->instate = state;
++	if (ctxt->instate != XML_PARSER_EOF)
++	    ctxt->instate = state;
+     }
+ }
+ 
+@@ -9588,6 +9590,8 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
+     else
+ 	name = xmlParseStartTag(ctxt);
+ #endif /* LIBXML_SAX1_ENABLED */
++    if (ctxt->instate == XML_PARSER_EOF)
++	return;
+     if (name == NULL) {
+ 	spacePop(ctxt);
+         return;
+@@ -10967,6 +10971,8 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		else
+ 		    name = xmlParseStartTag(ctxt);
+ #endif /* LIBXML_SAX1_ENABLED */
++		if (ctxt->instate == XML_PARSER_EOF)
++		    goto done;
+ 		if (name == NULL) {
+ 		    spacePop(ctxt);
+ 		    ctxt->instate = XML_PARSER_EOF;
+@@ -11153,7 +11159,9 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		  else
+ 		    xmlParseEndTag1(ctxt, 0);
+ #endif /* LIBXML_SAX1_ENABLED */
+-		if (ctxt->nameNr == 0) {
++		if (ctxt->instate == XML_PARSER_EOF) {
++		    /* Nothing */
++		} else if (ctxt->nameNr == 0) {
+ 		    ctxt->instate = XML_PARSER_EPILOG;
+ 		} else {
+ 		    ctxt->instate = XML_PARSER_CONTENT;
+-- 
+1.7.11.4
+
diff --git a/libxml2-More-avoid-quadratic-behaviour.patch b/libxml2-More-avoid-quadratic-behaviour.patch
new file mode 100644
index 0000000..b2c3f75
--- /dev/null
+++ b/libxml2-More-avoid-quadratic-behaviour.patch
@@ -0,0 +1,102 @@
+From a2e984b7fb4c62ed67a9a142c46498be507849cf Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 19 Jul 2012 20:36:25 +0800
+Subject: [PATCH] More avoid quadratic behaviour
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 0bb4591..8cb316c 100644
+--- a/parser.c
++++ b/parser.c
+@@ -11319,9 +11319,13 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    break;
+ 	        } else if ((cur == '<') && (next == '?')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
++		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
++                        ctxt->progressive = XML_PARSER_PI;
+ 			goto done;
++                    }
+ 		    xmlParsePI(ctxt);
++		    ctxt->instate = XML_PARSER_CONTENT;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (next != '!')) {
+ 		    ctxt->instate = XML_PARSER_START_TAG;
+ 		    break;
+@@ -11520,13 +11524,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		next = ctxt->input->cur[1];
+ 	        if ((cur == '<') && (next == '?')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
++		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
++                        ctxt->progressive = XML_PARSER_PI;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing PI\n");
+ #endif
+ 		    xmlParsePI(ctxt);
++		    ctxt->instate = XML_PARSER_MISC;
++                    ctxt->progressive = 1;
+ 		    ctxt->checkIndex = 0;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == '-') &&
+@@ -11610,13 +11618,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		next = ctxt->input->cur[1];
+ 	        if ((cur == '<') && (next == '?')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
++		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
++                        ctxt->progressive = XML_PARSER_PI;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing PI\n");
+ #endif
+ 		    xmlParsePI(ctxt);
++		    ctxt->instate = XML_PARSER_PROLOG;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ 		    if ((!terminate) &&
+@@ -11657,14 +11669,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		next = ctxt->input->cur[1];
+ 	        if ((cur == '<') && (next == '?')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
++		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0)) {
++                        ctxt->progressive = XML_PARSER_PI;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing PI\n");
+ #endif
+ 		    xmlParsePI(ctxt);
+ 		    ctxt->instate = XML_PARSER_EPILOG;
++                    ctxt->progressive = 1;
+ 		} else if ((cur == '<') && (next == '!') &&
+ 		    (ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
+ 		    if ((!terminate) &&
+@@ -11939,6 +11954,11 @@ xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
+             return(1);
+         return(0);
+     }
++    if (ctxt->progressive == XML_PARSER_PI) {
++        if (memchr(chunk, '>', size) != NULL)
++            return(1);
++        return(0);
++    }
+     return(1);
+ }
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-More-fixups-on-the-push-parser-behaviour.patch b/libxml2-More-fixups-on-the-push-parser-behaviour.patch
new file mode 100644
index 0000000..ee42f19
--- /dev/null
+++ b/libxml2-More-fixups-on-the-push-parser-behaviour.patch
@@ -0,0 +1,62 @@
+From 17c73f2e605322aad492b670123a6939f7706f88 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Fri, 3 Aug 2012 12:03:31 +0800
+Subject: [PATCH] More fixups on the push parser behaviour
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index f4ddc5b..6a9e54d 100644
+--- a/parser.c
++++ b/parser.c
+@@ -11561,13 +11561,17 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
+ 		    (ctxt->input->cur[7] == 'P') &&
+ 		    (ctxt->input->cur[8] == 'E')) {
+ 		    if ((!terminate) &&
+-		        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0))
++		        (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0)) {
++                        ctxt->progressive = XML_PARSER_DTD;
+ 			goto done;
++                    }
+ #ifdef DEBUG_PUSH
+ 		    xmlGenericError(xmlGenericErrorContext,
+ 			    "PP: Parsing internal subset\n");
+ #endif
+ 		    ctxt->inSubset = 1;
++                    ctxt->progressive = 1;
++		    ctxt->checkIndex = 0;
+ 		    xmlParseDocTypeDecl(ctxt);
+ 		    if (RAW == '[') {
+ 			ctxt->instate = XML_PARSER_DTD;
+@@ -11959,12 +11963,23 @@ xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
+             return(1);
+         return(0);
+     }
++    if (ctxt->instate == XML_PARSER_CDATA_SECTION) {
++        if (memchr(chunk, '>', size) != NULL)
++            return(1);
++        return(0);
++    }
+     if (ctxt->progressive == XML_PARSER_PI) {
+         if (memchr(chunk, '>', size) != NULL)
+             return(1);
+         return(0);
+     }
+-    if (ctxt->instate == XML_PARSER_DTD) {
++    if (ctxt->instate == XML_PARSER_END_TAG) {
++        if (memchr(chunk, '>', size) != NULL)
++            return(1);
++        return(0);
++    }
++    if ((ctxt->progressive == XML_PARSER_DTD) ||
++        (ctxt->instate == XML_PARSER_DTD)) {
+         if (memchr(chunk, ']', size) != NULL)
+             return(1);
+         return(0);
+-- 
+1.7.11.4
+
diff --git a/libxml2-Multilib-fix.patch b/libxml2-Multilib-fix.patch
new file mode 100644
index 0000000..d9d929c
--- /dev/null
+++ b/libxml2-Multilib-fix.patch
@@ -0,0 +1,34 @@
+From 02f33764685acb0f9b79d80a1fbe2e0830dac5ed Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 21 Aug 2012 11:59:03 +0800
+Subject: [PATCH] Multilib fix
+To: libvir-list at redhat.com
+
+Only for RHEL/Fedora
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xml2-config.in | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/xml2-config.in b/xml2-config.in
+index 2989325..f65b54d 100644
+--- a/xml2-config.in
++++ b/xml2-config.in
+@@ -3,7 +3,12 @@
+ prefix=@prefix@
+ exec_prefix=@exec_prefix@
+ includedir=@includedir@
+-libdir=@libdir@
++if [ "`ldd /bin/sh | grep lib64`" = "" ]
++then
++    libdir=${exec_prefix}/lib
++else
++    libdir=${exec_prefix}/lib64
++fi
+ 
+ usage()
+ {
+-- 
+1.7.11.4
+
diff --git a/libxml2-Reactivate-the-shared-library-versionning-script.patch b/libxml2-Reactivate-the-shared-library-versionning-script.patch
new file mode 100644
index 0000000..ab993d1
--- /dev/null
+++ b/libxml2-Reactivate-the-shared-library-versionning-script.patch
@@ -0,0 +1,27 @@
+From 5dcf504e12ce0404d0fc6a981b16af9c8c2ad6e8 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 4 Nov 2010 21:53:14 +0100
+Subject: [PATCH] Reactivate the shared library versionning script
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ configure.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.in b/configure.in
+index 59d0629..a1d2c89 100644
+--- a/configure.in
++++ b/configure.in
+@@ -84,7 +84,7 @@ else
+   esac
+ fi
+ AC_SUBST(VERSION_SCRIPT_FLAGS)
+-AM_CONDITIONAL([USE_VERSION_SCRIPT], [test -z "$VERSION_SCRIPT_FLAGS"])
++AM_CONDITIONAL([USE_VERSION_SCRIPT], [test -n "$VERSION_SCRIPT_FLAGS"])
+ 
+ dnl
+ dnl We process the AC_ARG_WITH first so that later we can modify
+-- 
+1.7.11.4
+
diff --git a/libxml2-Small-fix-for-previous-commit.patch b/libxml2-Small-fix-for-previous-commit.patch
new file mode 100644
index 0000000..66ed59b
--- /dev/null
+++ b/libxml2-Small-fix-for-previous-commit.patch
@@ -0,0 +1,34 @@
+From f7ec29239b66123c29d84f810070c23855061d3f Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Thu, 18 Nov 2010 11:07:24 +0100
+Subject: [PATCH] Small fix for previous commit
+To: libvir-list at redhat.com
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ xpath.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/xpath.c b/xpath.c
+index 5474849..eef69f7 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -11765,13 +11765,14 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt,
+ 	        xmlXPathObjectPtr tmp;
+ 		/* pop the result if any */
+ 		tmp = valuePop(ctxt);
+-                if (tmp != contextObj)
++                if (tmp != contextObj) {
+                     /*
+                      * Free up the result
+                      * then pop off contextObj, which will be freed later
+                      */
+                     xmlXPathReleaseObject(xpctxt, tmp);
+                     valuePop(ctxt);
++                }
+ 		goto evaluation_error;
+ 	    }
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-Strengthen-behaviour-of-the-push-parser-in-problematic-situations.patch b/libxml2-Strengthen-behaviour-of-the-push-parser-in-problematic-situations.patch
new file mode 100644
index 0000000..cdbe414
--- /dev/null
+++ b/libxml2-Strengthen-behaviour-of-the-push-parser-in-problematic-situations.patch
@@ -0,0 +1,71 @@
+From 3bb06661c6e9bf29df03dfb85b121cb195481887 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 31 Jul 2012 10:53:47 +0800
+Subject: [PATCH] Strengthen behaviour of the push parser in problematic
+ situations
+To: libvir-list at redhat.com
+
+Implement the maximum lookahead stategy, and fix some handling
+of DTD to speed up processing.
+
+Conflicts:
+	parser.c: a bit of surgery was needed to get that patch to
+	apply and work in a 2.7.6 context
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ parser.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/parser.c b/parser.c
+index 8cb316c..f4ddc5b 100644
+--- a/parser.c
++++ b/parser.c
+@@ -11812,6 +11812,10 @@ not_end_of_int_subset:
+ 		/*
+ 		 * We didn't found the end of the Internal subset
+ 		 */
++                if (quote == 0)
++                    ctxt->checkIndex = base;
++                else
++                    ctxt->checkIndex = 0;
+ #ifdef DEBUG_PUSH
+ 		if (next == 0)
+ 		    xmlGenericError(xmlGenericErrorContext,
+@@ -11820,6 +11824,7 @@ not_end_of_int_subset:
+ 	        goto done;
+ 
+ found_end_int_subset:
++                ctxt->checkIndex = 0;
+ 		xmlParseInternalSubset(ctxt);
+ 		ctxt->inSubset = 2;
+ 		if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
+@@ -11959,6 +11964,11 @@ xmlParseCheckTransition(xmlParserCtxtPtr ctxt, const char *chunk, int size) {
+             return(1);
+         return(0);
+     }
++    if (ctxt->instate == XML_PARSER_DTD) {
++        if (memchr(chunk, ']', size) != NULL)
++            return(1);
++        return(0);
++    }
+     return(1);
+ }
+ 
+@@ -12088,6 +12098,13 @@ xmldecl_done:
+                                      avail - old_avail)))
+             xmlParseTryOrFinish(ctxt, terminate);
+     }
++    if ((ctxt->input != NULL) &&
++         (((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
++         ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
++        ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
++        ctxt->instate = XML_PARSER_EOF;
++    }
+     if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+         return(ctxt->errNo);
+ 
+-- 
+1.7.11.4
+
diff --git a/libxml2-force-randomization-of-dict-and-hash.patch b/libxml2-force-randomization-of-dict-and-hash.patch
new file mode 100644
index 0000000..d614f6d
--- /dev/null
+++ b/libxml2-force-randomization-of-dict-and-hash.patch
@@ -0,0 +1,45 @@
+From 297c2c5ec7ac8766b626e41b9e15537e01cace22 Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard at redhat.com>
+Date: Tue, 21 Aug 2012 12:11:33 +0800
+Subject: [PATCH] force randomization of dict and hash
+To: libvir-list at redhat.com
+
+Force randomization even if configure wasn't regenerated
+
+Signed-off-by: Daniel Veillard <veillard at redhat.com>
+---
+ dict.c | 3 +++
+ hash.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/dict.c b/dict.c
+index d73d230..bd64afb 100644
+--- a/dict.c
++++ b/dict.c
+@@ -26,6 +26,9 @@
+ #include <time.h>
+ #endif
+ 
++/* Force randomization even if configure wasn't regenerated */
++#define DICT_RANDOMIZATION
++
+ /*
+  * Following http://www.ocert.org/advisories/ocert-2011-003.html
+  * it seems that having hash randomization might be a good idea
+diff --git a/hash.c b/hash.c
+index 02e01fb..ba36e15 100644
+--- a/hash.c
++++ b/hash.c
+@@ -28,6 +28,9 @@
+ #include <time.h>
+ #endif
+ 
++/* Force randomization even if configure wasn't regenerated */
++#define HASH_RANDOMIZATION
++
+ /*
+  * Following http://www.ocert.org/advisories/ocert-2011-003.html
+  * it seems that having hash randomization might be a good idea
+-- 
+1.7.11.4
+
diff --git a/libxml2.spec b/libxml2.spec
index 7856c13..ae8049a 100644
--- a/libxml2.spec
+++ b/libxml2.spec
@@ -1,16 +1,47 @@
 Summary: Library providing XML and HTML support
 Name: libxml2
 Version: 2.7.8
-Release: 7%{?dist}%{?extra_release}
+Release: 8%{?dist}%{?extra_release}
 License: MIT
 Group: Development/Libraries
 Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
 BuildRoot: %{_tmppath}/%{name}-%{version}-root
 BuildRequires: python python-devel zlib-devel pkgconfig
 URL: http://xmlsoft.org/
-Patch0: libxml2-multilib.patch
-Patch1: libxml2-2.7.8-reactivate-versionning-script.patch
-Patch2: libxml2-2.7.7-xpath-double-free.patch
+Patch0: libxml2-Multilib-fix.patch
+Patch1: libxml2-Reactivate-the-shared-library-versionning-script.patch
+Patch2: libxml2-Fix-a-potential-freeing-error-in-XPath.patch
+Patch3: libxml2-Small-fix-for-previous-commit.patch
+Patch4: libxml2-Fix-some-potential-problems-on-reallocation-failures.patch
+Patch5: libxml2-Hardening-of-XPath-evaluation.patch
+Patch6: libxml2-Fix-an-off-by-one-error-in-encoding.patch
+Patch7: libxml2-Fix-missing-error-status-in-XPath-evaluation.patch
+Patch8: libxml2-Make-sure-the-parser-returns-when-getting-a-Stop-order.patch
+Patch9: libxml2-Fix-an-allocation-error-when-copying-entities.patch
+Patch10: libxml2-Add-hash-randomization-to-hash-and-dict-structures.patch
+Patch11: libxml2-force-randomization-of-dict-and-hash.patch
+Patch12: libxml2-Fix-a-failure-to-report-xmlreader-parsing-failures.patch
+Patch13: libxml2-Fix-parser-local-buffers-size-problems.patch
+Patch14: libxml2-Fix-entities-local-buffers-size-problems.patch
+Patch15: libxml2-Fix-an-error-in-previous-commit.patch
+Patch16: libxml2-Do-not-fetch-external-parsed-entities.patch
+Patch17: libxml2-Impose-a-reasonable-limit-on-attribute-size.patch
+Patch18: libxml2-Impose-a-reasonable-limit-on-comment-size.patch
+Patch19: libxml2-Impose-a-reasonable-limit-on-PI-size.patch
+Patch20: libxml2-Cleanups-and-new-limit-APIs-for-dictionaries.patch
+Patch21: libxml2-Introduce-some-default-parser-limits.patch
+Patch22: libxml2-Implement-some-default-limits-in-the-XPath-module.patch
+Patch23: libxml2-Fixup-limits-parser.patch
+Patch24: libxml2-Enforce-XML_PARSER_EOF-state-handling-through-the-parser.patch
+Patch25: libxml2-Avoid-quadratic-behaviour-in-some-push-parsing-cases.patch
+Patch26: libxml2-More-avoid-quadratic-behaviour.patch
+Patch27: libxml2-Strengthen-behaviour-of-the-push-parser-in-problematic-situations.patch
+Patch28: libxml2-More-fixups-on-the-push-parser-behaviour.patch
+Patch29: libxml2-Fix-a-segfault-on-XSD-validation-on-pattern-error.patch
+Patch30: libxml2-Fix-an-unimplemented-part-in-RNG-value-validation.patch
+Patch31: libxml2-Fix-an-off-by-one-pointer-access.patch
+Patch32: libxml2-Change-the-XPath-code-to-percolate-allocation-errors.patch
+
 
 %description
 This library allows to manipulate XML files. It includes support 
@@ -71,6 +102,36 @@ at parse time or later once the document has been modified.
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
 
 %build
 %configure
@@ -145,6 +206,44 @@ rm -fr %{buildroot}
 %doc doc/python.html
 
 %changelog
+* Mon Sep 10 2012 Daniel Veillard <veillard at redhat.com> - 2.7.8-8
+- Fixes for CVE-2011-3919 CVE-2011-3905 CVE-2011-2834 (rhbz#772122)
+- Fixes for CVE-2012-2807 (843743)
+- Fixes for CVE-2012-0841 (795698)
+- Fix for CVE-2011-1944 (709750)
+- Fix for CVE-2011-0216 (755813)
+- Fix for CVE-2011-2821 (735715)
+- Fix for CVE-2011-3102 (822171)
+- Fix some potential problems on reallocation failures
+- Hardening of XPath evaluation
+- Fix an off by one error in encoding
+- Fix missing error status in XPath evaluation
+- Make sure the parser returns when getting a Stop order
+- Fix an allocation error when copying entities
+- Add hash randomization to hash and dict structures
+- Force randomization of dict and hash
+- Fix a failure to report xmlreader parsing failures
+- Fix parser local buffers size problems
+- Fix entities local buffers size problems
+- Fix an error in previous commit
+- Do not fetch external parsed entities
+- Impose a reasonable limit on attribute size
+- Impose a reasonable limit on comment size
+- Impose a reasonable limit on PI size
+- Cleanups and new limit APIs for dictionaries
+- Introduce some default parser limits
+- Implement some default limits in the XPath module
+- Fixup limits parser
+- Enforce XML_PARSER_EOF state handling through the parser
+- Avoid quadratic behaviour in some push parsing cases
+- More avoid quadratic behaviour
+- Strengthen behaviour of the push parser in problematic situations
+- More fixups on the push parser behaviour
+- Fix a segfault on XSD validation on pattern error
+- Fix an unimplemented part in RNG value validation
+- Fix an off by one pointer access
+- Change the XPath code to percolate allocation errors
+
 * Fri Jan 13 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.7.8-7
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
 


More information about the scm-commits mailing list