]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reftable: introduce macros to allocate arrays
authorPatrick Steinhardt <ps@pks.im>
Tue, 6 Feb 2024 06:35:27 +0000 (07:35 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 6 Feb 2024 20:10:08 +0000 (12:10 -0800)
Similar to the preceding commit, let's carry over macros to allocate
arrays with `REFTABLE_ALLOC_ARRAY()` and `REFTABLE_CALLOC_ARRAY()`. This
requires us to change the signature of `reftable_calloc()`, which only
takes a single argument right now and thus puts the burden on the caller
to calculate the final array's size. This is a net improvement though as
it means that we can now provide proper overflow checks when multiplying
the array size with the member size.

Convert callsites of `reftable_calloc()` to the new signature and start
using the new macros where possible.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
16 files changed:
reftable/basics.h
reftable/block.c
reftable/block_test.c
reftable/blocksource.c
reftable/iter.c
reftable/merged.c
reftable/merged_test.c
reftable/publicbasics.c
reftable/reader.c
reftable/readwrite_test.c
reftable/record.c
reftable/record_test.c
reftable/refname.c
reftable/stack.c
reftable/tree.c
reftable/writer.c

index 2f855cd724b35713fe35ab3635f87bbdc345b2d0..4c3ac963a35204fbb3d2d5aab6589fe6120646ab 100644 (file)
@@ -51,8 +51,10 @@ int names_length(char **names);
 void *reftable_malloc(size_t sz);
 void *reftable_realloc(void *p, size_t sz);
 void reftable_free(void *p);
-void *reftable_calloc(size_t sz);
+void *reftable_calloc(size_t nelem, size_t elsize);
 
+#define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc)))
+#define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x)))
 #define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc)))
 #define REFTABLE_ALLOC_GROW(x, nr, alloc) \
        do { \
index 6952d0facf52425f4698dea5683c7d8542001fb1..838759823a0473d124c02df126fcae5606b60059 100644 (file)
@@ -143,8 +143,10 @@ int block_writer_finish(struct block_writer *w)
                int block_header_skip = 4 + w->header_off;
                uLongf src_len = w->next - block_header_skip;
                uLongf dest_cap = src_len * 1.001 + 12;
+               uint8_t *compressed;
+
+               REFTABLE_ALLOC_ARRAY(compressed, dest_cap);
 
-               uint8_t *compressed = reftable_malloc(dest_cap);
                while (1) {
                        uLongf out_dest_len = dest_cap;
                        int zresult = compress2(compressed, &out_dest_len,
@@ -201,9 +203,9 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block,
                uLongf dst_len = sz - block_header_skip; /* total size of dest
                                                            buffer. */
                uLongf src_len = block->len - block_header_skip;
-               /* Log blocks specify the *uncompressed* size in their header.
-                */
-               uncompressed = reftable_malloc(sz);
+
+               /* Log blocks specify the *uncompressed* size in their header. */
+               REFTABLE_ALLOC_ARRAY(uncompressed, sz);
 
                /* Copy over the block header verbatim. It's not compressed. */
                memcpy(uncompressed, block->data, block_header_skip);
index dedb05c7d8c0560898b03aba93043c7efa46aeea..e162c6e33fa00af4e2b3b653c0d6210aea57c803 100644 (file)
@@ -36,7 +36,7 @@ static void test_block_read_write(void)
        int j = 0;
        struct strbuf want = STRBUF_INIT;
 
-       block.data = reftable_calloc(block_size);
+       REFTABLE_CALLOC_ARRAY(block.data, block_size);
        block.len = block_size;
        block.source = malloc_block_source();
        block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size,
index 8c41e3c70f36aa0aab704fd8d296825f6e342a3d..eeed254ba9c2da51177eb7ed81fbf16d17ba183b 100644 (file)
@@ -29,7 +29,7 @@ static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off,
 {
        struct strbuf *b = v;
        assert(off + size <= b->len);
-       dest->data = reftable_calloc(size);
+       REFTABLE_CALLOC_ARRAY(dest->data, size);
        memcpy(dest->data, b->buf + off, size);
        dest->len = size;
        return size;
@@ -132,7 +132,7 @@ int reftable_block_source_from_file(struct reftable_block_source *bs,
                return REFTABLE_IO_ERROR;
        }
 
-       p = reftable_calloc(sizeof(*p));
+       REFTABLE_CALLOC_ARRAY(p, 1);
        p->size = st.st_size;
        p->data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        close(fd);
index a8d174c040658edda3d2c45a9df2f692aef41c9d..8b5ebf6183a97f3ea16a0773880ccd3b835ef68e 100644 (file)
@@ -160,8 +160,7 @@ int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest,
                               int oid_len, uint64_t *offsets, int offset_len)
 {
        struct indexed_table_ref_iter empty = INDEXED_TABLE_REF_ITER_INIT;
-       struct indexed_table_ref_iter *itr =
-               reftable_calloc(sizeof(struct indexed_table_ref_iter));
+       struct indexed_table_ref_iter *itr = reftable_calloc(1, sizeof(*itr));
        int err = 0;
 
        *itr = empty;
index c258ce953e81d7df5774a03250b056280beccbf3..2031fd51b4426f26da14a68567d8f24b9c7a2e58 100644 (file)
@@ -190,7 +190,7 @@ int reftable_new_merged_table(struct reftable_merged_table **dest,
                }
        }
 
-       m = reftable_calloc(sizeof(struct reftable_merged_table));
+       REFTABLE_CALLOC_ARRAY(m, 1);
        m->stack = stack;
        m->stack_len = n;
        m->min = first_min;
@@ -240,7 +240,7 @@ static int merged_table_seek_record(struct reftable_merged_table *mt,
                                    struct reftable_record *rec)
 {
        struct reftable_iterator *iters = reftable_calloc(
-               sizeof(struct reftable_iterator) * mt->stack_len);
+               mt->stack_len, sizeof(*iters));
        struct merged_iter merged = {
                .stack = iters,
                .typ = reftable_record_type(rec),
index e05351e035fc089fe752ce75ca319e60f5b0b24f..e233a9d581cff05cf91836af5c653dd4a3f3dbfc 100644 (file)
@@ -93,10 +93,12 @@ merged_table_from_records(struct reftable_ref_record **refs,
        int i = 0;
        struct reftable_merged_table *mt = NULL;
        int err;
-       struct reftable_table *tabs =
-               reftable_calloc(n * sizeof(struct reftable_table));
-       *readers = reftable_calloc(n * sizeof(struct reftable_reader *));
-       *source = reftable_calloc(n * sizeof(**source));
+       struct reftable_table *tabs;
+
+       REFTABLE_CALLOC_ARRAY(tabs, n);
+       REFTABLE_CALLOC_ARRAY(*readers, n);
+       REFTABLE_CALLOC_ARRAY(*source, n);
+
        for (i = 0; i < n; i++) {
                write_test_table(&buf[i], refs[i], sizes[i]);
                block_source_from_strbuf(&(*source)[i], &buf[i]);
@@ -266,10 +268,12 @@ merged_table_from_log_records(struct reftable_log_record **logs,
        int i = 0;
        struct reftable_merged_table *mt = NULL;
        int err;
-       struct reftable_table *tabs =
-               reftable_calloc(n * sizeof(struct reftable_table));
-       *readers = reftable_calloc(n * sizeof(struct reftable_reader *));
-       *source = reftable_calloc(n * sizeof(**source));
+       struct reftable_table *tabs;
+
+       REFTABLE_CALLOC_ARRAY(tabs, n);
+       REFTABLE_CALLOC_ARRAY(*readers, n);
+       REFTABLE_CALLOC_ARRAY(*source, n);
+
        for (i = 0; i < n; i++) {
                write_test_log_table(&buf[i], logs[i], sizes[i], i + 1);
                block_source_from_strbuf(&(*source)[i], &buf[i]);
@@ -412,7 +416,7 @@ static void test_default_write_opts(void)
        };
        int err;
        struct reftable_block_source source = { NULL };
-       struct reftable_table *tab = reftable_calloc(sizeof(*tab) * 1);
+       struct reftable_table *tab = reftable_calloc(1, sizeof(*tab));
        uint32_t hash_id;
        struct reftable_reader *rd = NULL;
        struct reftable_merged_table *merged = NULL;
index bcb82530d6ce35e8a0a582d9718090067b238899..44b84a125e43b3f0de9460b019854e22835d39e6 100644 (file)
@@ -37,8 +37,9 @@ void reftable_free(void *p)
                free(p);
 }
 
-void *reftable_calloc(size_t sz)
+void *reftable_calloc(size_t nelem, size_t elsize)
 {
+       size_t sz = st_mult(nelem, elsize);
        void *p = reftable_malloc(sz);
        memset(p, 0, sz);
        return p;
index 64dc366fb15935c55c5377ec9d4f1b74640cc3f6..3e0de5e8ad8bb1d98810b2e14326bfd8299c836c 100644 (file)
@@ -539,8 +539,7 @@ static int reader_seek_indexed(struct reftable_reader *r,
 
        if (err == 0) {
                struct table_iter empty = TABLE_ITER_INIT;
-               struct table_iter *malloced =
-                       reftable_calloc(sizeof(struct table_iter));
+               struct table_iter *malloced = reftable_calloc(1, sizeof(*malloced));
                *malloced = empty;
                table_iter_copy_from(malloced, &next);
                iterator_from_table_iter(it, malloced);
@@ -635,8 +634,7 @@ void reader_close(struct reftable_reader *r)
 int reftable_new_reader(struct reftable_reader **p,
                        struct reftable_block_source *src, char const *name)
 {
-       struct reftable_reader *rd =
-               reftable_calloc(sizeof(struct reftable_reader));
+       struct reftable_reader *rd = reftable_calloc(1, sizeof(*rd));
        int err = init_reader(rd, src, name);
        if (err == 0) {
                *p = rd;
@@ -711,7 +709,7 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r,
                                              uint8_t *oid)
 {
        struct table_iter ti_empty = TABLE_ITER_INIT;
-       struct table_iter *ti = reftable_calloc(sizeof(struct table_iter));
+       struct table_iter *ti = reftable_calloc(1, sizeof(*ti));
        struct filtering_ref_iterator *filter = NULL;
        struct filtering_ref_iterator empty = FILTERING_REF_ITERATOR_INIT;
        int oid_len = hash_size(r->hash_id);
index b8a32240164d6a5c29789fb1730a630127f085d5..91ea7a10ef29240c46d77cb71c58b5ca873d53bf 100644 (file)
@@ -56,7 +56,9 @@ static void write_table(char ***names, struct strbuf *buf, int N,
        int i = 0, n;
        struct reftable_log_record log = { NULL };
        const struct reftable_stats *stats = NULL;
-       *names = reftable_calloc(sizeof(char *) * (N + 1));
+
+       REFTABLE_CALLOC_ARRAY(*names, N + 1);
+
        reftable_writer_set_limits(w, update_index, update_index);
        for (i = 0; i < N; i++) {
                char name[100];
@@ -188,7 +190,7 @@ static void test_log_overflow(void)
 static void test_log_write_read(void)
 {
        int N = 2;
-       char **names = reftable_calloc(sizeof(char *) * (N + 1));
+       char **names = reftable_calloc(N + 1, sizeof(*names));
        int err;
        struct reftable_write_options opts = {
                .block_size = 256,
@@ -519,7 +521,7 @@ static void test_table_read_write_seek_index(void)
 static void test_table_refs_for(int indexed)
 {
        int N = 50;
-       char **want_names = reftable_calloc(sizeof(char *) * (N + 1));
+       char **want_names = reftable_calloc(N + 1, sizeof(*want_names));
        int want_names_len = 0;
        uint8_t want_hash[GIT_SHA1_RAWSZ];
 
index 5c3fbb7b2a1e95ad418066df0aa96235116f5329..2f3cd6b62c02408a7ccc847b0d2bf9722f7ba339 100644 (file)
@@ -497,12 +497,13 @@ static void reftable_obj_record_copy_from(void *rec, const void *src_rec,
                (const struct reftable_obj_record *)src_rec;
 
        reftable_obj_record_release(obj);
-       obj->hash_prefix = reftable_malloc(src->hash_prefix_len);
+
+       REFTABLE_ALLOC_ARRAY(obj->hash_prefix, src->hash_prefix_len);
        obj->hash_prefix_len = src->hash_prefix_len;
        if (src->hash_prefix_len)
                memcpy(obj->hash_prefix, src->hash_prefix, obj->hash_prefix_len);
 
-       obj->offsets = reftable_malloc(src->offset_len * sizeof(uint64_t));
+       REFTABLE_ALLOC_ARRAY(obj->offsets, src->offset_len);
        obj->offset_len = src->offset_len;
        COPY_ARRAY(obj->offsets, src->offsets, src->offset_len);
 }
@@ -559,7 +560,8 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key,
        int n = 0;
        uint64_t last;
        int j;
-       r->hash_prefix = reftable_malloc(key.len);
+
+       REFTABLE_ALLOC_ARRAY(r->hash_prefix, key.len);
        memcpy(r->hash_prefix, key.buf, key.len);
        r->hash_prefix_len = key.len;
 
@@ -577,7 +579,7 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key,
        if (count == 0)
                return start.len - in.len;
 
-       r->offsets = reftable_malloc(count * sizeof(uint64_t));
+       REFTABLE_ALLOC_ARRAY(r->offsets, count);
        r->offset_len = count;
 
        n = get_var_int(&r->offsets[0], &in);
@@ -715,12 +717,12 @@ static void reftable_log_record_copy_from(void *rec, const void *src_rec,
                }
 
                if (dst->value.update.new_hash) {
-                       dst->value.update.new_hash = reftable_malloc(hash_size);
+                       REFTABLE_ALLOC_ARRAY(dst->value.update.new_hash, hash_size);
                        memcpy(dst->value.update.new_hash,
                               src->value.update.new_hash, hash_size);
                }
                if (dst->value.update.old_hash) {
-                       dst->value.update.old_hash = reftable_malloc(hash_size);
+                       REFTABLE_ALLOC_ARRAY(dst->value.update.old_hash, hash_size);
                        memcpy(dst->value.update.old_hash,
                               src->value.update.old_hash, hash_size);
                }
index 2876db7d2708aa36d861181775de74c966862c2d..999366ad46749639085e9db94954fe2cd1e71e56 100644 (file)
@@ -231,8 +231,8 @@ static void test_reftable_log_record_roundtrip(void)
                                .value_type = REFTABLE_LOG_UPDATE,
                                .value = {
                                        .update = {
-                                               .new_hash = reftable_calloc(GIT_SHA1_RAWSZ),
-                                               .old_hash = reftable_calloc(GIT_SHA1_RAWSZ),
+                                               .new_hash = reftable_calloc(GIT_SHA1_RAWSZ, 1),
+                                               .old_hash = reftable_calloc(GIT_SHA1_RAWSZ, 1),
                                                .name = xstrdup("old name"),
                                                .email = xstrdup("old@email"),
                                                .message = xstrdup("old message"),
index 957349693247ae34c0b248a130e1e97f83ba1a71..7570e4acf9eec740057a4c6ba8a615878f48799f 100644 (file)
@@ -140,8 +140,8 @@ int validate_ref_record_addition(struct reftable_table tab,
 {
        struct modification mod = {
                .tab = tab,
-               .add = reftable_calloc(sizeof(char *) * sz),
-               .del = reftable_calloc(sizeof(char *) * sz),
+               .add = reftable_calloc(sz, sizeof(*mod.add)),
+               .del = reftable_calloc(sz, sizeof(*mod.del)),
        };
        int i = 0;
        int err = 0;
index 1dfab99e96fffc823e23091f01ca200f85fa71f8..a7b2c610263b8403f1e5c4b88335e1d4cb6e198c 100644 (file)
@@ -50,8 +50,7 @@ static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz)
 int reftable_new_stack(struct reftable_stack **dest, const char *dir,
                       struct reftable_write_options config)
 {
-       struct reftable_stack *p =
-               reftable_calloc(sizeof(struct reftable_stack));
+       struct reftable_stack *p = reftable_calloc(1, sizeof(*p));
        struct strbuf list_file_name = STRBUF_INIT;
        int err = 0;
 
@@ -94,7 +93,7 @@ static int fd_read_lines(int fd, char ***namesp)
                goto done;
        }
 
-       buf = reftable_malloc(size + 1);
+       REFTABLE_ALLOC_ARRAY(buf, size + 1);
        if (read_in_full(fd, buf, size) != size) {
                err = REFTABLE_IO_ERROR;
                goto done;
@@ -114,7 +113,7 @@ int read_lines(const char *filename, char ***namesp)
        int err = 0;
        if (fd < 0) {
                if (errno == ENOENT) {
-                       *namesp = reftable_calloc(sizeof(char *));
+                       REFTABLE_CALLOC_ARRAY(*namesp, 1);
                        return 0;
                }
 
@@ -191,8 +190,7 @@ void reftable_stack_destroy(struct reftable_stack *st)
 static struct reftable_reader **stack_copy_readers(struct reftable_stack *st,
                                                   int cur_len)
 {
-       struct reftable_reader **cur =
-               reftable_calloc(sizeof(struct reftable_reader *) * cur_len);
+       struct reftable_reader **cur = reftable_calloc(cur_len, sizeof(*cur));
        int i = 0;
        for (i = 0; i < cur_len; i++) {
                cur[i] = st->readers[i];
@@ -208,9 +206,9 @@ static int reftable_stack_reload_once(struct reftable_stack *st, char **names,
        int err = 0;
        int names_len = names_length(names);
        struct reftable_reader **new_readers =
-               reftable_calloc(sizeof(struct reftable_reader *) * names_len);
+               reftable_calloc(names_len, sizeof(*new_readers));
        struct reftable_table *new_tables =
-               reftable_calloc(sizeof(struct reftable_table) * names_len);
+               reftable_calloc(names_len, sizeof(*new_tables));
        int new_readers_len = 0;
        struct reftable_merged_table *new_merged = NULL;
        struct strbuf table_path = STRBUF_INIT;
@@ -344,7 +342,7 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st,
                                goto out;
                        }
 
-                       names = reftable_calloc(sizeof(char *));
+                       REFTABLE_CALLOC_ARRAY(names, 1);
                } else {
                        err = fd_read_lines(fd, &names);
                        if (err < 0)
@@ -686,7 +684,7 @@ int reftable_stack_new_addition(struct reftable_addition **dest,
 {
        int err = 0;
        struct reftable_addition empty = REFTABLE_ADDITION_INIT;
-       *dest = reftable_calloc(sizeof(**dest));
+       REFTABLE_CALLOC_ARRAY(*dest, 1);
        **dest = empty;
        err = reftable_stack_init_addition(*dest, st);
        if (err) {
@@ -871,7 +869,7 @@ static int stack_write_compact(struct reftable_stack *st,
 {
        int subtabs_len = last - first + 1;
        struct reftable_table *subtabs = reftable_calloc(
-               sizeof(struct reftable_table) * (last - first + 1));
+               last - first + 1, sizeof(*subtabs));
        struct reftable_merged_table *mt = NULL;
        int err = 0;
        struct reftable_iterator it = { NULL };
@@ -979,9 +977,9 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
        int compact_count = last - first + 1;
        char **listp = NULL;
        char **delete_on_success =
-               reftable_calloc(sizeof(char *) * (compact_count + 1));
+               reftable_calloc(compact_count + 1, sizeof(*delete_on_success));
        char **subtable_locks =
-               reftable_calloc(sizeof(char *) * (compact_count + 1));
+               reftable_calloc(compact_count + 1, sizeof(*subtable_locks));
        int i = 0;
        int j = 0;
        int is_empty_table = 0;
@@ -1204,7 +1202,7 @@ int fastlog2(uint64_t sz)
 
 struct segment *sizes_to_segments(int *seglen, uint64_t *sizes, int n)
 {
-       struct segment *segs = reftable_calloc(sizeof(struct segment) * n);
+       struct segment *segs = reftable_calloc(n, sizeof(*segs));
        int next = 0;
        struct segment cur = { 0 };
        int i = 0;
@@ -1268,7 +1266,7 @@ struct segment suggest_compaction_segment(uint64_t *sizes, int n)
 static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st)
 {
        uint64_t *sizes =
-               reftable_calloc(sizeof(uint64_t) * st->merged->stack_len);
+               reftable_calloc(st->merged->stack_len, sizeof(*sizes));
        int version = (st->config.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2;
        int overhead = header_size(version) - 1;
        int i = 0;
index a5bf880985472dee7cd7c9169047752245599488..528f33ae388d0a6ad93eaa5e3f604596f07071fb 100644 (file)
@@ -20,8 +20,8 @@ struct tree_node *tree_search(void *key, struct tree_node **rootp,
                if (!insert) {
                        return NULL;
                } else {
-                       struct tree_node *n =
-                               reftable_calloc(sizeof(struct tree_node));
+                       struct tree_node *n;
+                       REFTABLE_CALLOC_ARRAY(n, 1);
                        n->key = key;
                        *rootp = n;
                        return *rootp;
index 4483bb21c3d6a86440a7877e926124bfaec0b3d4..47b344813264e7bcb4c2e793d4a1d795e2912a4a 100644 (file)
@@ -49,7 +49,7 @@ static int padded_write(struct reftable_writer *w, uint8_t *data, size_t len,
 {
        int n = 0;
        if (w->pending_padding > 0) {
-               uint8_t *zeroed = reftable_calloc(w->pending_padding);
+               uint8_t *zeroed = reftable_calloc(w->pending_padding, sizeof(*zeroed));
                int n = w->write(w->write_arg, zeroed, w->pending_padding);
                if (n < 0)
                        return n;
@@ -123,8 +123,7 @@ struct reftable_writer *
 reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t),
                    void *writer_arg, struct reftable_write_options *opts)
 {
-       struct reftable_writer *wp =
-               reftable_calloc(sizeof(struct reftable_writer));
+       struct reftable_writer *wp = reftable_calloc(1, sizeof(*wp));
        strbuf_init(&wp->block_writer_data.last_key, 0);
        options_set_defaults(opts);
        if (opts->block_size >= (1 << 24)) {
@@ -132,7 +131,7 @@ reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t),
                abort();
        }
        wp->last_key = reftable_empty_strbuf;
-       wp->block = reftable_calloc(opts->block_size);
+       REFTABLE_CALLOC_ARRAY(wp->block, opts->block_size);
        wp->write = writer_func;
        wp->write_arg = writer_arg;
        wp->opts = *opts;