make overflow test on delta base offset work regardless of variable size
authorNicolas Pitre <nico@cam.org>
Mon, 9 Apr 2007 05:06:29 +0000 (01:06 -0400)
committerJunio C Hamano <junkio@cox.net>
Tue, 10 Apr 2007 19:48:14 +0000 (12:48 -0700)
This patch introduces the MSB() macro to obtain the desired number of
most significant bits from a given variable independently of the variable
type.

It is then used to better implement the overflow test on the OBJ_OFS_DELTA
base offset variable with the property of always working correctly
regardless of the type/size of that variable.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-pack-objects.c
builtin-unpack-objects.c
git-compat-util.h
index-pack.c
sha1_file.c

index 6bff17b130b6a4aa4cbde44164f4e56b5893975d..ee607a0d2c086d93d9d9f56453a4e79e397b4a20 100644 (file)
@@ -1014,7 +1014,7 @@ static void check_object(struct object_entry *entry)
                                ofs = c & 127;
                                while (c & 128) {
                                        ofs += 1;
-                                       if (!ofs || ofs & ~(~0UL >> 7))
+                                       if (!ofs || MSB(ofs, 7))
                                                die("delta base offset overflow in pack for %s",
                                                    sha1_to_hex(entry->sha1));
                                        c = buf[used_0++];
index 3956c5633448a5c29c60cad370ec7da6a8bfeb64..63f7db6831f7d5408ddf67d0f7f882c4a7b236cd 100644 (file)
@@ -209,7 +209,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
                base_offset = c & 127;
                while (c & 128) {
                        base_offset += 1;
-                       if (!base_offset || base_offset & ~(~0UL >> 7))
+                       if (!base_offset || MSB(base_offset, 7))
                                die("offset value overflow for delta base object");
                        pack = fill(1);
                        c = *pack;
index 139fc19108cab51eb23659868ef8600ff6b25795..bcfcb35ecf81d024147c75880428cdea370111ce 100644 (file)
 
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
 
+#ifdef __GNUC__
+#define TYPEOF(x) (__typeof__(x))
+#else
+#define TYPEOF(x)
+#endif
+
+#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
+
 #if !defined(__APPLE__) && !defined(__FreeBSD__)
 #define _XOPEN_SOURCE 600 /* glibc2 and AIX 5.3L need 500, OpenBSD needs 600 for S_ISLNK() */
 #define _XOPEN_SOURCE_EXTENDED 1 /* AIX 5.3L needs this */
index 3c768fbc631387b59bbbae3423b65b6a311a702b..0e54aa68448bab2497f16e57f34537f7ac884f37 100644 (file)
@@ -249,7 +249,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
                base_offset = c & 127;
                while (c & 128) {
                        base_offset += 1;
-                       if (!base_offset || base_offset & ~(~0UL >> 7))
+                       if (!base_offset || MSB(base_offset, 7))
                                bad_object(obj->offset, "offset value overflow for delta base object");
                        p = fill(1);
                        c = *p;
index d9ca69a916f9a9699deb7d9972a0c6f491755f9d..ebdd497badf21abd599ad50607c957c177f993f8 100644 (file)
@@ -1150,7 +1150,7 @@ static off_t get_delta_base(struct packed_git *p,
                base_offset = c & 127;
                while (c & 128) {
                        base_offset += 1;
-                       if (!base_offset || base_offset & ~(~0UL >> 7))
+                       if (!base_offset || MSB(base_offset, 7))
                                die("offset value overflow for delta base object");
                        c = base_info[used++];
                        base_offset = (base_offset << 7) + (c & 127);