diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java
index 7289b9ee9..c1853327f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlock.java
@@ -74,11 +74,6 @@ final class DfsBlock {
return block.length;
}
- int remaining(long pos) {
- int ptr = (int) (pos - start);
- return block.length - ptr;
- }
-
boolean contains(DfsPackKey want, long pos) {
return pack == want && start <= pos && pos < end;
}
@@ -94,9 +89,11 @@ final class DfsBlock {
return n;
}
- void setInput(Inflater inf, long pos) {
+ int setInput(long pos, Inflater inf) {
int ptr = (int) (pos - start);
- inf.setInput(block, ptr, block.length - ptr);
+ int cnt = block.length - ptr;
+ inf.setInput(block, ptr, cnt);
+ return cnt;
}
void crc32(CRC32 out, long pos, int cnt) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index 22a03dd8e..5cab473c3 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -460,31 +460,29 @@ public class DfsInserter extends ObjectInserter {
}
Inflater inf = ctx.inflater();
- DfsBlock b = setInput(inf, pos);
+ pos += setInput(pos, inf);
for (int dstoff = 0;;) {
int n = inf.inflate(dstbuf, dstoff, dstbuf.length - dstoff);
- if (n > 0)
- dstoff += n;
- else if (inf.needsInput() && b != null) {
- pos += b.remaining(pos);
- b = setInput(inf, pos);
- } else if (inf.needsInput())
- throw new EOFException(DfsText.get().unexpectedEofInPack);
- else if (inf.finished())
+ dstoff += n;
+ if (inf.finished())
return dstbuf;
- else
+ if (inf.needsInput())
+ pos += setInput(pos, inf);
+ else if (n == 0)
throw new DataFormatException();
}
}
- private DfsBlock setInput(Inflater inf, long pos) throws IOException {
- if (pos < currPos) {
- DfsBlock b = getOrLoadBlock(pos);
- b.setInput(inf, pos);
- return b;
+ private int setInput(long pos, Inflater inf) throws IOException {
+ if (pos < currPos)
+ return getOrLoadBlock(pos).setInput(pos, inf);
+ if (pos < currPos + currPtr) {
+ int s = (int) (pos - currPos);
+ int n = currPtr - s;
+ inf.setInput(currBuf, s, n);
+ return n;
}
- inf.setInput(currBuf, (int) (pos - currPos), currPtr);
- return null;
+ throw new EOFException(DfsText.get().unexpectedEofInPack);
}
private DfsBlock getOrLoadBlock(long pos) throws IOException {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
index d7b222866..37dbc7ea7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReader.java
@@ -600,11 +600,11 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs {
* position within the file to read from.
* @param dstbuf
* destination buffer the inflater should output decompressed
- * data to.
+ * data to. Must be large enough to store the entire stream,
+ * unless headerOnly is true.
* @param headerOnly
* if true the caller wants only {@code dstbuf.length} bytes.
- * @return updated dstoff
based on the number of bytes
- * successfully inflated into dstbuf
.
+ * @return number of bytes inflated into dstbuf
.
* @throws IOException
* this cursor does not match the provider or id and the proper
* window could not be acquired through the provider's cache.
@@ -616,24 +616,17 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs {
boolean headerOnly) throws IOException, DataFormatException {
prepareInflater();
pin(pack, position);
- block.setInput(inf, position);
- int dstoff = 0;
- for (;;) {
+ position += block.setInput(position, inf);
+ for (int dstoff = 0;;) {
int n = inf.inflate(dstbuf, dstoff, dstbuf.length - dstoff);
- if (n == 0) {
- if (headerOnly && dstoff == dstbuf.length)
- return dstoff;
- if (inf.needsInput()) {
- position += block.remaining(position);
- pin(pack, position);
- block.setInput(inf, position);
- continue;
- }
- if (inf.finished())
- return dstoff;
- throw new DataFormatException();
- }
dstoff += n;
+ if (inf.finished() || (headerOnly && dstoff == dstbuf.length))
+ return dstoff;
+ if (inf.needsInput()) {
+ pin(pack, position);
+ position += block.setInput(position, inf);
+ } else if (n == 0)
+ throw new DataFormatException();
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
index 81f8ab675..306a0d389 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackFile.java
@@ -335,7 +335,7 @@ public class PackFile implements Iterable {
return null;
}
- if (curs.inflate(this, position, dstbuf, 0) != sz)
+ if (curs.inflate(this, position, dstbuf, false) != sz)
throw new EOFException(MessageFormat.format(
JGitText.get().shortCompressedStreamAt,
Long.valueOf(position)));
@@ -886,7 +886,7 @@ public class PackFile implements Iterable {
// the longest delta instruction header.
//
final byte[] hdr = new byte[18];
- wc.inflate(this, pos, hdr, 0);
+ wc.inflate(this, pos, hdr, true /* headerOnly */);
return hdr;
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
index 8dcbeb896..a0a4c952f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/WindowCursor.java
@@ -290,11 +290,11 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs {
* position within the file to read from.
* @param dstbuf
* destination buffer the inflater should output decompressed
- * data to.
- * @param dstoff
- * current offset within dstbuf
to inflate into.
- * @return updated dstoff
based on the number of bytes
- * successfully inflated into dstbuf
.
+ * data to. Must be large enough to store the entire stream,
+ * unless headerOnly is true.
+ * @param headerOnly
+ * if true the caller wants only {@code dstbuf.length} bytes.
+ * @return number of bytes inflated into dstbuf
.
* @throws IOException
* this cursor does not match the provider or id and the proper
* window could not be acquired through the provider's cache.
@@ -303,24 +303,21 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs {
* stream corruption is likely.
*/
int inflate(final PackFile pack, long position, final byte[] dstbuf,
- int dstoff) throws IOException, DataFormatException {
+ boolean headerOnly) throws IOException, DataFormatException {
prepareInflater();
pin(pack, position);
position += window.setInput(position, inf);
- do {
+ for (int dstoff = 0;;) {
int n = inf.inflate(dstbuf, dstoff, dstbuf.length - dstoff);
- if (n == 0) {
- if (inf.needsInput()) {
- pin(pack, position);
- position += window.setInput(position, inf);
- } else if (inf.finished())
- return dstoff;
- else
- throw new DataFormatException();
- }
dstoff += n;
- } while (dstoff < dstbuf.length);
- return dstoff;
+ if (inf.finished() || (headerOnly && dstoff == dstbuf.length))
+ return dstoff;
+ if (inf.needsInput()) {
+ pin(pack, position);
+ position += window.setInput(position, inf);
+ } else if (n == 0)
+ throw new DataFormatException();
+ }
}
ByteArrayWindow quickCopy(PackFile p, long pos, long cnt)
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
index c3fdacc27..633554a96 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java
@@ -1653,24 +1653,19 @@ public abstract class PackParser {
int n = 0;
while (n < cnt) {
int r = inf.inflate(dst, pos + n, cnt - n);
- if (r == 0) {
- if (inf.finished())
- break;
- if (inf.needsInput()) {
- onObjectData(src, buf, p, bAvail);
- use(bAvail);
-
- p = fill(src, 1);
- inf.setInput(buf, p, bAvail);
- } else {
- throw new CorruptObjectException(
- MessageFormat
- .format(
- JGitText.get().packfileCorruptionDetected,
- JGitText.get().unknownZlibError));
- }
- } else {
- n += r;
+ n += r;
+ if (inf.finished())
+ break;
+ if (inf.needsInput()) {
+ onObjectData(src, buf, p, bAvail);
+ use(bAvail);
+
+ p = fill(src, 1);
+ inf.setInput(buf, p, bAvail);
+ } else if (r == 0) {
+ throw new CorruptObjectException(MessageFormat.format(
+ JGitText.get().packfileCorruptionDetected,
+ JGitText.get().unknownZlibError));
}
}
actualSize += n;