summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-02-12 12:19:37 -0500
committerEdward Thomson <ethomson@microsoft.com>2015-02-13 09:27:33 -0500
commitf1453c59b2afb9dab43281bfe9f1ba34cf6e0d02 (patch)
treecb189e211547042080f35227b7e4d3f9b0c8ac2a
parent650e45f69124bd8b53ecefddeb214a82538ab2c1 (diff)
downloadlibgit2-f1453c59b2afb9dab43281bfe9f1ba34cf6e0d02.tar.gz
Make our overflow check look more like gcc/clang's
Make our overflow checking look more like gcc and clang's, so that we can substitute it out with the compiler instrinsics on platforms that support it. This means dropping the ability to pass `NULL` as an out parameter. As a result, the macros also get updated to reflect this as well.
-rw-r--r--src/array.h5
-rw-r--r--src/blame_git.c10
-rw-r--r--src/buf_text.c22
-rw-r--r--src/buffer.c143
-rw-r--r--src/common.h20
-rw-r--r--src/config_file.c24
-rw-r--r--src/delta-apply.c6
-rw-r--r--src/delta.c17
-rw-r--r--src/diff.c5
-rw-r--r--src/diff_driver.c9
-rw-r--r--src/diff_patch.c13
-rw-r--r--src/diff_tform.c5
-rw-r--r--src/filebuf.c12
-rw-r--r--src/fileops.c18
-rw-r--r--src/filter.c19
-rw-r--r--src/index.c17
-rw-r--r--src/integer.h28
-rw-r--r--src/iterator.c7
-rw-r--r--src/merge.c9
-rw-r--r--src/odb.c15
-rw-r--r--src/odb_loose.c42
-rw-r--r--src/odb_mempack.c5
-rw-r--r--src/pack-objects.c7
-rw-r--r--src/pack.c21
-rw-r--r--src/path.c43
-rw-r--r--src/pool.c15
-rw-r--r--src/refs.c22
-rw-r--r--src/sortedcache.c8
-rw-r--r--src/tag.c10
-rw-r--r--src/transports/cred.c8
-rw-r--r--src/transports/smart_pkt.c50
-rw-r--r--src/tree.c18
-rw-r--r--src/util.h19
-rw-r--r--src/vector.c3
-rw-r--r--src/win32/dir.c8
-rw-r--r--tests/core/errors.c16
36 files changed, 352 insertions, 347 deletions
diff --git a/src/array.h b/src/array.h
index 7c4dbdbc1..7cd9b7153 100644
--- a/src/array.h
+++ b/src/array.h
@@ -51,10 +51,9 @@ GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
if (a->size < 8) {
new_size = 8;
} else {
- if (GIT_ALLOC_OVERFLOW_MULTIPLY(a->size, 3 / 2))
+ if (GIT_MULTIPLY_SIZET_OVERFLOW(&new_size, a->size, 3))
goto on_oom;
-
- new_size = a->size * 3 / 2;
+ new_size /= 2;
}
if ((new_array = git__reallocarray(a->ptr, new_size, item_size)) == NULL)
diff --git a/src/blame_git.c b/src/blame_git.c
index 05aef5d99..e863efe2e 100644
--- a/src/blame_git.c
+++ b/src/blame_git.c
@@ -36,14 +36,14 @@ static void origin_decref(git_blame__origin *o)
static int make_origin(git_blame__origin **out, git_commit *commit, const char *path)
{
git_blame__origin *o;
- size_t path_len = strlen(path);
+ size_t path_len = strlen(path), alloc_len;
int error = 0;
- GITERR_CHECK_ALLOC_ADD(sizeof(*o), path_len);
- GITERR_CHECK_ALLOC_ADD(sizeof(*o) + path_len, 1);
-
- o = git__calloc(1, sizeof(*o) + path_len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*o), path_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+ o = git__calloc(1, alloc_len);
GITERR_CHECK_ALLOC(o);
+
o->commit = commit;
o->refcnt = 1;
strcpy(o->path, path);
diff --git a/src/buf_text.c b/src/buf_text.c
index 08b86f4cc..864e39cab 100644
--- a/src/buf_text.c
+++ b/src/buf_text.c
@@ -13,7 +13,7 @@ int git_buf_text_puts_escaped(
const char *esc_with)
{
const char *scan;
- size_t total = 0, esc_len = strlen(esc_with), count;
+ size_t total = 0, esc_len = strlen(esc_with), count, alloclen;
if (!string)
return 0;
@@ -29,8 +29,8 @@ int git_buf_text_puts_escaped(
scan += count;
}
- GITERR_CHECK_ALLOC_ADD(total, 1);
- if (git_buf_grow_by(buf, total + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloclen, total, 1);
+ if (git_buf_grow_by(buf, alloclen) < 0)
return -1;
for (scan = string; *scan; ) {
@@ -66,6 +66,7 @@ int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src)
const char *scan = src->ptr;
const char *scan_end = src->ptr + src->size;
const char *next = memchr(scan, '\r', src->size);
+ size_t new_size;
char *out;
assert(tgt != src);
@@ -74,8 +75,8 @@ int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src)
return git_buf_set(tgt, src->ptr, src->size);
/* reduce reallocs while in the loop */
- GITERR_CHECK_ALLOC_ADD(src->size, 1);
- if (git_buf_grow(tgt, src->size + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&new_size, src->size, 1);
+ if (git_buf_grow(tgt, new_size) < 0)
return -1;
out = tgt->ptr;
@@ -113,6 +114,7 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
const char *end = start + src->size;
const char *scan = start;
const char *next = memchr(scan, '\n', src->size);
+ size_t alloclen;
assert(tgt != src);
@@ -120,9 +122,9 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
return git_buf_set(tgt, src->ptr, src->size);
/* attempt to reduce reallocs while in the loop */
- GITERR_CHECK_ALLOC_ADD(src->size, src->size >> 4);
- GITERR_CHECK_ALLOC_ADD(src->size + (src->size >> 4), 1);
- if (git_buf_grow(tgt, src->size + (src->size >> 4) + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloclen, src->size, src->size >> 4);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+ if (git_buf_grow(tgt, alloclen) < 0)
return -1;
tgt->size = 0;
@@ -135,8 +137,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
return GIT_PASSTHROUGH;
}
- GITERR_CHECK_ALLOC_ADD(copylen, 3);
- if (git_buf_grow_by(tgt, copylen + 3) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloclen, copylen, 3);
+ if (git_buf_grow_by(tgt, alloclen) < 0)
return -1;
if (next > scan) {
diff --git a/src/buffer.c b/src/buffer.c
index 0d0314439..3deb0329c 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -103,13 +103,14 @@ int git_buf_grow(git_buf *buffer, size_t target_size)
int git_buf_grow_by(git_buf *buffer, size_t additional_size)
{
- if (GIT_ALLOC_OVERFLOW_ADD(buffer->size, additional_size)) {
+ size_t newsize;
+
+ if (GIT_ADD_SIZET_OVERFLOW(&newsize, buffer->size, additional_size)) {
buffer->ptr = git_buf__oom;
return -1;
}
- return git_buf_try_grow(
- buffer, buffer->size + additional_size, true, true);
+ return git_buf_try_grow(buffer, newsize, true, true);
}
void git_buf_free(git_buf *buf)
@@ -146,12 +147,14 @@ void git_buf_clear(git_buf *buf)
int git_buf_set(git_buf *buf, const void *data, size_t len)
{
+ size_t alloclen;
+
if (len == 0 || data == NULL) {
git_buf_clear(buf);
} else {
if (data != buf->ptr) {
- GITERR_CHECK_ALLOC_ADD(len, 1);
- ENSURE_SIZE(buf, len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+ ENSURE_SIZE(buf, alloclen);
memmove(buf->ptr, data, len);
}
@@ -180,8 +183,9 @@ int git_buf_sets(git_buf *buf, const char *string)
int git_buf_putc(git_buf *buf, char c)
{
- GITERR_CHECK_ALLOC_ADD(buf->size, 2);
- ENSURE_SIZE(buf, buf->size + 2);
+ size_t new_size;
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, 2);
+ ENSURE_SIZE(buf, new_size);
buf->ptr[buf->size++] = c;
buf->ptr[buf->size] = '\0';
return 0;
@@ -189,9 +193,10 @@ int git_buf_putc(git_buf *buf, char c)
int git_buf_putcn(git_buf *buf, char c, size_t len)
{
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+ size_t new_size;
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
memset(buf->ptr + buf->size, c, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
@@ -201,10 +206,13 @@ int git_buf_putcn(git_buf *buf, char c, size_t len)
int git_buf_put(git_buf *buf, const char *data, size_t len)
{
if (len) {
+ size_t new_size;
+
assert(data);
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
memmove(buf->ptr + buf->size, data, len);
buf->size += len;
buf->ptr[buf->size] = '\0';
@@ -226,12 +234,13 @@ int git_buf_encode_base64(git_buf *buf, const char *data, size_t len)
size_t extra = len % 3;
uint8_t *write, a, b, c;
const uint8_t *read = (const uint8_t *)data;
- size_t blocks = (len / 3) + !!extra;
+ size_t blocks = (len / 3) + !!extra, alloclen;
+
+ GITERR_CHECK_ALLOC_ADD(&blocks, blocks, 1);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 4);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
- GITERR_CHECK_ALLOC_MULTIPLY(blocks, 4);
- GITERR_CHECK_ALLOC_ADD(buf->size, 4 * blocks);
- GITERR_CHECK_ALLOC_ADD(buf->size + 4 * blocks, 1);
- ENSURE_SIZE(buf, buf->size + 4 * blocks + 1);
+ ENSURE_SIZE(buf, alloclen);
write = (uint8_t *)&buf->ptr[buf->size];
/* convert each run of 3 bytes into 4 output bytes */
@@ -282,12 +291,12 @@ int git_buf_decode_base64(git_buf *buf, const char *base64, size_t len)
{
size_t i;
int8_t a, b, c, d;
- size_t orig_size = buf->size;
+ size_t orig_size = buf->size, new_size;
assert(len % 4 == 0);
- GITERR_CHECK_ALLOC_ADD(buf->size, len / 4 * 3);
- GITERR_CHECK_ALLOC_ADD(buf->size + (len / 4 * 3), 1);
- ENSURE_SIZE(buf, buf->size + (len / 4 * 3) + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, (len / 4 * 3), buf->size);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
for (i = 0; i < len; i += 4) {
if ((a = BASE64_DECODE_VALUE(base64[i])) < 0 ||
@@ -315,12 +324,13 @@ static const char b85str[] =
int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
{
- size_t blocks = (len / 4) + !!(len % 4);
+ size_t blocks = (len / 4) + !!(len % 4), alloclen;
- GITERR_CHECK_ALLOC_MULTIPLY(blocks, 5);
- GITERR_CHECK_ALLOC_ADD(buf->size, 5 * blocks);
- GITERR_CHECK_ALLOC_ADD(buf->size + 5 * blocks, 1);
- ENSURE_SIZE(buf, buf->size + blocks * 5 + 1);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 5);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+
+ ENSURE_SIZE(buf, alloclen);
while (len) {
uint32_t acc = 0;
@@ -353,15 +363,11 @@ int git_buf_encode_base85(git_buf *buf, const char *data, size_t len)
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
{
- size_t expected_size = strlen(format);
+ size_t expected_size, new_size;
int len;
- GITERR_CHECK_ALLOC_MULTIPLY(expected_size, 2);
- expected_size *= 2;
-
- GITERR_CHECK_ALLOC_ADD(expected_size, buf->size);
- expected_size += buf->size;
-
+ GITERR_CHECK_ALLOC_MULTIPLY(&expected_size, strlen(format), 2);
+ GITERR_CHECK_ALLOC_ADD(&expected_size, expected_size, buf->size);
ENSURE_SIZE(buf, expected_size);
while (1) {
@@ -387,9 +393,9 @@ int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
break;
}
- GITERR_CHECK_ALLOC_ADD(buf->size, len);
- GITERR_CHECK_ALLOC_ADD(buf->size + len, 1);
- ENSURE_SIZE(buf, buf->size + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len);
+ GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1);
+ ENSURE_SIZE(buf, new_size);
}
return 0;
@@ -516,9 +522,11 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
continue;
segment_len = strlen(segment);
- total_size += segment_len;
+
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, segment_len);
+
if (segment_len == 0 || segment[segment_len - 1] != separator)
- ++total_size; /* space for separator */
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
}
va_end(ap);
@@ -526,8 +534,8 @@ int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
if (total_size == 0)
return 0;
- GITERR_CHECK_ALLOC_ADD(total_size, 1);
- if (git_buf_grow_by(buf, total_size + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
+ if (git_buf_grow_by(buf, total_size) < 0)
return -1;
out = buf->ptr + buf->size;
@@ -588,6 +596,7 @@ int git_buf_join(
{
size_t strlen_a = str_a ? strlen(str_a) : 0;
size_t strlen_b = strlen(str_b);
+ size_t alloc_len;
int need_sep = 0;
ssize_t offset_a = -1;
@@ -605,10 +614,10 @@ int git_buf_join(
if (str_a >= buf->ptr && str_a < buf->ptr + buf->size)
offset_a = str_a - buf->ptr;
- GITERR_CHECK_ALLOC_ADD(strlen_a, strlen_b);
- GITERR_CHECK_ALLOC_ADD(strlen_a + strlen_b, need_sep);
- GITERR_CHECK_ALLOC_ADD(strlen_a + strlen_b + need_sep, 1);
- if (git_buf_grow(buf, strlen_a + strlen_b + need_sep + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, strlen_a, strlen_b);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, need_sep);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+ if (git_buf_grow(buf, alloc_len) < 0)
return -1;
assert(buf->ptr);
@@ -636,7 +645,10 @@ int git_buf_join3(
const char *str_b,
const char *str_c)
{
- size_t len_a = strlen(str_a), len_b = strlen(str_b), len_c = strlen(str_c);
+ size_t len_a = strlen(str_a),
+ len_b = strlen(str_b),
+ len_c = strlen(str_c),
+ len_total;
int sep_a = 0, sep_b = 0;
char *tgt;
@@ -656,12 +668,12 @@ int git_buf_join3(
sep_b = (str_b[len_b - 1] != separator);
}
- GITERR_CHECK_ALLOC_ADD(len_a, sep_a);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a, len_b);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b, sep_b);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b + sep_b, len_c);
- GITERR_CHECK_ALLOC_ADD(len_a + sep_a + len_b + sep_b + len_c, 1);
- if (git_buf_grow(buf, len_a + sep_a + len_b + sep_b + len_c + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_a, sep_a);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_b);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, sep_b);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, len_c);
+ GITERR_CHECK_ALLOC_ADD(&len_total, len_total, 1);
+ if (git_buf_grow(buf, len_total) < 0)
return -1;
tgt = buf->ptr;
@@ -714,28 +726,25 @@ int git_buf_splice(
const char *data,
size_t nb_to_insert)
{
- size_t new_size;
+ char *splice_loc;
+ size_t new_size, alloc_size;
- assert(buf &&
- where <= git_buf_len(buf) &&
- where + nb_to_remove <= git_buf_len(buf));
+ assert(buf && where <= buf->size && nb_to_remove <= buf->size - where);
+
+ splice_loc = buf->ptr + where;
/* Ported from git.git
* https://github.com/git/git/blob/16eed7c/strbuf.c#L159-176
*/
- new_size = buf->size - nb_to_remove;
-
- GITERR_CHECK_ALLOC_ADD(new_size, nb_to_insert);
- new_size += nb_to_insert;
-
- GITERR_CHECK_ALLOC_ADD(new_size, 1);
- ENSURE_SIZE(buf, new_size + 1);
+ GITERR_CHECK_ALLOC_ADD(&new_size, (buf->size - nb_to_remove), nb_to_insert);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, new_size, 1);
+ ENSURE_SIZE(buf, alloc_size);
- memmove(buf->ptr + where + nb_to_insert,
- buf->ptr + where + nb_to_remove,
- buf->size - where - nb_to_remove);
+ memmove(splice_loc + nb_to_insert,
+ splice_loc + nb_to_remove,
+ buf->size - where - nb_to_remove);
- memcpy(buf->ptr + where, data, nb_to_insert);
+ memcpy(splice_loc, data, nb_to_insert);
buf->size = new_size;
buf->ptr[buf->size] = '\0';
diff --git a/src/common.h b/src/common.h
index 530e320e2..8d1e89064 100644
--- a/src/common.h
+++ b/src/common.h
@@ -176,21 +176,21 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0)
-/** Check for integer overflow from addition or multiplication */
-#define GIT_ALLOC_OVERFLOW_ADD(one, two) \
- (!git__add_sizet_overflow(NULL, (one), (two)) ? (giterr_set_oom(), 1) : 0)
+/** Check for additive overflow, setting an error if would occur. */
+#define GIT_ADD_SIZET_OVERFLOW(out, one, two) \
+ (git__add_sizet_overflow(out, one, two) ? (giterr_set_oom(), 1) : 0)
-/** Check for integer overflow from multiplication */
-#define GIT_ALLOC_OVERFLOW_MULTIPLY(one, two) \
- (!git__multiply_sizet_overflow(NULL, (one), (two)) ? (giterr_set_oom(), 1) : 0)
+/** Check for additive overflow, setting an error if would occur. */
+#define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \
+ (git__multiply_sizet_overflow(out, nelem, elsize) ? (giterr_set_oom(), 1) : 0)
/** Check for additive overflow, failing if it would occur. */
-#define GITERR_CHECK_ALLOC_ADD(one, two) \
- if (GIT_ALLOC_OVERFLOW_ADD(one, two)) { return -1; }
+#define GITERR_CHECK_ALLOC_ADD(out, one, two) \
+ if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; }
/** Check for multiplicative overflow, failing if it would occur. */
-#define GITERR_CHECK_ALLOC_MULTIPLY(nelem, elsize) \
- if (GIT_ALLOC_OVERFLOW_MULTIPLY(nelem, elsize)) { return -1; }
+#define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
+ if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
/* NOTE: other giterr functions are in the public errors.h header file */
diff --git a/src/config_file.c b/src/config_file.c
index 39e9ff841..8ccbe64cc 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -885,7 +885,7 @@ static char *reader_readline(struct reader *reader, bool skip_whitespace)
{
char *line = NULL;
char *line_src, *line_end;
- size_t line_len;
+ size_t line_len, alloc_len;
line_src = reader->read_ptr;
@@ -903,8 +903,8 @@ static char *reader_readline(struct reader *reader, bool skip_whitespace)
line_len = line_end - line_src;
- if (GIT_ALLOC_OVERFLOW_ADD(line_len, 1) ||
- (line = git__malloc(line_len + 1)) == NULL) {
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, line_len, 1) ||
+ (line = git__malloc(alloc_len)) == NULL) {
return NULL;
}
@@ -959,7 +959,7 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
int c, rpos;
char *first_quote, *last_quote;
git_buf buf = GIT_BUF_INIT;
- size_t quoted_len, base_name_len = strlen(base_name);
+ size_t quoted_len, alloc_len, base_name_len = strlen(base_name);
/*
* base_name is what came before the space. We should be at the
@@ -976,10 +976,10 @@ static int parse_section_header_ext(struct reader *reader, const char *line, con
return -1;
}
- GITERR_CHECK_ALLOC_ADD(base_name_len, quoted_len);
- GITERR_CHECK_ALLOC_ADD(base_name_len + quoted_len, 2);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, base_name_len, quoted_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
- git_buf_grow(&buf, base_name_len + quoted_len + 2);
+ git_buf_grow(&buf, alloc_len);
git_buf_printf(&buf, "%s.", base_name);
rpos = 0;
@@ -1050,9 +1050,7 @@ static int parse_section_header(struct reader *reader, char **section_out)
return -1;
}
- line_len = (size_t)(name_end - line);
-
- GITERR_CHECK_ALLOC_ADD(line_len, 1);
+ GITERR_CHECK_ALLOC_ADD(&line_len, (size_t)(name_end - line), 1);
name = git__malloc(line_len);
GITERR_CHECK_ALLOC(name);
@@ -1615,10 +1613,10 @@ static char *escape_value(const char *ptr)
static char *fixup_line(const char *ptr, int quote_count)
{
char *str, *out, *esc;
- size_t ptr_len = strlen(ptr);
+ size_t ptr_len = strlen(ptr), alloc_len;
- if (GIT_ALLOC_OVERFLOW_ADD(ptr_len, 1) ||
- (str = git__malloc(ptr_len + 1)) == NULL) {
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_len, ptr_len, 1) ||
+ (str = git__malloc(alloc_len)) == NULL) {
return NULL;
}
diff --git a/src/delta-apply.c b/src/delta-apply.c
index e46c9631c..89745faa0 100644
--- a/src/delta-apply.c
+++ b/src/delta-apply.c
@@ -57,7 +57,7 @@ int git__delta_apply(
size_t delta_len)
{
const unsigned char *delta_end = delta + delta_len;
- size_t base_sz, res_sz;
+ size_t base_sz, res_sz, alloc_sz;
unsigned char *res_dp;
/* Check that the base size matches the data we were given;
@@ -74,8 +74,8 @@ int git__delta_apply(
return -1;
}
- GITERR_CHECK_ALLOC_ADD(res_sz, 1);
- res_dp = git__malloc(res_sz + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_sz, res_sz, 1);
+ res_dp = git__malloc(alloc_sz);
GITERR_CHECK_ALLOC(res_dp);
res_dp[res_sz] = '\0';
diff --git a/src/delta.c b/src/delta.c
index 242f3abe3..d72d820d8 100644
--- a/src/delta.c
+++ b/src/delta.c
@@ -122,20 +122,13 @@ struct git_delta_index {
static int lookup_index_alloc(
void **out, unsigned long *out_len, size_t entries, size_t hash_count)
{
- size_t entries_len, hash_len,
- index_len = sizeof(struct git_delta_index);
+ size_t entries_len, hash_len, index_len;
- GITERR_CHECK_ALLOC_MULTIPLY(entries, sizeof(struct index_entry));
- entries_len = entries * sizeof(struct index_entry);
+ GITERR_CHECK_ALLOC_MULTIPLY(&entries_len, entries, sizeof(struct index_entry));
+ GITERR_CHECK_ALLOC_MULTIPLY(&hash_len, hash_count, sizeof(struct index_entry *));
- GITERR_CHECK_ALLOC_ADD(index_len, entries_len);
- index_len += entries_len;
-
- GITERR_CHECK_ALLOC_MULTIPLY(hash_count, sizeof(struct index_entry *));
- hash_len = hash_count * sizeof(struct index_entry *);
-
- GITERR_CHECK_ALLOC_ADD(index_len, hash_len);
- index_len += hash_len;
+ GITERR_CHECK_ALLOC_ADD(&index_len, sizeof(struct git_delta_index), entries_len);
+ GITERR_CHECK_ALLOC_ADD(&index_len, index_len, hash_len);
if (!git__is_ulong(index_len)) {
giterr_set(GITERR_NOMEMORY, "Overly large delta");
diff --git a/src/diff.c b/src/diff.c
index 75e9ae9a3..07eae03e7 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -1527,6 +1527,7 @@ int git_diff_format_email(
char *summary = NULL, *loc = NULL;
bool ignore_marker;
unsigned int format_flags = 0;
+ size_t allocsize;
int error;
assert(out && diff && opts);
@@ -1558,8 +1559,8 @@ int git_diff_format_email(
goto on_error;
}
- GITERR_CHECK_ALLOC_ADD(offset, 1);
- summary = git__calloc(offset + 1, sizeof(char));
+ GITERR_CHECK_ALLOC_ADD(&allocsize, offset, 1);
+ summary = git__calloc(allocsize, sizeof(char));
GITERR_CHECK_ALLOC(summary);
strncpy(summary, opts->summary, offset);
diff --git a/src/diff_driver.c b/src/diff_driver.c
index 67f1c591d..e4d9a0699 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -163,12 +163,13 @@ static int diff_driver_alloc(
{
git_diff_driver *driver;
size_t driverlen = sizeof(git_diff_driver),
- namelen = strlen(name);
+ namelen = strlen(name),
+ alloclen;
- GITERR_CHECK_ALLOC_ADD(driverlen, namelen);
- GITERR_CHECK_ALLOC_ADD(driverlen + namelen, 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, driverlen, namelen);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
- driver = git__calloc(1, driverlen + namelen + 1);
+ driver = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(driver);
memcpy(driver->name, name, namelen);
diff --git a/src/diff_patch.c b/src/diff_patch.c
index f5eecae66..1c4c0e8b8 100644
--- a/src/diff_patch.c
+++ b/src/diff_patch.c
@@ -388,16 +388,11 @@ static int diff_patch_with_delta_alloc(
diff_patch_with_delta *pd;
size_t old_len = *old_path ? strlen(*old_path) : 0;
size_t new_len = *new_path ? strlen(*new_path) : 0;
- size_t alloc_len = sizeof(*pd);
+ size_t alloc_len;
- GITERR_CHECK_ALLOC_ADD(alloc_len, old_len);
- alloc_len += old_len;
-
- GITERR_CHECK_ALLOC_ADD(alloc_len, new_len);
- alloc_len += new_len;
-
- GITERR_CHECK_ALLOC_ADD(alloc_len, 2);
- alloc_len += 2;
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*pd), old_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, new_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
*out = pd = git__calloc(1, alloc_len);
GITERR_CHECK_ALLOC(pd);
diff --git a/src/diff_tform.c b/src/diff_tform.c
index cad1356c3..8ee568cf4 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -811,6 +811,7 @@ int git_diff_find_similar(
size_t num_deltas, num_srcs = 0, num_tgts = 0;
size_t tried_srcs = 0, tried_tgts = 0;
size_t num_rewrites = 0, num_updates = 0, num_bumped = 0;
+ size_t sigcache_size;
void **sigcache = NULL; /* cache of similarity metric file signatures */
diff_find_match *tgt2src = NULL;
diff_find_match *src2tgt = NULL;
@@ -831,8 +832,8 @@ int git_diff_find_similar(
if ((opts.flags & GIT_DIFF_FIND_ALL) == 0)
goto cleanup;
- GITERR_CHECK_ALLOC_MULTIPLY(num_deltas, 2);
- sigcache = git__calloc(num_deltas * 2, sizeof(void *));
+ GITERR_CHECK_ALLOC_MULTIPLY(&sigcache_size, num_deltas, 2);
+ sigcache = git__calloc(sigcache_size, sizeof(void *));
GITERR_CHECK_ALLOC(sigcache);
/* Label rename sources and targets
diff --git a/src/filebuf.c b/src/filebuf.c
index 94f2bec32..932b8c7d1 100644
--- a/src/filebuf.c
+++ b/src/filebuf.c
@@ -194,7 +194,7 @@ static int write_deflate(git_filebuf *file, void *source, size_t len)
int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode)
{
int compression, error = -1;
- size_t path_len;
+ size_t path_len, alloc_len;
/* opening an already open buffer is a programming error;
* assert that this never happens instead of returning
@@ -271,8 +271,8 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode
GITERR_CHECK_ALLOC(file->path_original);
/* create the locking path by appending ".lock" to the original */
- GITERR_CHECK_ALLOC_ADD(path_len, GIT_FILELOCK_EXTLENGTH);
- file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, path_len, GIT_FILELOCK_EXTLENGTH);
+ file->path_lock = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(file->path_lock);
memcpy(file->path_lock, file->path_original, path_len);
@@ -408,7 +408,7 @@ int git_filebuf_reserve(git_filebuf *file, void **buffer, size_t len)
int git_filebuf_printf(git_filebuf *file, const char *format, ...)
{
va_list arglist;
- size_t space_left, len;
+ size_t space_left, len, alloclen;
int written, res;
char *tmp_buffer;
@@ -439,8 +439,8 @@ int git_filebuf_printf(git_filebuf *file, const char *format, ...)
} while (len + 1 <= space_left);
- if (GIT_ALLOC_OVERFLOW_ADD(len, 1) ||
- !(tmp_buffer = git__malloc(len + 1))) {
+ if (GIT_ADD_SIZET_OVERFLOW(&alloclen, len, 1) ||
+ !(tmp_buffer = git__malloc(alloclen))) {
file->last_error = BUFERR_MEM;
return -1;
}
diff --git a/src/fileops.c b/src/fileops.c
index 420ed70a2..09a8f5d4a 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -124,6 +124,7 @@ mode_t git_futils_canonical_mode(mode_t raw_mode)
int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
{
ssize_t read_size = 0;
+ size_t alloc_len;
git_buf_clear(buf);
@@ -132,8 +133,8 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
return -1;
}
- GITERR_CHECK_ALLOC_ADD(len, 1);
- if (git_buf_grow(buf, len + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, len, 1);
+ if (git_buf_grow(buf, alloc_len) < 0)
return -1;
/* p_read loops internally to read len bytes */
@@ -455,7 +456,13 @@ int git_futils_mkdir_ext(
}
if (opts->dir_map && opts->pool) {
- char *cache_path = git_pool_malloc(opts->pool, make_path.size + 1);
+ char *cache_path;
+ size_t alloc_size;
+
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, make_path.size, 1);
+ if (!git__is_uint32(alloc_size))
+ return -1;
+ cache_path = git_pool_malloc(opts->pool, (uint32_t)alloc_size);
GITERR_CHECK_ALLOC(cache_path);
memcpy(cache_path, make_path.ptr, make_path.size + 1);
@@ -715,9 +722,10 @@ static int cp_link(const char *from, const char *to, size_t link_size)
int error = 0;
ssize_t read_len;
char *link_data;
+ size_t alloc_size;
- GITERR_CHECK_ALLOC_ADD(link_size, 1);
- link_data = git__malloc(link_size + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, link_size, 1);
+ link_data = git__malloc(alloc_size);
GITERR_CHECK_ALLOC(link_data);
read_len = p_readlink(from, link_data, link_size);
diff --git a/src/filter.c b/src/filter.c
index d5c669f01..7b54a76c0 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -245,14 +245,9 @@ int git_filter_register(
if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0)
return -1;
- GITERR_CHECK_ALLOC_MULTIPLY(nattr, 2);
- alloc_len = nattr * 2;
-
- GITERR_CHECK_ALLOC_MULTIPLY(alloc_len, sizeof(char *));
- alloc_len *= sizeof(char *);
-
- GITERR_CHECK_ALLOC_ADD(alloc_len, sizeof(git_filter_def));
- alloc_len += sizeof(git_filter_def);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, nattr, 2);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, alloc_len, sizeof(char *));
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, sizeof(git_filter_def));
fdef = git__calloc(1, alloc_len);
GITERR_CHECK_ALLOC(fdef);
@@ -385,12 +380,12 @@ static int filter_list_new(
git_filter_list **out, const git_filter_source *src)
{
git_filter_list *fl = NULL;
- size_t pathlen = src->path ? strlen(src->path) : 0;
+ size_t pathlen = src->path ? strlen(src->path) : 0, alloclen;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_filter_list), pathlen);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_filter_list) + pathlen, 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_filter_list), pathlen);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
- fl = git__calloc(1, sizeof(git_filter_list) + pathlen + 1);
+ fl = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(fl);
if (src->path)
diff --git a/src/index.c b/src/index.c
index 35f512ca4..75700a719 100644
--- a/src/index.c
+++ b/src/index.c
@@ -770,7 +770,7 @@ static int index_entry_create(
git_repository *repo,
const char *path)
{
- size_t pathlen = strlen(path);
+ size_t pathlen = strlen(path), alloclen;
struct entry_internal *entry;
if (!git_path_isvalid(repo, path,
@@ -779,9 +779,9 @@ static int index_entry_create(
return -1;
}
- GITERR_CHECK_ALLOC_ADD(sizeof(struct entry_internal), pathlen);
- GITERR_CHECK_ALLOC_ADD(sizeof(struct entry_internal) + pathlen, 1);
- entry = git__calloc(1, sizeof(struct entry_internal) + pathlen + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(struct entry_internal), pathlen);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+ entry = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(entry);
entry->pathlen = pathlen;
@@ -829,14 +829,15 @@ static int index_entry_init(
static git_index_reuc_entry *reuc_entry_alloc(const char *path)
{
size_t pathlen = strlen(path),
- structlen = sizeof(struct reuc_entry_internal);
+ structlen = sizeof(struct reuc_entry_internal),
+ alloclen;
struct reuc_entry_internal *entry;
- if (GIT_ALLOC_OVERFLOW_ADD(structlen, pathlen) ||
- GIT_ALLOC_OVERFLOW_ADD(structlen + pathlen, 1))
+ if (GIT_ADD_SIZET_OVERFLOW(&alloclen, structlen, pathlen) ||
+ GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1))
return NULL;
- entry = git__calloc(1, structlen + pathlen + 1);
+ entry = git__calloc(1, alloclen);
if (!entry)
return NULL;
diff --git a/src/integer.h b/src/integer.h
index a9ed10aae..a4abe2bd1 100644
--- a/src/integer.h
+++ b/src/integer.h
@@ -35,6 +35,13 @@ GIT_INLINE(int) git__is_ulong(git_off_t p)
return p == (git_off_t)r;
}
+/** @return true if p fits into the range of an int */
+GIT_INLINE(int) git__is_int(long long p)
+{
+ int r = (int)p;
+ return p == (long long)r;
+}
+
/**
* Sets `one + two` into `out`, unless the arithmetic would overflow.
* @return true if the result fits in a `uint64_t`, false on overflow.
@@ -42,10 +49,9 @@ GIT_INLINE(int) git__is_ulong(git_off_t p)
GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t two)
{
if (UINT64_MAX - one < two)
- return false;
- if (out)
- *out = one + two;
- return true;
+ return true;
+ *out = one + two;
+ return false;
}
/**
@@ -55,10 +61,9 @@ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t
GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
{
if (SIZE_MAX - one < two)
- return false;
- if (out)
- *out = one + two;
- return true;
+ return true;
+ *out = one + two;
+ return false;
}
/**
@@ -68,10 +73,9 @@ GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t two)
{
if (one && SIZE_MAX / one < two)
- return false;
- if (out)
- *out = one * two;
- return true;
+ return true;
+ *out = one * two;
+ return false;
}
#endif /* INCLUDE_integer_h__ */
diff --git a/src/iterator.c b/src/iterator.c
index e90cf30ff..9ddacebd1 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -344,11 +344,8 @@ static int tree_iterator__push_frame(tree_iterator *ti)
for (i = head->current; i < head->next; ++i)
n_entries += git_tree_entrycount(head->entries[i]->tree);
- GITERR_CHECK_ALLOC_MULTIPLY(sizeof(tree_iterator_entry *), n_entries);
- alloclen = sizeof(tree_iterator_entry *) * n_entries;
-
- GITERR_CHECK_ALLOC_ADD(alloclen, sizeof(tree_iterator_frame));
- alloclen += sizeof(tree_iterator_frame);
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, sizeof(tree_iterator_entry *), n_entries);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, sizeof(tree_iterator_frame));
tf = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(tf);
diff --git a/src/merge.c b/src/merge.c
index 25d7bd7aa..e4b60c847 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -1169,8 +1169,7 @@ int git_merge_diff_list__find_renames(
goto done;
if (diff_list->conflicts.length <= opts->target_limit) {
- GITERR_CHECK_ALLOC_MULTIPLY(diff_list->conflicts.length, 3);
- cache_size = diff_list->conflicts.length * 3;
+ GITERR_CHECK_ALLOC_MULTIPLY(&cache_size, diff_list->conflicts.length, 3);
cache = git__calloc(cache_size, sizeof(void *));
GITERR_CHECK_ALLOC(cache);
@@ -2224,13 +2223,13 @@ static int merge_ancestor_head(
size_t their_heads_len)
{
git_oid *oids, ancestor_oid;
- size_t i;
+ size_t i, alloc_len;
int error = 0;
assert(repo && our_head && their_heads);
- GITERR_CHECK_ALLOC_ADD(their_heads_len, 1);
- oids = git__calloc(their_heads_len + 1, sizeof(git_oid));
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, their_heads_len, 1);
+ oids = git__calloc(alloc_len, sizeof(git_oid));
GITERR_CHECK_ALLOC(oids);
git_oid_cpy(&oids[0], git_commit_id(our_head->commit));
diff --git a/src/odb.c b/src/odb.c
index fcb21c1ce..b1d606b4d 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -216,30 +216,31 @@ int git_odb__hashfd_filtered(
int git_odb__hashlink(git_oid *out, const char *path)
{
struct stat st;
- size_t size;
+ int size;
int result;
if (git_path_lstat(path, &st) < 0)
return -1;
- if (!git__is_sizet(st.st_size)) {
+ if (!git__is_int(st.st_size) || (int)st.st_size < 0) {
giterr_set(GITERR_FILESYSTEM, "File size overflow for 32-bit systems");
return -1;
}
- size = (size_t)st.st_size;
+ size = (int)st.st_size;
if (S_ISLNK(st.st_mode)) {
char *link_data;
- ssize_t read_len;
+ int read_len;
+ size_t alloc_size;
- GITERR_CHECK_ALLOC_ADD(size, 1);
- link_data = git__malloc(size + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, size, 1);
+ link_data = git__malloc(alloc_size);
GITERR_CHECK_ALLOC(link_data);
read_len = p_readlink(path, link_data, size);
link_data[size] = '\0';
- if (read_len != (ssize_t)size) {
+ if (read_len != size) {
giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", path);
git__free(link_data);
return -1;
diff --git a/src/odb_loose.c b/src/odb_loose.c
index e43b261fa..bfd95588b 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -63,10 +63,12 @@ typedef struct {
static int object_file_name(
git_buf *name, const loose_backend *be, const git_oid *id)
{
+ size_t alloclen;
+
/* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
- GITERR_CHECK_ALLOC_ADD(be->objects_dirlen, GIT_OID_HEXSZ);
- GITERR_CHECK_ALLOC_ADD(be->objects_dirlen + GIT_OID_HEXSZ, 3);
- if (git_buf_grow(name, be->objects_dirlen + GIT_OID_HEXSZ + 3) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3);
+ if (git_buf_grow(name, alloclen) < 0)
return -1;
git_buf_set(name, be->objects_dir, be->objects_dirlen);
@@ -263,15 +265,15 @@ static int inflate_buffer(void *in, size_t inlen, void *out, size_t outlen)
static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
{
unsigned char *buf, *head = hb;
- size_t tail;
+ size_t tail, alloc_size;
/*
* allocate a buffer to hold the inflated data and copy the
* initial sequence of inflated data from the tail of the
* head buffer, if any.
*/
- if (GIT_ALLOC_OVERFLOW_ADD(hdr->size, 1) ||
- (buf = git__malloc(hdr->size + 1)) == NULL) {
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr->size, 1) ||
+ (buf = git__malloc(alloc_size)) == NULL) {
inflateEnd(s);
return NULL;
}
@@ -309,7 +311,7 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
{
unsigned char *in, *buf;
obj_hdr hdr;
- size_t len, used;
+ size_t len, used, alloclen;
/*
* read the object header, which is an (uncompressed)
@@ -324,8 +326,8 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
/*
* allocate a buffer and inflate the data into it
*/
- GITERR_CHECK_ALLOC_ADD(hdr.size, 1);
- buf = git__malloc(hdr.size + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, hdr.size, 1);
+ buf = git__malloc(alloclen);
GITERR_CHECK_ALLOC(buf);
in = ((unsigned char *)obj->ptr) + used;
@@ -519,14 +521,14 @@ static int locate_object_short_oid(
size_t len)
{
char *objects_dir = backend->objects_dir;
- size_t dir_len = strlen(objects_dir);
+ size_t dir_len = strlen(objects_dir), alloc_len;
loose_locate_object_state state;
int error;
/* prealloc memory for OBJ_DIR/xx/xx..38x..xx */
- GITERR_CHECK_ALLOC_ADD(dir_len, GIT_OID_HEXSZ);
- GITERR_CHECK_ALLOC_ADD(dir_len + GIT_OID_HEXSZ, 3);
- if (git_buf_grow(object_location, dir_len + 3 + GIT_OID_HEXSZ) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3);
+ if (git_buf_grow(object_location, alloc_len) < 0)
return -1;
git_buf_set(object_location, objects_dir, dir_len);
@@ -569,11 +571,11 @@ static int locate_object_short_oid(
return error;
/* Update the location according to the oid obtained */
- GITERR_CHECK_ALLOC_ADD(dir_len, GIT_OID_HEXSZ);
- GITERR_CHECK_ALLOC_ADD(dir_len + GIT_OID_HEXSZ, 2);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
git_buf_truncate(object_location, dir_len);
- if (git_buf_grow(object_location, dir_len + GIT_OID_HEXSZ + 2) < 0)
+ if (git_buf_grow(object_location, alloc_len) < 0)
return -1;
git_oid_pathfmt(object_location->ptr + dir_len, res_oid);
@@ -930,15 +932,15 @@ int git_odb_backend_loose(
unsigned int file_mode)
{
loose_backend *backend;
- size_t objects_dirlen;
+ size_t objects_dirlen, alloclen;
assert(backend_out && objects_dir);
objects_dirlen = strlen(objects_dir);
- GITERR_CHECK_ALLOC_ADD(sizeof(loose_backend), objects_dirlen);
- GITERR_CHECK_ALLOC_ADD(sizeof(loose_backend) + objects_dirlen, 2);
- backend = git__calloc(1, sizeof(loose_backend) + objects_dirlen + 2);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(loose_backend), objects_dirlen);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 2);
+ backend = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(backend);
backend->parent.version = GIT_ODB_BACKEND_VERSION;
diff --git a/src/odb_mempack.c b/src/odb_mempack.c
index a71d8db4b..32bc84442 100644
--- a/src/odb_mempack.c
+++ b/src/odb_mempack.c
@@ -38,6 +38,7 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
struct memobject *obj = NULL;
khiter_t pos;
+ size_t alloc_len;
int rval;
pos = kh_put(oid, db->objects, oid, &rval);
@@ -47,8 +48,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
if (rval == 0)
return 0;
- GITERR_CHECK_ALLOC_ADD(sizeof(struct memobject), len);
- obj = git__malloc(sizeof(struct memobject) + len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
+ obj = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(obj);
memcpy(obj->data, data, len);
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 8236ef9f3..67d6125ff 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -202,9 +202,8 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
return 0;
if (pb->nr_objects >= pb->nr_alloc) {
- GITERR_CHECK_ALLOC_ADD(pb->nr_alloc, 1024);
- GITERR_CHECK_ALLOC_MULTIPLY(pb->nr_alloc + 1024, 3 / 2);
- newsize = (pb->nr_alloc + 1024) * 3 / 2;
+ GITERR_CHECK_ALLOC_ADD(&newsize, pb->nr_alloc, 1024);
+ GITERR_CHECK_ALLOC_MULTIPLY(&newsize, newsize, 3 / 2);
if (!git__is_uint32(newsize)) {
giterr_set(GITERR_NOMEMORY, "Packfile too large to fit in memory.");
@@ -833,7 +832,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
trg_object->delta_data = NULL;
}
if (delta_cacheable(pb, src_size, trg_size, delta_size)) {
- if (!git__add_uint64_overflow(&pb->delta_cache_size, pb->delta_cache_size, delta_size))
+ if (git__add_uint64_overflow(&pb->delta_cache_size, pb->delta_cache_size, delta_size))
return -1;
git_packbuilder__cache_unlock(pb);
diff --git a/src/pack.c b/src/pack.c
index d475b28ee..26a6036c2 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -624,7 +624,7 @@ int git_packfile_unpack(
struct pack_chain_elem *elem = NULL, *stack;
git_pack_cache_entry *cached = NULL;
struct pack_chain_elem small_stack[SMALL_STACK_SIZE];
- size_t stack_size = 0, elem_pos;
+ size_t stack_size = 0, elem_pos, alloclen;
git_otype base_type;
/*
@@ -684,8 +684,8 @@ int git_packfile_unpack(
if (cached && stack_size == 1) {
void *data = obj->data;
- GITERR_CHECK_ALLOC_ADD(obj->len, 1);
- obj->data = git__malloc(obj->len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, obj->len, 1);
+ obj->data = git__malloc(alloclen);
GITERR_CHECK_ALLOC(obj->data);
memcpy(obj->data, data, obj->len + 1);
@@ -840,17 +840,18 @@ int packfile_unpack_compressed(
size_t size,
git_otype type)
{
+ size_t buf_size;
int st;
z_stream stream;
unsigned char *buffer, *in;
- GITERR_CHECK_ALLOC_ADD(size, 1);
- buffer = git__calloc(1, size + 1);
+ GITERR_CHECK_ALLOC_ADD(&buf_size, size, 1);
+ buffer = git__calloc(1, buf_size);
GITERR_CHECK_ALLOC(buffer);
memset(&stream, 0, sizeof(stream));
stream.next_out = buffer;
- stream.avail_out = (uInt)size + 1;
+ stream.avail_out = (uInt)buf_size;
stream.zalloc = use_git_alloc;
stream.zfree = use_git_free;
@@ -1089,17 +1090,17 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
{
struct stat st;
struct git_pack_file *p;
- size_t path_len = path ? strlen(path) : 0;
+ size_t path_len = path ? strlen(path) : 0, alloc_len;
*pack_out = NULL;
if (path_len < strlen(".idx"))
return git_odb__error_notfound("invalid packfile path", NULL);
- GITERR_CHECK_ALLOC_ADD(sizeof(*p), path_len);
- GITERR_CHECK_ALLOC_ADD(sizeof(*p) + path_len, 2);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(*p), path_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
- p = git__calloc(1, sizeof(*p) + path_len + 2);
+ p = git__calloc(1, alloc_len);
GITERR_CHECK_ALLOC(p);
memcpy(p->pack_name, path, path_len + 1);
diff --git a/src/path.c b/src/path.c
index 3dbd7187b..64c7b7e12 100644
--- a/src/path.c
+++ b/src/path.c
@@ -620,11 +620,12 @@ static bool _check_dir_contents(
bool result;
size_t dir_size = git_buf_len(dir);
size_t sub_size = strlen(sub);
+ size_t alloc_size;
/* leave base valid even if we could not make space for subdir */
- if (GIT_ALLOC_OVERFLOW_ADD(dir_size, sub_size) ||
- GIT_ALLOC_OVERFLOW_ADD(dir_size + sub_size, 2) ||
- git_buf_try_grow(dir, dir_size + sub_size + 2, false, false) < 0)
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, dir_size, sub_size) ||
+ GIT_ADD_SIZET_OVERFLOW(&alloc_size, alloc_size, 2) ||
+ git_buf_try_grow(dir, alloc_size, false, false) < 0)
return false;
/* save excursion */
@@ -786,7 +787,7 @@ int git_path_cmp(
int git_path_make_relative(git_buf *path, const char *parent)
{
const char *p, *q, *p_dirsep, *q_dirsep;
- size_t plen = path->size, newlen, depth = 1, i, offset;
+ size_t plen = path->size, newlen, alloclen, depth = 1, i, offset;
for (p_dirsep = p = path->ptr, q_dirsep = q = parent; *p && *q; p++, q++) {
if (*p == '/' && *q == '/') {
@@ -824,14 +825,14 @@ int git_path_make_relative(git_buf *path, const char *parent)
for (; (q = strchr(q, '/')) && *(q + 1); q++)
depth++;
- GITERR_CHECK_ALLOC_MULTIPLY(depth, 3);
- GITERR_CHECK_ALLOC_ADD(depth * 3, plen);
- GITERR_CHECK_ALLOC_ADD(depth * 3, 1);
- newlen = (depth * 3) + plen;
+ GITERR_CHECK_ALLOC_MULTIPLY(&newlen, depth, 3);
+ GITERR_CHECK_ALLOC_ADD(&newlen, newlen, plen);
+
+ GITERR_CHECK_ALLOC_ADD(&alloclen, newlen, 1);
/* save the offset as we might realllocate the pointer */
offset = p - path->ptr;
- if (git_buf_try_grow(path, newlen + 1, 1, 0) < 0)
+ if (git_buf_try_grow(path, alloclen, 1, 0) < 0)
return -1;
p = path->ptr + offset;
@@ -876,7 +877,7 @@ void git_path_iconv_clear(git_path_iconv_t *ic)
int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen)
{
char *nfd = *in, *nfc;
- size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, rv;
+ size_t nfdlen = *inlen, nfclen, wantlen = nfdlen, alloclen, rv;
int retry = 1;
if (!ic || ic->map == (iconv_t)-1 ||
@@ -886,8 +887,8 @@ int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen)
git_buf_clear(&ic->buf);
while (1) {
- GITERR_CHECK_ALLOC_ADD(wantlen, 1);
- if (git_buf_grow(&ic->buf, wantlen + 1) < 0)
+ GITERR_CHECK_ALLOC_ADD(&alloclen, wantlen, 1);
+ if (git_buf_grow(&ic->buf, alloclen) < 0)
return -1;
nfc = ic->buf.ptr + ic->buf.size;
@@ -1072,21 +1073,13 @@ static int entry_path_alloc(
size_t alloc_extra)
{
int need_slash = (path_len > 0 && path[path_len-1] != '/') ? 1 : 0;
- size_t alloc_size = path_len;
+ size_t alloc_size;
char *entry_path;
- GITERR_CHECK_ALLOC_ADD(alloc_size, de_len);
- alloc_size += de_len;
-
- GITERR_CHECK_ALLOC_ADD(alloc_size, need_slash);
- alloc_size += need_slash;
-
- GITERR_CHECK_ALLOC_ADD(alloc_size, 1);
- alloc_size++;
-
- GITERR_CHECK_ALLOC_ADD(alloc_size, alloc_extra);
- alloc_size += alloc_extra;
-
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, path_len, de_len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, need_slash);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_size, alloc_size, alloc_extra);
entry_path = git__calloc(1, alloc_size);
GITERR_CHECK_ALLOC(entry_path);
diff --git a/src/pool.c b/src/pool.c
index 919e13d08..c93d78182 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -107,21 +107,22 @@ static void pool_insert_page(git_pool *pool, git_pool_page *page)
static void *pool_alloc_page(git_pool *pool, uint32_t size)
{
git_pool_page *page;
- uint32_t alloc_size;
+ uint32_t new_page_size;
+ size_t alloc_size;
if (size <= pool->page_size)
- alloc_size = pool->page_size;
+ new_page_size = pool->page_size;
else {
- alloc_size = size;
+ new_page_size = size;
pool->has_large_page_alloc = 1;
}
- if (GIT_ALLOC_OVERFLOW_ADD(alloc_size, sizeof(git_pool_page)) ||
- !(page = git__calloc(1, alloc_size + sizeof(git_pool_page))))
+ if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, new_page_size, sizeof(git_pool_page)) ||
+ !(page = git__calloc(1, alloc_size)))
return NULL;
- page->size = alloc_size;
- page->avail = alloc_size - size;
+ page->size = new_page_size;
+ page->avail = new_page_size - size;
if (page->avail > 0)
pool_insert_page(pool, page);
diff --git a/src/refs.c b/src/refs.c
index af3190ef9..2e88c26c3 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -36,15 +36,13 @@ enum {
static git_reference *alloc_ref(const char *name)
{
- git_reference *ref;
- size_t namelen = strlen(name), reflen = sizeof(git_reference);
-
- if (GIT_ALLOC_OVERFLOW_ADD(reflen, namelen) ||
- GIT_ALLOC_OVERFLOW_ADD(reflen + namelen, 1) ||
- (ref = git__calloc(1, reflen + namelen + 1)) == NULL)
- return NULL;
+ git_reference *ref = NULL;
+ size_t namelen = strlen(name), reflen;
- memcpy(ref->name, name, namelen + 1);
+ if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
+ !GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
+ (ref = git__calloc(1, reflen)) != NULL)
+ memcpy(ref->name, name, namelen + 1);
return ref;
}
@@ -96,12 +94,12 @@ git_reference *git_reference__set_name(
git_reference *ref, const char *name)
{
size_t namelen = strlen(name);
- size_t reflen = sizeof(git_reference);
+ size_t reflen;
git_reference *rewrite = NULL;
- if (!GIT_ALLOC_OVERFLOW_ADD(reflen, namelen) &&
- !GIT_ALLOC_OVERFLOW_ADD(reflen + namelen, 1) &&
- (rewrite = git__realloc(ref, reflen + namelen + 1)) != NULL)
+ if (!GIT_ADD_SIZET_OVERFLOW(&reflen, sizeof(git_reference), namelen) &&
+ !GIT_ADD_SIZET_OVERFLOW(&reflen, reflen, 1) &&
+ (rewrite = git__realloc(ref, reflen)) != NULL)
memcpy(rewrite->name, name, namelen + 1);
return rewrite;
diff --git a/src/sortedcache.c b/src/sortedcache.c
index 021f79632..1195ea339 100644
--- a/src/sortedcache.c
+++ b/src/sortedcache.c
@@ -11,13 +11,13 @@ int git_sortedcache_new(
const char *path)
{
git_sortedcache *sc;
- size_t pathlen;
+ size_t pathlen, alloclen;
pathlen = path ? strlen(path) : 0;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_sortedcache), pathlen);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_sortedcache) + pathlen, 1);
- sc = git__calloc(1, sizeof(git_sortedcache) + pathlen + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_sortedcache), pathlen);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+ sc = git__calloc(1, alloclen);
GITERR_CHECK_ALLOC(sc);
if (git_pool_init(&sc->pool, 1, 0) < 0 ||
diff --git a/src/tag.c b/src/tag.c
index b82131401..3b8d684ed 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -72,7 +72,7 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
};
unsigned int i;
- size_t text_len;
+ size_t text_len, alloc_len;
char *search;
if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0)
@@ -117,8 +117,8 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
text_len = search - buffer;
- GITERR_CHECK_ALLOC_ADD(text_len, 1);
- tag->tag_name = git__malloc(text_len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
+ tag->tag_name = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(tag->tag_name);
memcpy(tag->tag_name, buffer, text_len);
@@ -142,8 +142,8 @@ static int tag_parse(git_tag *tag, const char *buffer, const char *buffer_end)
text_len = buffer_end - ++buffer;
- GITERR_CHECK_ALLOC_ADD(text_len, 1);
- tag->message = git__malloc(text_len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, text_len, 1);
+ tag->message = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(tag->message);
memcpy(tag->message, buffer, text_len);
diff --git a/src/transports/cred.c b/src/transports/cred.c
index 8e5447d18..8163d3115 100644
--- a/src/transports/cred.c
+++ b/src/transports/cred.c
@@ -306,15 +306,15 @@ int git_cred_default_new(git_cred **cred)
int git_cred_username_new(git_cred **cred, const char *username)
{
git_cred_username *c;
- size_t len;
+ size_t len, allocsize;
assert(cred);
len = strlen(username);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_cred_username), len);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_cred_username) + len, 1);
- c = git__malloc(sizeof(git_cred_username) + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&allocsize, sizeof(git_cred_username), len);
+ GITERR_CHECK_ALLOC_ADD(&allocsize, allocsize, 1);
+ c = git__malloc(allocsize);
GITERR_CHECK_ALLOC(c);
c->parent.credtype = GIT_CREDTYPE_USERNAME;
diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c
index 11c6215ff..d214c9fa5 100644
--- a/src/transports/smart_pkt.c
+++ b/src/transports/smart_pkt.c
@@ -102,10 +102,11 @@ static int pack_pkt(git_pkt **out)
static int comment_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_comment *pkt;
+ size_t alloclen;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_comment), len);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_comment) + len, 1);
- pkt = git__malloc(sizeof(git_pkt_comment) + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_comment), len);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+ pkt = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_COMMENT;
@@ -120,14 +121,15 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len)
static int err_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_err *pkt;
+ size_t alloclen;
/* Remove "ERR " from the line */
line += 4;
len -= 4;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_progress), len);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_progress) + len, 1);
- pkt = git__malloc(sizeof(git_pkt_err) + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
+ pkt = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_ERR;
@@ -143,12 +145,13 @@ static int err_pkt(git_pkt **out, const char *line, size_t len)
static int data_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_data *pkt;
+ size_t alloclen;
line++;
len--;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_progress), len);
- pkt = git__malloc(sizeof(git_pkt_data) + len);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+ pkt = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_DATA;
@@ -163,12 +166,13 @@ static int data_pkt(git_pkt **out, const char *line, size_t len)
static int sideband_progress_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_progress *pkt;
+ size_t alloclen;
line++;
len--;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_progress), len);
- pkt = git__malloc(sizeof(git_pkt_progress) + len);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_pkt_progress), len);
+ pkt = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_PROGRESS;
@@ -183,13 +187,14 @@ static int sideband_progress_pkt(git_pkt **out, const char *line, size_t len)
static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_err *pkt;
+ size_t alloc_len;
line++;
len--;
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_err), len);
- GITERR_CHECK_ALLOC_ADD(sizeof(git_pkt_err) + len, 1);
- pkt = git__malloc(sizeof(git_pkt_err) + len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(git_pkt_err), len);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 1);
+ pkt = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(pkt);
pkt->type = GIT_PKT_ERR;
@@ -209,6 +214,7 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
{
int error;
git_pkt_ref *pkt;
+ size_t alloclen;
pkt = git__malloc(sizeof(git_pkt_ref));
GITERR_CHECK_ALLOC(pkt);
@@ -232,8 +238,8 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
if (line[len - 1] == '\n')
--len;
- GITERR_CHECK_ALLOC_ADD(len, 1);
- pkt->head.name = git__malloc(len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+ pkt->head.name = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt->head.name);
memcpy(pkt->head.name, line, len);
@@ -255,6 +261,7 @@ static int ok_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_ok *pkt;
const char *ptr;
+ size_t alloc_len;
pkt = git__malloc(sizeof(*pkt));
GITERR_CHECK_ALLOC(pkt);
@@ -268,8 +275,8 @@ static int ok_pkt(git_pkt **out, const char *line, size_t len)
}
len = ptr - line;
- GITERR_CHECK_ALLOC_ADD(len, 1);
- pkt->ref = git__malloc(len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, len, 1);
+ pkt->ref = git__malloc(alloc_len);
GITERR_CHECK_ALLOC(pkt->ref);
memcpy(pkt->ref, line, len);
@@ -283,6 +290,7 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
{
git_pkt_ng *pkt;
const char *ptr;
+ size_t alloclen;
pkt = git__malloc(sizeof(*pkt));
GITERR_CHECK_ALLOC(pkt);
@@ -296,8 +304,8 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
}
len = ptr - line;
- GITERR_CHECK_ALLOC_ADD(len, 1);
- pkt->ref = git__malloc(len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+ pkt->ref = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt->ref);
memcpy(pkt->ref, line, len);
@@ -310,8 +318,8 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
}
len = ptr - line;
- GITERR_CHECK_ALLOC_ADD(len, 1);
- pkt->msg = git__malloc(len + 1);
+ GITERR_CHECK_ALLOC_ADD(&alloclen, len, 1);
+ pkt->msg = git__malloc(alloclen);
GITERR_CHECK_ALLOC(pkt->msg);
memcpy(pkt->msg, line, len);
diff --git a/src/tree.c b/src/tree.c
index 573e56447..9fd4e0a07 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -84,12 +84,11 @@ int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
static git_tree_entry *alloc_entry(const char *filename)
{
git_tree_entry *entry = NULL;
- size_t filename_len = strlen(filename),
- tree_len = sizeof(git_tree_entry);
+ size_t filename_len = strlen(filename), tree_len;
- if (GIT_ALLOC_OVERFLOW_ADD(tree_len, filename_len) ||
- GIT_ALLOC_OVERFLOW_ADD(tree_len + filename_len, 1) ||
- !(entry = git__malloc(tree_len + filename_len + 1)))
+ if (GIT_ADD_SIZET_OVERFLOW(&tree_len, sizeof(git_tree_entry), filename_len) ||
+ GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1) ||
+ !(entry = git__malloc(tree_len)))
return NULL;
memset(entry, 0x0, sizeof(git_tree_entry));
@@ -207,16 +206,13 @@ void git_tree_entry_free(git_tree_entry *entry)
int git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source)
{
- size_t total_size = sizeof(git_tree_entry);
+ size_t total_size;
git_tree_entry *copy;
assert(source);
- GITERR_CHECK_ALLOC_ADD(total_size, source->filename_len);
- total_size += source->filename_len;
-
- GITERR_CHECK_ALLOC_ADD(total_size, 1);
- total_size++;
+ GITERR_CHECK_ALLOC_ADD(&total_size, sizeof(git_tree_entry), source->filename_len);
+ GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
copy = git__malloc(total_size);
GITERR_CHECK_ALLOC(copy);
diff --git a/src/util.h b/src/util.h
index 86139ef77..38dcae79b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -59,17 +59,13 @@ GIT_INLINE(char *) git__strdup(const char *str)
GIT_INLINE(char *) git__strndup(const char *str, size_t n)
{
- size_t length = 0;
+ size_t length = 0, alloclength;
char *ptr;
length = p_strnlen(str, n);
- if (GIT_ALLOC_OVERFLOW_ADD(length, 1))
- return NULL;
-
- ptr = git__malloc(length + 1);
-
- if (!ptr)
+ if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
+ !(ptr = git__malloc(alloclength)))
return NULL;
if (length)
@@ -84,8 +80,10 @@ GIT_INLINE(char *) git__strndup(const char *str, size_t n)
GIT_INLINE(char *) git__substrdup(const char *start, size_t n)
{
char *ptr;
+ size_t alloclen;
- if (GIT_ALLOC_OVERFLOW_ADD(n, 1) || !(ptr = git__malloc(n+1)))
+ if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
+ !(ptr = git__malloc(alloclen)))
return NULL;
memcpy(ptr, start, n);
@@ -107,8 +105,9 @@ GIT_INLINE(void *) git__realloc(void *ptr, size_t size)
*/
GIT_INLINE(void *) git__reallocarray(void *ptr, size_t nelem, size_t elsize)
{
- return GIT_ALLOC_OVERFLOW_MULTIPLY(nelem, elsize) ?
- NULL : realloc(ptr, nelem * elsize);
+ size_t newsize;
+ return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
+ NULL : realloc(ptr, newsize);
}
/**
diff --git a/src/vector.c b/src/vector.c
index 27eafebc8..93d09bb5b 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -46,8 +46,7 @@ int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp)
assert(v && src);
- GITERR_CHECK_ALLOC_MULTIPLY(src->length, sizeof(void *));
- bytes = src->length * sizeof(void *);
+ GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *));
v->_alloc_size = src->length;
v->_cmp = cmp ? cmp : src->_cmp;
diff --git a/src/win32/dir.c b/src/win32/dir.c
index 7f2a5a56e..c15757085 100644
--- a/src/win32/dir.c
+++ b/src/win32/dir.c
@@ -11,16 +11,16 @@ git__DIR *git__opendir(const char *dir)
{
git_win32_path filter_w;
git__DIR *new = NULL;
- size_t dirlen;
+ size_t dirlen, alloclen;
if (!dir || !git_win32__findfirstfile_filter(filter_w, dir))
return NULL;
dirlen = strlen(dir);
- if (GIT_ALLOC_OVERFLOW_ADD(sizeof(*new), dirlen) ||
- GIT_ALLOC_OVERFLOW_ADD(sizeof(*new) + dirlen, 1) ||
- !(new = git__calloc(1, sizeof(*new) + dirlen + 1)))
+ if (GIT_ADD_SIZET_OVERFLOW(&alloclen, sizeof(*new), dirlen) ||
+ GIT_ADD_SIZET_OVERFLOW(&alloclen, alloclen, 1) ||
+ !(new = git__calloc(1, alloclen)))
return NULL;
memcpy(new->dir, dir, dirlen);
diff --git a/tests/core/errors.c b/tests/core/errors.c
index 11e0bb2bb..a06ec4abc 100644
--- a/tests/core/errors.c
+++ b/tests/core/errors.c
@@ -112,7 +112,8 @@ void test_core_errors__restore(void)
static int test_arraysize_multiply(size_t nelem, size_t size)
{
- GITERR_CHECK_ALLOC_MULTIPLY(nelem, size);
+ size_t out;
+ GITERR_CHECK_ALLOC_MULTIPLY(&out, nelem, size);
return 0;
}
@@ -133,7 +134,8 @@ void test_core_errors__integer_overflow_alloc_multiply(void)
static int test_arraysize_add(size_t one, size_t two)
{
- GITERR_CHECK_ALLOC_ADD(one, two);
+ size_t out;
+ GITERR_CHECK_ALLOC_ADD(&out, one, two);
return 0;
}
@@ -152,21 +154,23 @@ void test_core_errors__integer_overflow_alloc_add(void)
void test_core_errors__integer_overflow_sets_oom(void)
{
+ size_t out;
+
giterr_clear();
- cl_assert(!GIT_ALLOC_OVERFLOW_ADD(SIZE_MAX-1, 1));
+ cl_assert(!GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX-1, 1));
cl_assert_equal_p(NULL, giterr_last());
giterr_clear();
- cl_assert(!GIT_ALLOC_OVERFLOW_ADD(42, 69));
+ cl_assert(!GIT_ADD_SIZET_OVERFLOW(&out, 42, 69));
cl_assert_equal_p(NULL, giterr_last());
giterr_clear();
- cl_assert(GIT_ALLOC_OVERFLOW_ADD(SIZE_MAX, SIZE_MAX));
+ cl_assert(GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX, SIZE_MAX));
cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
cl_assert_equal_s("Out of memory", giterr_last()->message);
giterr_clear();
- cl_assert(GIT_ALLOC_OVERFLOW_MULTIPLY(SIZE_MAX, SIZE_MAX));
+ cl_assert(GIT_ADD_SIZET_OVERFLOW(&out, SIZE_MAX, SIZE_MAX));
cl_assert_equal_i(GITERR_NOMEMORY, giterr_last()->klass);
cl_assert_equal_s("Out of memory", giterr_last()->message);
}