summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2021-01-22 22:45:48 +0100
committerThomas Wolf <thomas.wolf@paranor.ch>2021-01-22 23:00:01 +0100
commit84dbc2d43169cdd41c79d853b75483cfd76ce7d6 (patch)
tree15eee2b5d374b9cbb4341c5a85221cffdf4a8e7b /org.eclipse.jgit
parentcf9433a9b3c3359fbb4cbdd9c65b99b44eba08e8 (diff)
downloadjgit-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.java35
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) {