aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2007-04-09 01:06:29 -0400
committerJunio C Hamano <junkio@cox.net>2007-04-10 12:48:14 -0700
commit8723f216263ba4a0f06be7b93fada863c0931e09 (patch)
tree6d357724c891ce009a8c7ae1a0a4083bc39ff1f5
parent57059091fad25427bce9b3d47e073ce0518d164b (diff)
downloadgit-8723f216263ba4a0f06be7b93fada863c0931e09.tar.gz
git-8723f216263ba4a0f06be7b93fada863c0931e09.tar.xz
make overflow test on delta base offset work regardless of variable size
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>
-rw-r--r--builtin-pack-objects.c2
-rw-r--r--builtin-unpack-objects.c2
-rw-r--r--git-compat-util.h8
-rw-r--r--index-pack.c2
-rw-r--r--sha1_file.c2
5 files changed, 12 insertions, 4 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 6bff17b13..ee607a0d2 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -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++];
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 3956c5633..63f7db683 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -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;
diff --git a/git-compat-util.h b/git-compat-util.h
index 139fc1910..bcfcb35ec 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -13,6 +13,14 @@
#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 */
diff --git a/index-pack.c b/index-pack.c
index 3c768fbc6..0e54aa684 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -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;
diff --git a/sha1_file.c b/sha1_file.c
index d9ca69a91..ebdd497ba 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -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);