diff --git a/reftable/record.c b/reftable/record.c index 23b497adab..5506f3e913 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -159,6 +159,30 @@ int reftable_encode_key(int *restart, struct string_view dest, return start.len - dest.len; } +int reftable_decode_keylen(struct string_view in, + uint64_t *prefix_len, + uint64_t *suffix_len, + uint8_t *extra) +{ + size_t start_len = in.len; + int n; + + n = get_var_int(prefix_len, &in); + if (n < 0) + return -1; + string_view_consume(&in, n); + + n = get_var_int(suffix_len, &in); + if (n <= 0) + return -1; + string_view_consume(&in, n); + + *extra = (uint8_t)(*suffix_len & 0x7); + *suffix_len >>= 3; + + return start_len - in.len; +} + int reftable_decode_key(struct strbuf *last_key, uint8_t *extra, struct string_view in) { @@ -167,19 +191,11 @@ int reftable_decode_key(struct strbuf *last_key, uint8_t *extra, uint64_t suffix_len = 0; int n; - n = get_var_int(&prefix_len, &in); + n = reftable_decode_keylen(in, &prefix_len, &suffix_len, extra); if (n < 0) return -1; string_view_consume(&in, n); - n = get_var_int(&suffix_len, &in); - if (n <= 0) - return -1; - string_view_consume(&in, n); - - *extra = (uint8_t)(suffix_len & 0x7); - suffix_len >>= 3; - if (in.len < suffix_len || prefix_len > last_key->len) return -1; diff --git a/reftable/record.h b/reftable/record.h index 826ee1c55c..d778133e6e 100644 --- a/reftable/record.h +++ b/reftable/record.h @@ -86,6 +86,12 @@ int reftable_encode_key(int *is_restart, struct string_view dest, struct strbuf prev_key, struct strbuf key, uint8_t extra); +/* Decode a record's key lengths. */ +int reftable_decode_keylen(struct string_view in, + uint64_t *prefix_len, + uint64_t *suffix_len, + uint8_t *extra); + /* * Decode into `last_key` and `extra` from `in`. `last_key` is expected to * contain the decoded key of the preceding record, if any.