diff options
Diffstat (limited to 'reftable/record.c')
| -rw-r--r-- | reftable/record.c | 320 |
1 files changed, 140 insertions, 180 deletions
diff --git a/reftable/record.c b/reftable/record.c index a2cba5ef74..30d563e16d 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -215,13 +215,14 @@ static void reftable_ref_record_key(const void *r, struct strbuf *dest) strbuf_addstr(dest, rec->refname); } -static void reftable_ref_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_ref_record_copy_from(void *rec, const void *src_rec, + int hash_size) { struct reftable_ref_record *ref = rec; const struct reftable_ref_record *src = src_rec; char *refname = NULL; size_t refname_cap = 0; + int err; assert(hash_size > 0); @@ -236,6 +237,11 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec, REFTABLE_ALLOC_GROW(ref->refname, refname_len + 1, ref->refname_cap); + if (!ref->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + memcpy(ref->refname, src->refname, refname_len); ref->refname[refname_len] = 0; } @@ -254,61 +260,17 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec, src->value.val2.target_value, hash_size); break; case REFTABLE_REF_SYMREF: - ref->value.symref = xstrdup(src->value.symref); - break; - } -} - -static char hexdigit(int c) -{ - if (c <= 9) - return '0' + c; - return 'a' + (c - 10); -} - -static void hex_format(char *dest, const unsigned char *src, int hash_size) -{ - assert(hash_size > 0); - if (src) { - int i = 0; - for (i = 0; i < hash_size; i++) { - dest[2 * i] = hexdigit(src[i] >> 4); - dest[2 * i + 1] = hexdigit(src[i] & 0xf); + ref->value.symref = reftable_strdup(src->value.symref); + if (!ref->value.symref) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; } - dest[2 * hash_size] = 0; - } -} - -static void reftable_ref_record_print_sz(const struct reftable_ref_record *ref, - int hash_size) -{ - char hex[GIT_MAX_HEXSZ + 1] = { 0 }; /* BUG */ - printf("ref{%s(%" PRIu64 ") ", ref->refname, ref->update_index); - switch (ref->value_type) { - case REFTABLE_REF_SYMREF: - printf("=> %s", ref->value.symref); - break; - case REFTABLE_REF_VAL2: - hex_format(hex, ref->value.val2.value, hash_size); - printf("val 2 %s", hex); - hex_format(hex, ref->value.val2.target_value, - hash_size); - printf("(T %s)", hex); - break; - case REFTABLE_REF_VAL1: - hex_format(hex, ref->value.val1, hash_size); - printf("val 1 %s", hex); - break; - case REFTABLE_REF_DELETION: - printf("delete"); break; } - printf("}\n"); -} -void reftable_ref_record_print(const struct reftable_ref_record *ref, - uint32_t hash_id) { - reftable_ref_record_print_sz(ref, hash_size(hash_id)); + err = 0; +out: + return err; } static void reftable_ref_record_release_void(void *rec) @@ -397,7 +359,7 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, uint64_t update_index = 0; const char *refname = NULL; size_t refname_cap = 0; - int n; + int n, err; assert(hash_size > 0); @@ -413,6 +375,10 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, SWAP(r->refname_cap, refname_cap); REFTABLE_ALLOC_GROW(r->refname, key.len + 1, r->refname_cap); + if (!r->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } memcpy(r->refname, key.buf, key.len); r->refname[key.len] = 0; @@ -421,7 +387,8 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, switch (val_type) { case REFTABLE_REF_VAL1: if (in.len < hash_size) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } memcpy(r->value.val1, in.buf, hash_size); @@ -430,7 +397,8 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, case REFTABLE_REF_VAL2: if (in.len < 2 * hash_size) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } memcpy(r->value.val2.value, in.buf, hash_size); @@ -443,7 +411,8 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, case REFTABLE_REF_SYMREF: { int n = decode_string(scratch, in); if (n < 0) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } string_view_consume(&in, n); r->value.symref = strbuf_detach(scratch, NULL); @@ -457,6 +426,9 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, } return start.len - in.len; + +done: + return err; } static int reftable_ref_record_is_deletion_void(const void *p) @@ -480,12 +452,6 @@ static int reftable_ref_record_cmp_void(const void *_a, const void *_b) return strcmp(a->refname, b->refname); } -static void reftable_ref_record_print_void(const void *rec, - int hash_size) -{ - reftable_ref_record_print_sz((struct reftable_ref_record *) rec, hash_size); -} - static struct reftable_record_vtable reftable_ref_record_vtable = { .key = &reftable_ref_record_key, .type = BLOCK_TYPE_REF, @@ -497,7 +463,6 @@ static struct reftable_record_vtable reftable_ref_record_vtable = { .is_deletion = &reftable_ref_record_is_deletion_void, .equal = &reftable_ref_record_equal_void, .cmp = &reftable_ref_record_cmp_void, - .print = &reftable_ref_record_print_void, }; static void reftable_obj_record_key(const void *r, struct strbuf *dest) @@ -511,43 +476,33 @@ static void reftable_obj_record_key(const void *r, struct strbuf *dest) static void reftable_obj_record_release(void *rec) { struct reftable_obj_record *obj = rec; - FREE_AND_NULL(obj->hash_prefix); - FREE_AND_NULL(obj->offsets); + REFTABLE_FREE_AND_NULL(obj->hash_prefix); + REFTABLE_FREE_AND_NULL(obj->offsets); memset(obj, 0, sizeof(struct reftable_obj_record)); } -static void reftable_obj_record_print(const void *rec, int hash_size) -{ - const struct reftable_obj_record *obj = rec; - char hex[GIT_MAX_HEXSZ + 1] = { 0 }; - struct strbuf offset_str = STRBUF_INIT; - int i; - - for (i = 0; i < obj->offset_len; i++) - strbuf_addf(&offset_str, "%" PRIu64 " ", obj->offsets[i]); - hex_format(hex, obj->hash_prefix, obj->hash_prefix_len); - printf("prefix %s (len %d), offsets [%s]\n", - hex, obj->hash_prefix_len, offset_str.buf); - strbuf_release(&offset_str); -} - -static void reftable_obj_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_obj_record_copy_from(void *rec, const void *src_rec, + int hash_size UNUSED) { struct reftable_obj_record *obj = rec; - const struct reftable_obj_record *src = - (const struct reftable_obj_record *)src_rec; + const struct reftable_obj_record *src = src_rec; reftable_obj_record_release(obj); REFTABLE_ALLOC_ARRAY(obj->hash_prefix, src->hash_prefix_len); + if (!obj->hash_prefix) + return REFTABLE_OUT_OF_MEMORY_ERROR; obj->hash_prefix_len = src->hash_prefix_len; if (src->hash_prefix_len) memcpy(obj->hash_prefix, src->hash_prefix, obj->hash_prefix_len); REFTABLE_ALLOC_ARRAY(obj->offsets, src->offset_len); + if (!obj->offsets) + return REFTABLE_OUT_OF_MEMORY_ERROR; obj->offset_len = src->offset_len; COPY_ARRAY(obj->offsets, src->offsets, src->offset_len); + + return 0; } static uint8_t reftable_obj_record_val_type(const void *rec) @@ -559,7 +514,7 @@ static uint8_t reftable_obj_record_val_type(const void *rec) } static int reftable_obj_record_encode(const void *rec, struct string_view s, - int hash_size) + int hash_size UNUSED) { const struct reftable_obj_record *r = rec; struct string_view start = s; @@ -594,7 +549,8 @@ static int reftable_obj_record_encode(const void *rec, struct string_view s, static int reftable_obj_record_decode(void *rec, struct strbuf key, uint8_t val_type, struct string_view in, - int hash_size, struct strbuf *scratch UNUSED) + int hash_size UNUSED, + struct strbuf *scratch UNUSED) { struct string_view start = in; struct reftable_obj_record *r = rec; @@ -606,6 +562,8 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, reftable_obj_record_release(r); REFTABLE_ALLOC_ARRAY(r->hash_prefix, key.len); + if (!r->hash_prefix) + return REFTABLE_OUT_OF_MEMORY_ERROR; memcpy(r->hash_prefix, key.buf, key.len); r->hash_prefix_len = key.len; @@ -624,6 +582,8 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, return start.len - in.len; REFTABLE_ALLOC_ARRAY(r->offsets, count); + if (!r->offsets) + return REFTABLE_OUT_OF_MEMORY_ERROR; r->offset_len = count; n = get_var_int(&r->offsets[0], &in); @@ -647,12 +607,13 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, return start.len - in.len; } -static int not_a_deletion(const void *p) +static int not_a_deletion(const void *p UNUSED) { return 0; } -static int reftable_obj_record_equal_void(const void *a, const void *b, int hash_size) +static int reftable_obj_record_equal_void(const void *a, const void *b, + int hash_size UNUSED) { struct reftable_obj_record *ra = (struct reftable_obj_record *) a; struct reftable_obj_record *rb = (struct reftable_obj_record *) b; @@ -701,41 +662,8 @@ static struct reftable_record_vtable reftable_obj_record_vtable = { .is_deletion = ¬_a_deletion, .equal = &reftable_obj_record_equal_void, .cmp = &reftable_obj_record_cmp_void, - .print = &reftable_obj_record_print, }; -static void reftable_log_record_print_sz(struct reftable_log_record *log, - int hash_size) -{ - char hex[GIT_MAX_HEXSZ + 1] = { 0 }; - - switch (log->value_type) { - case REFTABLE_LOG_DELETION: - printf("log{%s(%" PRIu64 ") delete\n", log->refname, - log->update_index); - break; - case REFTABLE_LOG_UPDATE: - printf("log{%s(%" PRIu64 ") %s <%s> %" PRIu64 " %04d\n", - log->refname, log->update_index, - log->value.update.name ? log->value.update.name : "", - log->value.update.email ? log->value.update.email : "", - log->value.update.time, - log->value.update.tz_offset); - hex_format(hex, log->value.update.old_hash, hash_size); - printf("%s => ", hex); - hex_format(hex, log->value.update.new_hash, hash_size); - printf("%s\n\n%s\n}\n", hex, - log->value.update.message ? log->value.update.message : ""); - break; - } -} - -void reftable_log_record_print(struct reftable_log_record *log, - uint32_t hash_id) -{ - reftable_log_record_print_sz(log, hash_size(hash_id)); -} - static void reftable_log_record_key(const void *r, struct strbuf *dest) { const struct reftable_log_record *rec = @@ -751,33 +679,44 @@ static void reftable_log_record_key(const void *r, struct strbuf *dest) strbuf_add(dest, i64, sizeof(i64)); } -static void reftable_log_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_log_record_copy_from(void *rec, const void *src_rec, + int hash_size) { struct reftable_log_record *dst = rec; const struct reftable_log_record *src = (const struct reftable_log_record *)src_rec; + int ret; reftable_log_record_release(dst); *dst = *src; + if (dst->refname) { - dst->refname = xstrdup(dst->refname); + dst->refname = reftable_strdup(dst->refname); + if (!dst->refname) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } } + switch (dst->value_type) { case REFTABLE_LOG_DELETION: break; case REFTABLE_LOG_UPDATE: - if (dst->value.update.email) { + if (dst->value.update.email) dst->value.update.email = - xstrdup(dst->value.update.email); - } - if (dst->value.update.name) { + reftable_strdup(dst->value.update.email); + if (dst->value.update.name) dst->value.update.name = - xstrdup(dst->value.update.name); - } - if (dst->value.update.message) { + reftable_strdup(dst->value.update.name); + if (dst->value.update.message) dst->value.update.message = - xstrdup(dst->value.update.message); + reftable_strdup(dst->value.update.message); + + if (!dst->value.update.email || + !dst->value.update.name || + !dst->value.update.message) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; } memcpy(dst->value.update.new_hash, @@ -786,6 +725,10 @@ static void reftable_log_record_copy_from(void *rec, const void *src_rec, src->value.update.old_hash, hash_size); break; } + + ret = 0; +out: + return ret; } static void reftable_log_record_release_void(void *rec) @@ -872,12 +815,17 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, struct reftable_log_record *r = rec; uint64_t max = 0; uint64_t ts = 0; - int n; + int err, n; if (key.len <= 9 || key.buf[key.len - 9] != 0) return REFTABLE_FORMAT_ERROR; REFTABLE_ALLOC_GROW(r->refname, key.len - 8, r->refname_cap); + if (!r->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + memcpy(r->refname, key.buf, key.len - 8); ts = get_be64(key.buf + key.len - 8); @@ -886,10 +834,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, if (val_type != r->value_type) { switch (r->value_type) { case REFTABLE_LOG_UPDATE: - FREE_AND_NULL(r->value.update.message); + REFTABLE_FREE_AND_NULL(r->value.update.message); r->value.update.message_cap = 0; - FREE_AND_NULL(r->value.update.email); - FREE_AND_NULL(r->value.update.name); + REFTABLE_FREE_AND_NULL(r->value.update.email); + REFTABLE_FREE_AND_NULL(r->value.update.name); break; case REFTABLE_LOG_DELETION: break; @@ -900,8 +848,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, if (val_type == REFTABLE_LOG_DELETION) return 0; - if (in.len < 2 * hash_size) - return REFTABLE_FORMAT_ERROR; + if (in.len < 2 * hash_size) { + err = REFTABLE_FORMAT_ERROR; + goto done; + } memcpy(r->value.update.old_hash, in.buf, hash_size); memcpy(r->value.update.new_hash, in.buf + hash_size, hash_size); @@ -909,8 +859,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, string_view_consume(&in, 2 * hash_size); n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); /* @@ -921,52 +873,75 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, */ if (!r->value.update.name || strcmp(r->value.update.name, scratch->buf)) { - r->value.update.name = - reftable_realloc(r->value.update.name, scratch->len + 1); + char *name = reftable_realloc(r->value.update.name, scratch->len + 1); + if (!name) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + + r->value.update.name = name; memcpy(r->value.update.name, scratch->buf, scratch->len); r->value.update.name[scratch->len] = 0; } n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); /* Same as above, but for the reflog email. */ if (!r->value.update.email || strcmp(r->value.update.email, scratch->buf)) { - r->value.update.email = - reftable_realloc(r->value.update.email, scratch->len + 1); + char *email = reftable_realloc(r->value.update.email, scratch->len + 1); + if (!email) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + + r->value.update.email = email; memcpy(r->value.update.email, scratch->buf, scratch->len); r->value.update.email[scratch->len] = 0; } ts = 0; n = get_var_int(&ts, &in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); r->value.update.time = ts; - if (in.len < 2) + if (in.len < 2) { + err = REFTABLE_FORMAT_ERROR; goto done; + } r->value.update.tz_offset = get_be16(in.buf); string_view_consume(&in, 2); n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); REFTABLE_ALLOC_GROW(r->value.update.message, scratch->len + 1, r->value.update.message_cap); + if (!r->value.update.message) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + memcpy(r->value.update.message, scratch->buf, scratch->len); r->value.update.message[scratch->len] = 0; return start.len - in.len; done: - return REFTABLE_FORMAT_ERROR; + return err; } static int null_streq(const char *a, const char *b) @@ -1039,11 +1014,6 @@ static int reftable_log_record_is_deletion_void(const void *p) (const struct reftable_log_record *)p); } -static void reftable_log_record_print_void(const void *rec, int hash_size) -{ - reftable_log_record_print_sz((struct reftable_log_record*)rec, hash_size); -} - static struct reftable_record_vtable reftable_log_record_vtable = { .key = &reftable_log_record_key, .type = BLOCK_TYPE_LOG, @@ -1055,7 +1025,6 @@ static struct reftable_record_vtable reftable_log_record_vtable = { .is_deletion = &reftable_log_record_is_deletion_void, .equal = &reftable_log_record_equal_void, .cmp = &reftable_log_record_cmp_void, - .print = &reftable_log_record_print_void, }; static void reftable_index_record_key(const void *r, struct strbuf *dest) @@ -1065,8 +1034,8 @@ static void reftable_index_record_key(const void *r, struct strbuf *dest) strbuf_addbuf(dest, &rec->last_key); } -static void reftable_index_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_index_record_copy_from(void *rec, const void *src_rec, + int hash_size UNUSED) { struct reftable_index_record *dst = rec; const struct reftable_index_record *src = src_rec; @@ -1074,6 +1043,8 @@ static void reftable_index_record_copy_from(void *rec, const void *src_rec, strbuf_reset(&dst->last_key); strbuf_addbuf(&dst->last_key, &src->last_key); dst->offset = src->offset; + + return 0; } static void reftable_index_record_release(void *rec) @@ -1082,13 +1053,13 @@ static void reftable_index_record_release(void *rec) strbuf_release(&idx->last_key); } -static uint8_t reftable_index_record_val_type(const void *rec) +static uint8_t reftable_index_record_val_type(const void *rec UNUSED) { return 0; } static int reftable_index_record_encode(const void *rec, struct string_view out, - int hash_size) + int hash_size UNUSED) { const struct reftable_index_record *r = (const struct reftable_index_record *)rec; @@ -1104,8 +1075,10 @@ static int reftable_index_record_encode(const void *rec, struct string_view out, } static int reftable_index_record_decode(void *rec, struct strbuf key, - uint8_t val_type, struct string_view in, - int hash_size, struct strbuf *scratch UNUSED) + uint8_t val_type UNUSED, + struct string_view in, + int hash_size UNUSED, + struct strbuf *scratch UNUSED) { struct string_view start = in; struct reftable_index_record *r = rec; @@ -1122,7 +1095,8 @@ static int reftable_index_record_decode(void *rec, struct strbuf key, return start.len - in.len; } -static int reftable_index_record_equal(const void *a, const void *b, int hash_size) +static int reftable_index_record_equal(const void *a, const void *b, + int hash_size UNUSED) { struct reftable_index_record *ia = (struct reftable_index_record *) a; struct reftable_index_record *ib = (struct reftable_index_record *) b; @@ -1137,13 +1111,6 @@ static int reftable_index_record_cmp(const void *_a, const void *_b) return strbuf_cmp(&a->last_key, &b->last_key); } -static void reftable_index_record_print(const void *rec, int hash_size) -{ - const struct reftable_index_record *idx = rec; - /* TODO: escape null chars? */ - printf("\"%s\" %" PRIu64 "\n", idx->last_key.buf, idx->offset); -} - static struct reftable_record_vtable reftable_index_record_vtable = { .key = &reftable_index_record_key, .type = BLOCK_TYPE_INDEX, @@ -1155,7 +1122,6 @@ static struct reftable_record_vtable reftable_index_record_vtable = { .is_deletion = ¬_a_deletion, .equal = &reftable_index_record_equal, .cmp = &reftable_index_record_cmp, - .print = &reftable_index_record_print, }; void reftable_record_key(struct reftable_record *rec, struct strbuf *dest) @@ -1170,14 +1136,14 @@ int reftable_record_encode(struct reftable_record *rec, struct string_view dest, dest, hash_size); } -void reftable_record_copy_from(struct reftable_record *rec, +int reftable_record_copy_from(struct reftable_record *rec, struct reftable_record *src, int hash_size) { assert(src->type == rec->type); - reftable_record_vtable(rec)->copy_from(reftable_record_data(rec), - reftable_record_data(src), - hash_size); + return reftable_record_vtable(rec)->copy_from(reftable_record_data(rec), + reftable_record_data(src), + hash_size); } uint8_t reftable_record_val_type(struct reftable_record *rec) @@ -1334,9 +1300,3 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ) BUG("unhandled record type"); } } - -void reftable_record_print(struct reftable_record *rec, int hash_size) -{ - printf("'%c': ", rec->type); - reftable_record_vtable(rec)->print(reftable_record_data(rec), hash_size); -} |
