diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-01-22 22:45:48 +0100 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-01-22 23:00:01 +0100 |
commit | 84dbc2d43169cdd41c79d853b75483cfd76ce7d6 (patch) | |
tree | 15eee2b5d374b9cbb4341c5a85221cffdf4a8e7b /org.eclipse.jgit | |
parent | cf9433a9b3c3359fbb4cbdd9c65b99b44eba08e8 (diff) | |
download | jgit-84dbc2d43169cdd41c79d853b75483cfd76ce7d6.tar.gz jgit-84dbc2d43169cdd41c79d853b75483cfd76ce7d6.zip |
TemporaryBuffer: fix toByteArray(limit)
Heap always copied whole blocks, which leads to AIOOBEs. LocalFile
didn't overwrite the method and thus caused NPEs.
Change-Id: Ia37d4a875df9f25d4825e6bc95fed7f0dff42afb
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 1f0fedda6b..562eb05dd9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -230,11 +230,16 @@ public abstract class TemporaryBuffer extends OutputStream { if (Integer.MAX_VALUE < len) throw new OutOfMemoryError( JGitText.get().lengthExceedsMaximumArraySize); - final byte[] out = new byte[(int) len]; + int length = (int) len; + final byte[] out = new byte[length]; int outPtr = 0; for (Block b : blocks) { - System.arraycopy(b.buffer, 0, out, outPtr, b.count); - outPtr += b.count; + int toCopy = Math.min(length - outPtr, b.count); + System.arraycopy(b.buffer, 0, out, outPtr, toCopy); + outPtr += toCopy; + if (outPtr == length) { + break; + } } return out; } @@ -461,6 +466,30 @@ public abstract class TemporaryBuffer extends OutputStream { } @Override + public byte[] toByteArray(int limit) throws IOException { + if (onDiskFile == null) { + return super.toByteArray(limit); + } + final long len = Math.min(length(), limit); + if (Integer.MAX_VALUE < len) { + throw new OutOfMemoryError( + JGitText.get().lengthExceedsMaximumArraySize); + } + final byte[] out = new byte[(int) len]; + try (FileInputStream in = new FileInputStream(onDiskFile)) { + int read = 0; + int chunk; + while ((chunk = in.read(out, read, out.length - read)) >= 0) { + read += chunk; + if (read == out.length) { + break; + } + } + } + return out; + } + + @Override public void writeTo(OutputStream os, ProgressMonitor pm) throws IOException { if (onDiskFile == null) { |