diff src/org/tmatesoft/hg/internal/InflaterDataAccess.java @ 399:fdc1db8f7f61 smartgit3

Issue 25: Underflow in InflaterDataAccess; test and fix for hang up when reading past end of compressed data (or zero-length data)
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Sat, 25 Feb 2012 19:31:57 +0100
parents 856517285256
children 6c22bdc0bdfd
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/InflaterDataAccess.java	Thu Feb 23 15:31:57 2012 +0100
+++ b/src/org/tmatesoft/hg/internal/InflaterDataAccess.java	Sat Feb 25 19:31:57 2012 +0100
@@ -158,20 +158,20 @@
 		    int n;
 		    while (len > 0) {
 			    while ((n = inflater.inflate(b, off, len)) == 0) {
-			    	// FIXME few last bytes (checksum?) may be ignored by inflater, thus inflate may return 0 in
+			    	// XXX few last bytes (checksum?) may be ignored by inflater, thus inflate may return 0 in
 			    	// perfectly legal conditions (when all data already expanded, but there are still some bytes
-			    	// in the input stream
-					if (inflater.finished() || inflater.needsDictionary()) {
-	                    throw new EOFException();
-					}
-					if (inflater.needsInput()) {
+			    	// in the input stream)
+					int toRead = -1;
+					if (inflater.needsInput() && (toRead = super.available()) > 0) {
 						// fill:
-						int toRead = super.available();
 						if (toRead > buffer.length) {
 							toRead = buffer.length;
 						}
 						super.readBytes(buffer, 0, toRead);
 						inflater.setInput(buffer, 0, toRead);
+					} else {
+						// prevent hang up in this cycle if no more data is available, see Issue 25
+						throw new EOFException(String.format("No more compressed data is available to satisfy request for %d bytes. [finished:%b, needDict:%b, needInp:%b, available:%d", len, inflater.finished(), inflater.needsDictionary(), inflater.needsInput(), toRead));
 					}
 			    }
 				off += n;