Skip to content

Commit c03c831

Browse files
kusmagitster
authored andcommitted
do not depend on signed integer overflow
Signed integer overflow is not defined in C, so do not depend on it. This fixes a problem with GCC 4.4.0 and -O3 where the optimizer would consider "consumed_bytes > consumed_bytes + bytes" as a constant expression, and never execute the die()-call. Signed-off-by: Erik Faye-Lund <[email protected]> Acked-by: Nicolas Pitre <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b90d9b8 commit c03c831

File tree

4 files changed

+15
-3
lines changed

4 files changed

+15
-3
lines changed

builtin/index-pack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static void use(int bytes)
161161
input_offset += bytes;
162162

163163
/* make sure off_t is sufficiently large not to wrap */
164-
if (consumed_bytes > consumed_bytes + bytes)
164+
if (signed_add_overflows(consumed_bytes, bytes))
165165
die("pack too large for current definition of off_t");
166166
consumed_bytes += bytes;
167167
}

builtin/pack-objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ static int write_one(struct sha1file *f,
431431
written_list[nr_written++] = &e->idx;
432432

433433
/* make sure off_t is sufficiently large not to wrap */
434-
if (*offset > *offset + size)
434+
if (signed_add_overflows(*offset, size))
435435
die("pack too large for current definition of off_t");
436436
*offset += size;
437437
return 1;

builtin/unpack-objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static void use(int bytes)
8383
offset += bytes;
8484

8585
/* make sure off_t is sufficiently large not to wrap */
86-
if (consumed_bytes > consumed_bytes + bytes)
86+
if (signed_add_overflows(consumed_bytes, bytes))
8787
die("pack too large for current definition of off_t");
8888
consumed_bytes += bytes;
8989
}

git-compat-util.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
2929
#define bitsizeof(x) (CHAR_BIT * sizeof(x))
3030

31+
#define maximum_signed_value_of_type(a) \
32+
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
33+
34+
/*
35+
* Signed integer overflow is undefined in C, so here's a helper macro
36+
* to detect if the sum of two integers will overflow.
37+
*
38+
* Requires: a >= 0, typeof(a) equals typeof(b)
39+
*/
40+
#define signed_add_overflows(a, b) \
41+
((b) > maximum_signed_value_of_type(a) - (a))
42+
3143
#ifdef __GNUC__
3244
#define TYPEOF(x) (__typeof__(x))
3345
#else

0 commit comments

Comments
 (0)