Index: xmlreader.c
===================================================================
--- xmlreader.c	(revision 7902)
+++ xmlreader.c	(working copy)
@@ -809,6 +809,8 @@
     xmlBufferPtr inbuf;
     int val, s;
     xmlTextReaderState oldstate;
+    int csize = CHUNK_SIZE;
+    int search_tag_end;
 
     if ((reader->input == NULL) || (reader->input->buffer == NULL))
 	return(-1);
@@ -816,9 +818,10 @@
     oldstate = reader->state;
     reader->state = XML_TEXTREADER_NONE;
     inbuf = reader->input->buffer;
+    search_tag_end = 0;
 
     while (reader->state == XML_TEXTREADER_NONE) {
-	if (inbuf->use < reader->cur + CHUNK_SIZE) {
+	if (inbuf->use < reader->cur + csize) {
 	    /*
 	     * Refill the buffer unless we are at the end of the stream
 	     */
@@ -840,8 +843,15 @@
 		    /* mark the end of the stream and process the remains */
 		    reader->mode = XML_TEXTREADER_MODE_EOF;
 		    break;
+		} if ((val > 0) && (search_tag_end)) {
+		    const xmlChar *tmp, *end;
+		    tmp = &inbuf->content[inbuf->use-val];
+		    end = &inbuf->content[inbuf->use];
+		    while (*tmp != '>' && tmp < end) tmp++;
+		    csize = tmp - &inbuf->content[reader->cur] + 1;
+		    search_tag_end = (tmp == end);
 		}
-
+		continue; /* ensure we have enough data */
 	    } else 
 		break;
 	}
@@ -849,11 +859,11 @@
 	 * parse by block of CHUNK_SIZE bytes, various tests show that
 	 * it's the best tradeoff at least on a 1.2GH Duron
 	 */
-	if (inbuf->use >= reader->cur + CHUNK_SIZE) {
+	if (inbuf->use >= reader->cur + csize) {
 	    val = xmlParseChunk(reader->ctxt,
 		          (const char *) &inbuf->content[reader->cur],
-			  CHUNK_SIZE, 0);
-	    reader->cur += CHUNK_SIZE;
+			  csize, 0);
+	    reader->cur += csize;
 	    if ((val != 0) || (reader->ctxt->wellFormed == 0))
 		return(-1);
 	} else {
@@ -866,6 +876,22 @@
 		return(-1);
 	    break;
 	}
+
+	/*
+	 * If nothing parsed on first pass try to find the end of a tag
+	 * and pass at least that much to next chunk parse or trigger
+	 * reading of input until we find a potential tag end
+	 */
+	if (reader->state == XML_TEXTREADER_NONE) {
+	    const xmlChar *tmp, *end;
+	    tmp = &inbuf->content[reader->cur];
+	    end = &inbuf->content[inbuf->use];
+	    while (*tmp != '>' && tmp < end) tmp++;
+	    csize = tmp - &inbuf->content[reader->cur] + 1;
+	    if (csize < CHUNK_SIZE)
+		csize = CHUNK_SIZE;
+	    search_tag_end = (tmp == end);
+	}
     }
 
     /*
