Skip to content

Commit 3931216

Browse files
pks-tgitster
authored andcommitted
refs: fully reset struct ref_iterator::ref on iteration
With the introduction of the `struct ref_iterator::ref` field it now is a whole lot easier to introduce new fields that become accessible to the caller without having to adapt every single callsite. But there's a downside: when a new field is introduced we always have to adapt all backends to set that field. This isn't something we can avoid in the general case: when the new field is expected to be populated by all backends we of course cannot avoid doing so. But new fields may be entirely optional, in which case we'd still have such churn. And furthermore, it is very easy right now to leak state from a previous iteration into the next iteration. Address this issue by ensuring that the reference backends all fully reset the field on every single iteration. This ensures that no state from previous iterations can leak into the next one. And it ensures that any newly introduced fields will be zeroed out by default. Note that we don't have to explicitly adapt the "files" backend, as it uses the `cache_ref_iterator` internally. Furthermore, other "wrapping" iterators like for example the `prefix_ref_iterator` copy around the whole reference, so these don't need to be adapted either. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 203ecb8 commit 3931216

File tree

3 files changed

+4
-1
lines changed

3 files changed

+4
-1
lines changed

refs/packed-backend.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,7 @@ static int next_record(struct packed_ref_iterator *iter)
882882
{
883883
const char *p, *eol;
884884

885+
memset(&iter->base.ref, 0, sizeof(iter->base.ref));
885886
strbuf_reset(&iter->refname_buf);
886887

887888
/*
@@ -916,6 +917,7 @@ static int next_record(struct packed_ref_iterator *iter)
916917
!isspace(*p++))
917918
die_invalid_line(iter->snapshot->refs->path,
918919
iter->pos, iter->eof - iter->pos);
920+
iter->base.ref.oid = &iter->oid;
919921

920922
eol = memchr(p, '\n', iter->eof - p);
921923
if (!eol)
@@ -1194,7 +1196,6 @@ static struct ref_iterator *packed_ref_iterator_begin(
11941196
iter->snapshot = snapshot;
11951197
acquire_snapshot(snapshot);
11961198
strbuf_init(&iter->refname_buf, 0);
1197-
iter->base.ref.oid = &iter->oid;
11981199
iter->repo = ref_store->repo;
11991200
iter->flags = flags;
12001201

refs/ref-cache.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator)
425425
level->prefix_state = entry_prefix_state;
426426
level->index = -1;
427427
} else {
428+
memset(&iter->base.ref, 0, sizeof(iter->base.ref));
428429
iter->base.ref.name = entry->name;
429430
iter->base.ref.target = entry->u.value.referent;
430431
iter->base.ref.oid = &entry->u.value.oid;

refs/reftable-backend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,7 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
703703
&iter->oid, flags))
704704
continue;
705705

706+
memset(&iter->base.ref, 0, sizeof(iter->base.ref));
706707
iter->base.ref.name = iter->ref.refname;
707708
iter->base.ref.target = referent;
708709
iter->base.ref.oid = &iter->oid;

0 commit comments

Comments
 (0)