# HG changeset patch # User Artem Tikhomirov # Date 1330194916 -3600 # Node ID deb64baaa4127b0cf6de6ae787812d1aeecba34c # Parent c76c57f6b961308180b12ac5637fa9cc1c84a6a3# Parent fdc1db8f7f614704cf93169cb95d145b770c3511 Merge fixes for issue 25 from smartgit3 branch diff -r c76c57f6b961 -r deb64baaa412 src/org/tmatesoft/hg/internal/DataAccess.java --- a/src/org/tmatesoft/hg/internal/DataAccess.java Thu Feb 23 21:53:21 2012 +0100 +++ b/src/org/tmatesoft/hg/internal/DataAccess.java Sat Feb 25 19:35:16 2012 +0100 @@ -32,6 +32,7 @@ public boolean isEmpty() { return true; } + // TODO throws IOException (few subclasses have non-trivial length() operation) public int length() { return 0; } @@ -68,6 +69,10 @@ readBytes(b, 0, 4); return b[0] << 24 | (b[1] & 0xFF) << 16 | (b[2] & 0xFF) << 8 | (b[3] & 0xFF); } + + /** + * Read 8 bytes as long value, big-endian. + */ public long readLong() throws IOException { byte[] b = new byte[8]; readBytes(b, 0, 8); diff -r c76c57f6b961 -r deb64baaa412 src/org/tmatesoft/hg/internal/InflaterDataAccess.java --- a/src/org/tmatesoft/hg/internal/InflaterDataAccess.java Thu Feb 23 21:53:21 2012 +0100 +++ b/src/org/tmatesoft/hg/internal/InflaterDataAccess.java Sat Feb 25 19:35:16 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; diff -r c76c57f6b961 -r deb64baaa412 test-data/test-repos.jar Binary file test-data/test-repos.jar has changed diff -r c76c57f6b961 -r deb64baaa412 test/org/tmatesoft/hg/test/TestStatus.java --- a/test/org/tmatesoft/hg/test/TestStatus.java Thu Feb 23 21:53:21 2012 +0100 +++ b/test/org/tmatesoft/hg/test/TestStatus.java Sat Feb 25 19:35:16 2012 +0100 @@ -537,6 +537,10 @@ * b) That FilterDataAccess (with 0 size represents patch more or less relevantly, but didn't represent actual revision) get successfully * reassigned as lastUserData for the next iteration. And at the next step attempt to apply patch recorded in the next revision failed * because baseRevisionData is 0 length FilterDataAccess + * + * Same applies for + * Issue 25: IOException: Underflow. Rewind past end of the slice in InflaterDataAccess + * with the difference in separate .i and .d (thus not 0 but 'x' first byte was read) * * Sample: * status-5/file1 has 3 revisions, second is zero-length patch: @@ -551,10 +555,12 @@ @Test public void testZeroLengthPatchAgainstNonEmptyBaseRev() throws Exception{ repo = Configuration.get().find("status-5"); - // pretend we modified file in the working copy + // pretend we modified files in the working copy // for HgWorkingCopyStatusCollector to go and retrieve its content from repository File f1 = new File(repo.getWorkingDir(), "file1"); f1.setLastModified(System.currentTimeMillis()); + File f3 = new File(repo.getWorkingDir(), "file3"); + f3.setLastModified(System.currentTimeMillis()); // HgStatusCommand cmd = new HgStatusCommand(repo); cmd.all();