Skip to content

Commit 45c2fcc

Browse files
hanwengitster
authored andcommitted
reftable: avoid writing empty keys at the block layer
The public interface (reftable_writer) already ensures that keys are written in strictly increasing order, and an empty key by definition fails this check. However, by also enforcing this at the block layer, it is easier to verify that records (which are written into blocks) never have to consider the possibility of empty keys. Signed-off-by: Han-Wen Nienhuys <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1407659 commit 45c2fcc

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

reftable/block.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@ uint8_t block_writer_type(struct block_writer *bw)
8888
return bw->buf[bw->header_off];
8989
}
9090

91-
/* adds the reftable_record to the block. Returns -1 if it does not fit, 0 on
92-
success */
91+
/* Adds the reftable_record to the block. Returns -1 if it does not fit, 0 on
92+
success. Returns REFTABLE_API_ERROR if attempting to write a record with
93+
empty key. */
9394
int block_writer_add(struct block_writer *w, struct reftable_record *rec)
9495
{
9596
struct strbuf empty = STRBUF_INIT;
@@ -105,8 +106,14 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
105106
int is_restart = 0;
106107
struct strbuf key = STRBUF_INIT;
107108
int n = 0;
109+
int err = -1;
108110

109111
reftable_record_key(rec, &key);
112+
if (!key.len) {
113+
err = REFTABLE_API_ERROR;
114+
goto done;
115+
}
116+
110117
n = reftable_encode_key(&is_restart, out, last, key,
111118
reftable_record_val_type(rec));
112119
if (n < 0)
@@ -118,16 +125,11 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
118125
goto done;
119126
string_view_consume(&out, n);
120127

121-
if (block_writer_register_restart(w, start.len - out.len, is_restart,
122-
&key) < 0)
123-
goto done;
124-
125-
strbuf_release(&key);
126-
return 0;
127-
128+
err = block_writer_register_restart(w, start.len - out.len, is_restart,
129+
&key);
128130
done:
129131
strbuf_release(&key);
130-
return -1;
132+
return err;
131133
}
132134

133135
int block_writer_finish(struct block_writer *w)
@@ -332,6 +334,9 @@ int block_iter_next(struct block_iter *it, struct reftable_record *rec)
332334
if (n < 0)
333335
return -1;
334336

337+
if (!key.len)
338+
return REFTABLE_FORMAT_ERROR;
339+
335340
string_view_consume(&in, n);
336341
n = reftable_record_decode(rec, key, extra, in, it->br->hash_size);
337342
if (n < 0)
@@ -358,6 +363,8 @@ int block_reader_first_key(struct block_reader *br, struct strbuf *key)
358363
int n = reftable_decode_key(key, &extra, empty, in);
359364
if (n < 0)
360365
return n;
366+
if (!key->len)
367+
return REFTABLE_FORMAT_ERROR;
361368

362369
return 0;
363370
}

reftable/block_test.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ static void test_block_read_write(void)
4242
block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size,
4343
header_off, hash_size(GIT_SHA1_FORMAT_ID));
4444

45+
rec.u.ref.refname = "";
46+
rec.u.ref.value_type = REFTABLE_REF_DELETION;
47+
n = block_writer_add(&bw, &rec);
48+
EXPECT(n == REFTABLE_API_ERROR);
49+
4550
for (i = 0; i < N; i++) {
4651
char name[100];
4752
uint8_t hash[GIT_SHA1_RAWSZ];

reftable/writer.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,14 +240,13 @@ static int writer_add_record(struct reftable_writer *w,
240240

241241
writer_reinit_block_writer(w, reftable_record_type(rec));
242242
err = block_writer_add(w->block_writer, rec);
243-
if (err < 0) {
243+
if (err == -1) {
244244
/* we are writing into memory, so an error can only mean it
245245
* doesn't fit. */
246246
err = REFTABLE_ENTRY_TOO_BIG_ERROR;
247247
goto done;
248248
}
249249

250-
err = 0;
251250
done:
252251
strbuf_release(&key);
253252
return err;

0 commit comments

Comments
 (0)