summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}