aboutsummaryrefslogtreecommitdiffstats
path: root/reftable/record.c
diff options
context:
space:
mode:
Diffstat (limited to 'reftable/record.c')
-rw-r--r--reftable/record.c320
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 = &not_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 = &not_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);
-}