Index: /trunk/src/libs/libxml2-2.6.31/include/libxml/parser.h
===================================================================
--- /trunk/src/libs/libxml2-2.6.31/include/libxml/parser.h	(revision 45448)
+++ /trunk/src/libs/libxml2-2.6.31/include/libxml/parser.h	(revision 45449)
@@ -300,4 +300,5 @@
     unsigned long    nbentities;    /* number of entities references */
     unsigned long  sizeentities;    /* size of parsed entities */
+    unsigned long      sizeentcopy;   /* volume of entity copy */
 };
 
Index: /trunk/src/libs/libxml2-2.6.31/include/libxml/parserInternals.h
===================================================================
--- /trunk/src/libs/libxml2-2.6.31/include/libxml/parserInternals.h	(revision 45448)
+++ /trunk/src/libs/libxml2-2.6.31/include/libxml/parserInternals.h	(revision 45449)
@@ -30,4 +30,13 @@
  */
 XMLPUBVAR unsigned int xmlParserMaxDepth;
+
+/**
+ * XML_MAX_TEXT_LENGTH:
+ *
+ * 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.
+ */
+#define XML_MAX_TEXT_LENGTH 10000000
 
  /**
Index: /trunk/src/libs/libxml2-2.6.31/parser.c
===================================================================
--- /trunk/src/libs/libxml2-2.6.31/parser.c	(revision 45448)
+++ /trunk/src/libs/libxml2-2.6.31/parser.c	(revision 45449)
@@ -112,5 +112,5 @@
 static int
 xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size,
-                     xmlEntityPtr ent)
+                     xmlEntityPtr ent, size_t replacement)
 {
     size_t consumed = 0;
@@ -120,5 +120,22 @@
     if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
         return (1);
-    if (size != 0) {
+    if (replacement != 0) {
+	if (replacement < XML_MAX_TEXT_LENGTH)
+	    return(0);
+
+        /*
+	 * If the volume of entity copy reaches 10 times the
+	 * amount of parsed data and over the large text threshold
+	 * then that's very likely to be an abuse.
+	 */
+        if (ctxt->input != NULL) {
+	    consumed = ctxt->input->consumed +
+	               (ctxt->input->cur - ctxt->input->base);
+	}
+        consumed += ctxt->sizeentities;
+
+        if (replacement < XML_PARSER_NON_LINEAR * consumed)
+	    return(0);
+    } else if (size != 0) {
         /*
          * Do the check based on the replacement size of the entity
@@ -166,5 +183,4 @@
         return (0);
     }
-
     xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
     return (1);
@@ -2379,5 +2395,5 @@
 			buffer[nbchars++] = *current++;
 			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
-			    if (xmlParserEntityCheck(ctxt, nbchars, ent)) {
+			    if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) {
 			        xmlFree(rep);
 			        goto int_error;
@@ -2421,5 +2437,5 @@
 			buffer[nbchars++] = *current++;
 			if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
-			    if (xmlParserEntityCheck(ctxt, nbchars, ent)) {
+			    if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) {
 			        xmlFree(rep);
 			        goto int_error;
@@ -6278,5 +6294,5 @@
 			return;
 		    }
-		    if (xmlParserEntityCheck(ctxt, 0, ent)) {
+		    if (xmlParserEntityCheck(ctxt, 0, ent, 0)) {
 			xmlFreeNodeList(list);
 			return;
@@ -6431,4 +6447,11 @@
 
 			/*
+			 * We are copying here, make sure there is no abuse
+			 */
+			ctxt->sizeentcopy += ent->length;
+			if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
+			    return;
+
+			/*
 			 * when operating on a reader, the entities definitions
 			 * are always owning the entities subtree.
@@ -6470,4 +6493,12 @@
 			xmlNodePtr nw = NULL, cur, next, last,
 			           firstChild = NULL;
+
+			/*
+			 * We are copying here, make sure there is no abuse
+			 */
+			ctxt->sizeentcopy += ent->length;
+			if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
+			    return;
+
 			/*
 			 * Copy the entity child list and make it the new
@@ -13308,4 +13339,5 @@
     ctxt->nbentities = 0;
     ctxt->sizeentities = 0;
+    ctxt->sizeentcopy = 0;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
 
Index: /trunk/src/libs/libxml2-2.6.31/parserInternals.c
===================================================================
--- /trunk/src/libs/libxml2-2.6.31/parserInternals.c	(revision 45448)
+++ /trunk/src/libs/libxml2-2.6.31/parserInternals.c	(revision 45449)
@@ -1672,4 +1672,6 @@
     ctxt->catalogs = NULL;
     ctxt->nbentities = 0;
+    ctxt->sizeentities = 0;
+    ctxt->sizeentcopy = 0;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
     return(0);
