Browse Source

Fix loading packed objects >2G

Parsing the size from a packed object header was incorrectly computing
the total inflated length when the length exceeded the range of a Java
int. The next 7 bits of size information was shifted left as an int
using a shift of 25 bits, placing the higher bits of the size into the
sign position. When this size was extended to a long to be added to
the current size accumulator the size went negative, resulting in
NegativeArraySizeException being thrown.

Fix all places where this particular pattern of code is used to read a
pack size field, or a binary delta header, as they both use the same
variable length encoding scheme.

Change-Id: I04008728ed828f18202652c3d5401cf95a441d0a
stable-2.0
Shawn O. Pearce 13 years ago
parent
commit
6c0d300a54
  1. 6
      org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/PackChunk.java
  2. 6
      org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java
  3. 6
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
  4. 4
      org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java
  5. 12
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/BinaryDelta.java
  6. 6
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaStream.java
  7. 4
      org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java

6
org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/PackChunk.java

@ -349,7 +349,7 @@ public final class PackChunk {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = dataBuf[posPtr + p++] & 0xff; c = dataBuf[posPtr + p++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -603,7 +603,7 @@ public final class PackChunk {
int shift = 4; int shift = 4;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = dataBuf[ptr++] & 0xff; c = dataBuf[ptr++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -650,7 +650,7 @@ public final class PackChunk {
int shift = 4; int shift = 4;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = dataBuf[ptr++] & 0xff; c = dataBuf[ptr++] & 0xff;
inflatedSize += (c & 0x7f) << shift; inflatedSize += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }

6
org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java

@ -395,7 +395,7 @@ public final class DfsPackFile {
int headerCnt = 1; int headerCnt = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = buf[headerCnt++] & 0xff; c = buf[headerCnt++] & 0xff;
inflatedLength += (c & 0x7f) << shift; inflatedLength += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -676,7 +676,7 @@ public final class DfsPackFile {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = ib[p++] & 0xff; c = ib[p++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -907,7 +907,7 @@ public final class DfsPackFile {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = ib[p++] & 0xff; c = ib[p++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }

6
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java

@ -345,7 +345,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
int headerCnt = 1; int headerCnt = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = buf[headerCnt++] & 0xff; c = buf[headerCnt++] & 0xff;
inflatedLength += (c & 0x7f) << shift; inflatedLength += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -684,7 +684,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = ib[p++] & 0xff; c = ib[p++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -929,7 +929,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = ib[p++] & 0xff; c = ib[p++] & 0xff;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }

4
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java

@ -151,7 +151,7 @@ public class UnpackedObject {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = hdr[p++] & 0xff; c = hdr[p++] & 0xff;
size += (c & 0x7f) << shift; size += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
@ -224,7 +224,7 @@ public class UnpackedObject {
int p = 1; int p = 1;
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = hdr[p++] & 0xff; c = hdr[p++] & 0xff;
size += (c & 0x7f) << shift; size += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
return size; return size;

12
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/BinaryDelta.java

@ -70,7 +70,7 @@ public class BinaryDelta {
int c, shift = 0; int c, shift = 0;
do { do {
c = delta[p++] & 0xff; c = delta[p++] & 0xff;
baseLen |= (c & 0x7f) << shift; baseLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
return baseLen; return baseLen;
@ -97,7 +97,7 @@ public class BinaryDelta {
int shift = 0; int shift = 0;
do { do {
c = delta[p++] & 0xff; c = delta[p++] & 0xff;
resLen |= (c & 0x7f) << shift; resLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
return resLen; return resLen;
@ -142,7 +142,7 @@ public class BinaryDelta {
int c, shift = 0; int c, shift = 0;
do { do {
c = delta[deltaPtr++] & 0xff; c = delta[deltaPtr++] & 0xff;
baseLen |= (c & 0x7f) << shift; baseLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
if (base.length != baseLen) if (base.length != baseLen)
@ -155,7 +155,7 @@ public class BinaryDelta {
shift = 0; shift = 0;
do { do {
c = delta[deltaPtr++] & 0xff; c = delta[deltaPtr++] & 0xff;
resLen |= (c & 0x7f) << shift; resLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
@ -243,7 +243,7 @@ public class BinaryDelta {
int c, shift = 0; int c, shift = 0;
do { do {
c = delta[deltaPtr++] & 0xff; c = delta[deltaPtr++] & 0xff;
baseLen |= (c & 0x7f) << shift; baseLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
@ -251,7 +251,7 @@ public class BinaryDelta {
shift = 0; shift = 0;
do { do {
c = delta[deltaPtr++] & 0xff; c = delta[deltaPtr++] & 0xff;
resLen |= (c & 0x7f) << shift; resLen |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);

6
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaStream.java

@ -114,7 +114,7 @@ public abstract class DeltaStream extends InputStream {
int c, shift = 0; int c, shift = 0;
do { do {
c = cmdbuf[cmdptr++] & 0xff; c = cmdbuf[cmdptr++] & 0xff;
baseSize |= (c & 0x7f) << shift; baseSize |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
@ -123,7 +123,7 @@ public abstract class DeltaStream extends InputStream {
shift = 0; shift = 0;
do { do {
c = cmdbuf[cmdptr++] & 0xff; c = cmdbuf[cmdptr++] & 0xff;
resultSize |= (c & 0x7f) << shift; resultSize |= ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} while ((c & 0x80) != 0); } while ((c & 0x80) != 0);
@ -286,7 +286,7 @@ public abstract class DeltaStream extends InputStream {
if ((cmd & 0x04) != 0) if ((cmd & 0x04) != 0)
copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 16; copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 16;
if ((cmd & 0x08) != 0) if ((cmd & 0x08) != 0)
copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 24; copyOffset |= ((long) (cmdbuf[cmdptr++] & 0xff)) << 24;
copySize = 0; copySize = 0;
if ((cmd & 0x10) != 0) if ((cmd & 0x10) != 0)

4
org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java

@ -681,7 +681,7 @@ public abstract class PackParser {
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = readFrom(Source.DATABASE); c = readFrom(Source.DATABASE);
hdrBuf[hdrPtr++] = (byte) c; hdrBuf[hdrPtr++] = (byte) c;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }
info.size = sz; info.size = sz;
@ -892,7 +892,7 @@ public abstract class PackParser {
while ((c & 0x80) != 0) { while ((c & 0x80) != 0) {
c = readFrom(Source.INPUT); c = readFrom(Source.INPUT);
hdrBuf[hdrPtr++] = (byte) c; hdrBuf[hdrPtr++] = (byte) c;
sz += (c & 0x7f) << shift; sz += ((long) (c & 0x7f)) << shift;
shift += 7; shift += 7;
} }

Loading…
Cancel
Save