diff --git a/ThirdParty/libxml2/vtklibxml2/configure.ac b/ThirdParty/libxml2/vtklibxml2/configure.ac
index 36e74e4e967253c378cb0770181007a8914536bf..48cd2f0dc4524d584c1f24354ddf68f50cb7c864 100644
--- a/ThirdParty/libxml2/vtklibxml2/configure.ac
+++ b/ThirdParty/libxml2/vtklibxml2/configure.ac
@@ -3,7 +3,7 @@ AC_PREREQ([2.63])
 
 m4_define([MAJOR_VERSION], 2)
 m4_define([MINOR_VERSION], 13)
-m4_define([MICRO_VERSION], 4)
+m4_define([MICRO_VERSION], 5)
 
 AC_INIT([libxml2],[MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION])
 AC_CONFIG_SRCDIR([entities.c])
diff --git a/ThirdParty/libxml2/vtklibxml2/parser.c b/ThirdParty/libxml2/vtklibxml2/parser.c
index 365025c5eb94f3811e42d325a6e3b1173a67a032..52ca356526131b1d70c5cdd16306e353087128f0 100644
--- a/ThirdParty/libxml2/vtklibxml2/parser.c
+++ b/ThirdParty/libxml2/vtklibxml2/parser.c
@@ -8912,6 +8912,35 @@ xmlAttrHashInsert(xmlParserCtxtPtr ctxt, unsigned size, const xmlChar *name,
     return(INT_MAX);
 }
 
+static int
+xmlAttrHashInsertQName(xmlParserCtxtPtr ctxt, unsigned size,
+                       const xmlChar *name, const xmlChar *prefix,
+                       unsigned hashValue, int aindex) {
+    xmlAttrHashBucket *table = ctxt->attrHash;
+    xmlAttrHashBucket *bucket;
+    unsigned hindex;
+
+    hindex = hashValue & (size - 1);
+    bucket = &table[hindex];
+
+    while (bucket->index >= 0) {
+        const xmlChar **atts = &ctxt->atts[bucket->index];
+
+        if ((name == atts[0]) && (prefix == atts[1]))
+            return(bucket->index);
+
+        hindex++;
+        bucket++;
+        if (hindex >= size) {
+            hindex = 0;
+            bucket = table;
+        }
+    }
+
+    bucket->index = aindex;
+
+    return(INT_MAX);
+}
 /**
  * xmlParseStartTag2:
  * @ctxt:  an XML parser context
@@ -8960,6 +8989,8 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
     int nratts, nbatts, nbdef;
     int i, j, nbNs, nbTotalDef, attval, nsIndex, maxAtts;
     int alloc = 0;
+    int numNsErr = 0;
+    int numDupErr = 0;
 
     if (RAW != '<') return(NULL);
     NEXT1;
@@ -9338,10 +9369,12 @@ next_attr:
             if (res < INT_MAX) {
                 if (aprefix == atts[res+1]) {
                     xmlErrAttributeDup(ctxt, aprefix, attname);
+                    numDupErr += 1;
                 } else {
                     xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
                              "Namespaced Attribute %s in '%s' redefined\n",
                              attname, nsuri, NULL);
+                    numNsErr += 1;
                 }
             }
         }
@@ -9440,6 +9473,43 @@ next_attr:
 	}
     }
 
+    /*
+     * Using a single hash table for nsUri/localName pairs cannot
+     * detect duplicate QNames reliably. The following example will
+     * only result in two namespace errors.
+     *
+     * <doc xmlns:a="a" xmlns:b="a">
+     *   <elem a:a="" b:a="" b:a=""/>
+     * </doc>
+     *
+     * If we saw more than one namespace error but no duplicate QNames
+     * were found, we have to scan for duplicate QNames.
+     */
+    if ((numDupErr == 0) && (numNsErr > 1)) {
+        memset(ctxt->attrHash, -1,
+               attrHashSize * sizeof(ctxt->attrHash[0]));
+
+        for (i = 0, j = 0; j < nratts; i += 5, j++) {
+            unsigned hashValue, nameHashValue, prefixHashValue;
+            int res;
+
+            aprefix = atts[i+1];
+            if (aprefix == NULL)
+                continue;
+
+            attname = atts[i];
+            /* Hash values always have bit 31 set, see dict.c */
+            nameHashValue = ctxt->attallocs[j] | 0x80000000;
+            prefixHashValue = xmlDictComputeHash(ctxt->dict, aprefix);
+
+            hashValue = xmlDictCombineHash(nameHashValue, prefixHashValue);
+            res = xmlAttrHashInsertQName(ctxt, attrHashSize, attname,
+                                         aprefix, hashValue, i);
+            if (res < INT_MAX)
+                xmlErrAttributeDup(ctxt, aprefix, attname);
+        }
+    }
+
     /*
      * Reconstruct attribute pointers
      */
@@ -11763,6 +11833,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
         xmlFreeParserInputBuffer(input);
 	return(NULL);
     }
+    xmlCtxtSetOptions(ctxt, XML_PARSE_DTDLOAD);
 
     /*
      * generate a parser input from the I/O handler
@@ -11852,6 +11923,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
     if (ctxt == NULL) {
 	return(NULL);
     }
+    xmlCtxtSetOptions(ctxt, XML_PARSE_DTDLOAD);
 
     /*
      * Canonicalise the system ID
@@ -12143,6 +12215,15 @@ xmlCtxtParseEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr ent) {
 
         while (list != NULL) {
             list->parent = (xmlNodePtr) ent;
+
+            /*
+             * Downstream code like the nginx xslt module can set
+             * ctxt->myDoc->extSubset to a separate DTD, so the entity
+             * might have a different or a NULL document.
+             */
+            if (list->doc != ent->doc)
+                xmlSetTreeDoc(list, ent->doc);
+
             if (list->next == NULL)
                 ent->last = list;
             list = list->next;
diff --git a/ThirdParty/libxml2/vtklibxml2/xmlIO.c b/ThirdParty/libxml2/vtklibxml2/xmlIO.c
index 353771b7f2535111193f0e23072f970711c82d3e..41197477c9efb729f250844d3170bbcf9cf8ea0e 100644
--- a/ThirdParty/libxml2/vtklibxml2/xmlIO.c
+++ b/ThirdParty/libxml2/vtklibxml2/xmlIO.c
@@ -1210,7 +1210,13 @@ xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) {
         if (xzStream == NULL) {
             close(fd);
         } else {
-            if (__libxml2_xzcompressed(xzStream) > 0) {
+            /*
+             * Non-regular files like pipes can't be reopened.
+             * If a file isn't seekable, we pipe uncompressed
+             * input through xzlib.
+             */
+            if ((lseek(fd, 0, SEEK_CUR) < 0) ||
+                (__libxml2_xzcompressed(xzStream) > 0)) {
                 buf->context = xzStream;
                 buf->readcallback = xmlXzfileRead;
                 buf->closecallback = xmlXzfileClose;
@@ -1237,12 +1243,13 @@ xmlInputDefaultOpen(xmlParserInputBufferPtr buf, const char *filename) {
         if (gzStream == NULL) {
             close(fd);
         } else {
-            char buff4[4];
-
-            if ((gzread(gzStream, buff4, 4) > 0) &&
+            /*
+             * Non-regular files like pipes can't be reopened.
+             * If a file isn't seekable, we pipe uncompressed
+             * input through zlib.
+             */
+            if ((lseek(fd, 0, SEEK_CUR) < 0) ||
                 (gzdirect(gzStream) == 0)) {
-                gzrewind(gzStream);
-
                 buf->context = gzStream;
                 buf->readcallback = xmlGzfileRead;
                 buf->closecallback = xmlGzfileClose;
diff --git a/ThirdParty/libxml2/vtklibxml2/xmlreader.c b/ThirdParty/libxml2/vtklibxml2/xmlreader.c
index 3528d7d8f0c179d401c4a454a43c1a290ddae0c1..e23400ac34392e7a14c142aeac1c97ffe5e43064 100644
--- a/ThirdParty/libxml2/vtklibxml2/xmlreader.c
+++ b/ThirdParty/libxml2/vtklibxml2/xmlreader.c
@@ -58,7 +58,7 @@
   #ifdef __va_copy
     #define va_copy(dest, src) __va_copy(dest, src)
   #else
-    #define va_copy(dest, src) memcpy(dest, src, sizeof(va_list))
+    #define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
   #endif
 #endif
 
@@ -1750,7 +1750,8 @@ xmlTextReaderReadString(xmlTextReaderPtr reader)
         case XML_CDATA_SECTION_NODE:
             break;
         case XML_ELEMENT_NODE:
-            if (xmlTextReaderDoExpand(reader) == -1)
+            if ((xmlTextReaderDoExpand(reader) == -1) ||
+                (node->children == NULL))
                 return(NULL);
             break;
         case XML_ATTRIBUTE_NODE:
diff --git a/ThirdParty/libxml2/vtklibxml2/xmlstring.c b/ThirdParty/libxml2/vtklibxml2/xmlstring.c
index 258ecc92c3bfe2fec9ce195f9882e86ff1b055d1..e3f92d3a8fcf77a3601f045e93ae51f4bcb114cd 100644
--- a/ThirdParty/libxml2/vtklibxml2/xmlstring.c
+++ b/ThirdParty/libxml2/vtklibxml2/xmlstring.c
@@ -30,7 +30,7 @@
   #ifdef __va_copy
     #define va_copy(dest, src) __va_copy(dest, src)
   #else
-    #define va_copy(dest, src) memcpy(dest, src, sizeof(va_list))
+    #define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
   #endif
 #endif
 
diff --git a/ThirdParty/libxml2/vtklibxml2/xmlwriter.c b/ThirdParty/libxml2/vtklibxml2/xmlwriter.c
index f648dc0520b388addc28d0fdc3b23681b9059f7a..c84d2be3ef3db3a402a6bf22e844a268914a4fa5 100644
--- a/ThirdParty/libxml2/vtklibxml2/xmlwriter.c
+++ b/ThirdParty/libxml2/vtklibxml2/xmlwriter.c
@@ -36,7 +36,7 @@
   #ifdef __va_copy
     #define va_copy(dest, src) __va_copy(dest, src)
   #else
-    #define va_copy(dest, src) memcpy(dest, src, sizeof(va_list))
+    #define va_copy(dest, src) memcpy(&(dest), &(src), sizeof(va_list))
   #endif
 #endif
 
diff --git a/ThirdParty/libxml2/vtklibxml2/xpath.c b/ThirdParty/libxml2/vtklibxml2/xpath.c
index 033de6219d8e14135e02bef55ed190e6f3fa633d..485d774738fc5cd1c1d3dbd98ab4b47772f4d426 100644
--- a/ThirdParty/libxml2/vtklibxml2/xpath.c
+++ b/ThirdParty/libxml2/vtklibxml2/xpath.c
@@ -10434,8 +10434,9 @@ xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
 	    } else if (CUR == '/') {
 		NEXT;
 		SKIP_BLANKS;
-		if ((CUR != 0 ) &&
-		    ((IS_ASCII_LETTER(CUR)) || (CUR == '_') || (CUR == '.') ||
+		if ((CUR != 0) &&
+		    ((IS_ASCII_LETTER(CUR)) || (CUR >= 0x80) ||
+                     (CUR == '_') || (CUR == '.') ||
 		     (CUR == '@') || (CUR == '*')))
 		    xmlXPathCompRelativeLocationPath(ctxt);
 	    }