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_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); + GITERR_CHECK_ALLOC_ADD(&blocks, blocks, 1); + GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, blocks, 4); + GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, buf->size); + + 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, (buf->size - nb_to_remove), nb_to_insert); + GITERR_CHECK_ALLOC_ADD(&alloc_size, new_size, 1); + ENSURE_SIZE(buf, alloc_size); - GITERR_CHECK_ALLOC_ADD(new_size, nb_to_insert); - new_size += nb_to_insert; + memmove(splice_loc + nb_to_insert, + splice_loc + nb_to_remove, + buf->size - where - nb_to_remove); - GITERR_CHECK_ALLOC_ADD(new_size, 1); - ENSURE_SIZE(buf, new_size + 1); - - memmove(buf->ptr + where + nb_to_insert, - buf->ptr + where + 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); + git_reference *ref = NULL; + size_t namelen = strlen(name), reflen; - if (GIT_ALLOC_OVERFLOW_ADD(reflen, namelen) || - GIT_ALLOC_OVERFLOW_ADD(reflen + namelen, 1) || - (ref = git__calloc(1, reflen + namelen + 1)) == NULL) - return NULL; - - 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); }