]> source.dussan.org Git - jgit.git/commitdiff
Fix loading packed objects >2G 90/5490/2
authorShawn O. Pearce <spearce@spearce.org>
Wed, 28 Mar 2012 14:12:20 +0000 (10:12 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Wed, 28 Mar 2012 14:36:51 +0000 (10:36 -0400)
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

org.eclipse.jgit.storage.dht/src/org/eclipse/jgit/storage/dht/PackChunk.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/BinaryDelta.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaStream.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java

index 66d3d3386bbd7c246589699ea68fddc24748cda9..57d357e4cf8cd4543d33b00714a5e3d13a109452 100644 (file)
@@ -349,7 +349,7 @@ public final class PackChunk {
                                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 @@ public final class PackChunk {
                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 @@ public final class PackChunk {
                int shift = 4;
                while ((c & 0x80) != 0) {
                        c = dataBuf[ptr++] & 0xff;
-                       inflatedSize += (c & 0x7f) << shift;
+                       inflatedSize += ((long) (c & 0x7f)) << shift;
                        shift += 7;
                }
 
index f13b543f5ef986d5c85af9c5a44b34b4606acdd3..419e1e8729800f1dd2964b61b1869bad5e3ca887 100644 (file)
@@ -395,7 +395,7 @@ public final class DfsPackFile {
                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 @@ public final class DfsPackFile {
                                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 @@ public final class DfsPackFile {
                int p = 1;
                while ((c & 0x80) != 0) {
                        c = ib[p++] & 0xff;
-                       sz += (c & 0x7f) << shift;
+                       sz += ((long) (c & 0x7f)) << shift;
                        shift += 7;
                }
 
index 9965c0e526e20a86a2fcdb456b86ac5b773e3dbc..95ca4a41f05d8fe606ff23fc64c8de26c56da939 100644 (file)
@@ -345,7 +345,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
                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 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
                                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 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
                int p = 1;
                while ((c & 0x80) != 0) {
                        c = ib[p++] & 0xff;
-                       sz += (c & 0x7f) << shift;
+                       sz += ((long) (c & 0x7f)) << shift;
                        shift += 7;
                }
 
index e3be206825aafa806fcc240b50e1c20df4d18357..d059869451433cf8627649ef2d97d183a993c09f 100644 (file)
@@ -151,7 +151,7 @@ public class UnpackedObject {
                                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 @@ public class UnpackedObject {
                                int p = 1;
                                while ((c & 0x80) != 0) {
                                        c = hdr[p++] & 0xff;
-                                       size += (c & 0x7f) << shift;
+                                       size += ((long) (c & 0x7f)) << shift;
                                        shift += 7;
                                }
                                return size;
index 4c87e87f1b3e92a065cadb11f09538ff4e8c16e2..9e1cbd0e1660ce88a33d2488eced156b3bfd6520 100644 (file)
@@ -70,7 +70,7 @@ public class BinaryDelta {
                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 class BinaryDelta {
                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 class BinaryDelta {
                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 class BinaryDelta {
                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 class BinaryDelta {
                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 class BinaryDelta {
                shift = 0;
                do {
                        c = delta[deltaPtr++] & 0xff;
-                       resLen |= (c & 0x7f) << shift;
+                       resLen |= ((long) (c & 0x7f)) << shift;
                        shift += 7;
                } while ((c & 0x80) != 0);
 
index 3c3df90b73d227693559574904a721b21cf218d4..7275729f6343df4f0e8f969e87ca96504c0cbfda 100644 (file)
@@ -114,7 +114,7 @@ public abstract class DeltaStream extends InputStream {
                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 abstract class DeltaStream extends InputStream {
                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 @@ public abstract class DeltaStream extends InputStream {
                        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)
index 84de99d5882e44ac95aafb1d54d2ce25c315d213..584d9337e12e00bfa78c203f46a38d3afde05e4e 100644 (file)
@@ -681,7 +681,7 @@ public abstract class PackParser {
                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 @@ public abstract class PackParser {
                while ((c & 0x80) != 0) {
                        c = readFrom(Source.INPUT);
                        hdrBuf[hdrPtr++] = (byte) c;
-                       sz += (c & 0x7f) << shift;
+                       sz += ((long) (c & 0x7f)) << shift;
                        shift += 7;
                }