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
This commit is contained in:
parent
55bf06b43d
commit
6c0d300a54
|
@ -349,7 +349,7 @@ private static ObjectLoader read1(PackChunk pc, int pos,
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = dataBuf[posPtr + p++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -603,7 +603,7 @@ int readObjectTypeAndSize(int ptr, PackParser.ObjectTypeAndSize info) {
|
|||
int shift = 4;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = dataBuf[ptr++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -650,7 +650,7 @@ void copyObjectAsIs(PackOutputStream out, DhtObjectToPack obj,
|
|||
int shift = 4;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = dataBuf[ptr++] & 0xff;
|
||||
inflatedSize += (c & 0x7f) << shift;
|
||||
inflatedSize += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@ void copyAsIs(PackOutputStream out, DfsObjectToPack src,
|
|||
int headerCnt = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = buf[headerCnt++] & 0xff;
|
||||
inflatedLength += (c & 0x7f) << shift;
|
||||
inflatedLength += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -676,7 +676,7 @@ ObjectLoader load(DfsReader ctx, long pos)
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = ib[p++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -907,7 +907,7 @@ long getObjectSize(DfsReader ctx, long pos)
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = ib[p++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ private void copyAsIs2(PackOutputStream out, LocalObjectToPack src,
|
|||
int headerCnt = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = buf[headerCnt++] & 0xff;
|
||||
inflatedLength += (c & 0x7f) << shift;
|
||||
inflatedLength += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -684,7 +684,7 @@ ObjectLoader load(final WindowCursor curs, long pos)
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = ib[p++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -929,7 +929,7 @@ long getObjectSize(final WindowCursor curs, final long pos)
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = ib[p++] & 0xff;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ static ObjectLoader open(InputStream in, File path, AnyObjectId id,
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = hdr[p++] & 0xff;
|
||||
size += (c & 0x7f) << shift;
|
||||
size += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ static long getSize(InputStream in, AnyObjectId id, WindowCursor wc)
|
|||
int p = 1;
|
||||
while ((c & 0x80) != 0) {
|
||||
c = hdr[p++] & 0xff;
|
||||
size += (c & 0x7f) << shift;
|
||||
size += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
return size;
|
||||
|
|
|
@ -70,7 +70,7 @@ public static long getBaseSize(final byte[] delta) {
|
|||
int c, shift = 0;
|
||||
do {
|
||||
c = delta[p++] & 0xff;
|
||||
baseLen |= (c & 0x7f) << shift;
|
||||
baseLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
return baseLen;
|
||||
|
@ -97,7 +97,7 @@ public static long getResultSize(final byte[] delta) {
|
|||
int shift = 0;
|
||||
do {
|
||||
c = delta[p++] & 0xff;
|
||||
resLen |= (c & 0x7f) << shift;
|
||||
resLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
return resLen;
|
||||
|
@ -142,7 +142,7 @@ public static final byte[] apply(final byte[] base, final byte[] delta,
|
|||
int c, shift = 0;
|
||||
do {
|
||||
c = delta[deltaPtr++] & 0xff;
|
||||
baseLen |= (c & 0x7f) << shift;
|
||||
baseLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
if (base.length != baseLen)
|
||||
|
@ -155,7 +155,7 @@ public static final byte[] apply(final byte[] base, final byte[] delta,
|
|||
shift = 0;
|
||||
do {
|
||||
c = delta[deltaPtr++] & 0xff;
|
||||
resLen |= (c & 0x7f) << shift;
|
||||
resLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
|
||||
|
@ -243,7 +243,7 @@ public static String format(byte[] delta, boolean includeHeader) {
|
|||
int c, shift = 0;
|
||||
do {
|
||||
c = delta[deltaPtr++] & 0xff;
|
||||
baseLen |= (c & 0x7f) << shift;
|
||||
baseLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
|
||||
|
@ -251,7 +251,7 @@ public static String format(byte[] delta, boolean includeHeader) {
|
|||
shift = 0;
|
||||
do {
|
||||
c = delta[deltaPtr++] & 0xff;
|
||||
resLen |= (c & 0x7f) << shift;
|
||||
resLen |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ public DeltaStream(final InputStream deltaStream) throws IOException {
|
|||
int c, shift = 0;
|
||||
do {
|
||||
c = cmdbuf[cmdptr++] & 0xff;
|
||||
baseSize |= (c & 0x7f) << shift;
|
||||
baseSize |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
|
||||
|
@ -123,7 +123,7 @@ public DeltaStream(final InputStream deltaStream) throws IOException {
|
|||
shift = 0;
|
||||
do {
|
||||
c = cmdbuf[cmdptr++] & 0xff;
|
||||
resultSize |= (c & 0x7f) << shift;
|
||||
resultSize |= ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
} while ((c & 0x80) != 0);
|
||||
|
||||
|
@ -286,7 +286,7 @@ private int next() throws IOException {
|
|||
if ((cmd & 0x04) != 0)
|
||||
copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 16;
|
||||
if ((cmd & 0x08) != 0)
|
||||
copyOffset |= (cmdbuf[cmdptr++] & 0xff) << 24;
|
||||
copyOffset |= ((long) (cmdbuf[cmdptr++] & 0xff)) << 24;
|
||||
|
||||
copySize = 0;
|
||||
if ((cmd & 0x10) != 0)
|
||||
|
|
|
@ -681,7 +681,7 @@ protected ObjectTypeAndSize readObjectHeader(ObjectTypeAndSize info)
|
|||
while ((c & 0x80) != 0) {
|
||||
c = readFrom(Source.DATABASE);
|
||||
hdrBuf[hdrPtr++] = (byte) c;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
info.size = sz;
|
||||
|
@ -892,7 +892,7 @@ private void indexOneObject() throws IOException {
|
|||
while ((c & 0x80) != 0) {
|
||||
c = readFrom(Source.INPUT);
|
||||
hdrBuf[hdrPtr++] = (byte) c;
|
||||
sz += (c & 0x7f) << shift;
|
||||
sz += ((long) (c & 0x7f)) << shift;
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue