mirror of
https://github.com/git/git.git
synced 2024-11-18 02:23:52 +01:00
compat: helper for detecting unsigned overflow
The idiom (a + b < a) works fine for detecting that an unsigned integer has overflowed, but a more explicit unsigned_add_overflows(a, b) might be easier to read. Define such a macro, expanding roughly to ((a) < UINT_MAX - (b)). Because the expansion uses each argument only once outside of sizeof() expressions, it is safe to use with arguments that have side effects. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
a8e4a5943a
commit
1368f65002
@ -31,6 +31,9 @@
|
||||
#define maximum_signed_value_of_type(a) \
|
||||
(INTMAX_MAX >> (bitsizeof(intmax_t) - bitsizeof(a)))
|
||||
|
||||
#define maximum_unsigned_value_of_type(a) \
|
||||
(UINTMAX_MAX >> (bitsizeof(uintmax_t) - bitsizeof(a)))
|
||||
|
||||
/*
|
||||
* Signed integer overflow is undefined in C, so here's a helper macro
|
||||
* to detect if the sum of two integers will overflow.
|
||||
@ -40,6 +43,9 @@
|
||||
#define signed_add_overflows(a, b) \
|
||||
((b) > maximum_signed_value_of_type(a) - (a))
|
||||
|
||||
#define unsigned_add_overflows(a, b) \
|
||||
((b) > maximum_unsigned_value_of_type(a) - (a))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define TYPEOF(x) (__typeof__(x))
|
||||
#else
|
||||
|
@ -48,7 +48,7 @@ void *patch_delta(const void *src_buf, unsigned long src_size,
|
||||
if (cmd & 0x20) cp_size |= (*data++ << 8);
|
||||
if (cmd & 0x40) cp_size |= (*data++ << 16);
|
||||
if (cp_size == 0) cp_size = 0x10000;
|
||||
if (cp_off + cp_size < cp_size ||
|
||||
if (unsigned_add_overflows(cp_off, cp_size) ||
|
||||
cp_off + cp_size > src_size ||
|
||||
cp_size > size)
|
||||
break;
|
||||
|
5
strbuf.c
5
strbuf.c
@ -63,7 +63,8 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
|
||||
|
||||
void strbuf_grow(struct strbuf *sb, size_t extra)
|
||||
{
|
||||
if (sb->len + extra + 1 <= sb->len)
|
||||
if (unsigned_add_overflows(extra, 1) ||
|
||||
unsigned_add_overflows(sb->len, extra + 1))
|
||||
die("you want to use way too much memory");
|
||||
if (!sb->alloc)
|
||||
sb->buf = NULL;
|
||||
@ -152,7 +153,7 @@ int strbuf_cmp(const struct strbuf *a, const struct strbuf *b)
|
||||
void strbuf_splice(struct strbuf *sb, size_t pos, size_t len,
|
||||
const void *data, size_t dlen)
|
||||
{
|
||||
if (pos + len < pos)
|
||||
if (unsigned_add_overflows(pos, len))
|
||||
die("you want to use way too much memory");
|
||||
if (pos > sb->len)
|
||||
die("`pos' is too far after the end of the buffer");
|
||||
|
@ -53,7 +53,7 @@ void *xmalloc(size_t size)
|
||||
void *xmallocz(size_t size)
|
||||
{
|
||||
void *ret;
|
||||
if (size + 1 < size)
|
||||
if (unsigned_add_overflows(size, 1))
|
||||
die("Data too large to fit into virtual memory space.");
|
||||
ret = xmalloc(size + 1);
|
||||
((char*)ret)[size] = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user