diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2017-05-22 16:17:35 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-05-23 14:29:52 +0900 |
commit | b9c8e7f2fb6ee19defeaa2927a0af42b525d8b33 (patch) | |
tree | 95c057da36e50b4b34fe9a48f538020c6fb85b7d /refs | |
parent | 04aea8d4df199836da3802f08cb5738eae66fa6c (diff) | |
download | git-b9c8e7f2fb6ee19defeaa2927a0af42b525d8b33.tar.gz |
prefix_ref_iterator: don't trim too much
The `trim` parameter can be set independently of `prefix`. So if some
caller were to set `trim` to be greater than `strlen(prefix)`, we
could end up pointing the `refname` field of the iterator past the NUL
of the actual reference name string.
That can't happen currently, because `trim` is always set either to
zero or to `strlen(prefix)`. But even the latter could lead to
confusion, if a refname is exactly equal to the prefix, because then
we would set the outgoing `refname` to the empty string.
And we're about to decouple the `prefix` and `trim` arguments even
more, so let's be cautious here. Report a bug if ever asked to trim a
reference whose name is not longer than `trim`.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs')
-rw-r--r-- | refs/iterator.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/refs/iterator.c b/refs/iterator.c index bce1f192f7..4cf449ef66 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -292,7 +292,23 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) if (!starts_with(iter->iter0->refname, iter->prefix)) continue; - iter->base.refname = iter->iter0->refname + iter->trim; + if (iter->trim) { + /* + * It is nonsense to trim off characters that + * you haven't already checked for via a + * prefix check, whether via this + * `prefix_ref_iterator` or upstream in + * `iter0`). So if there wouldn't be at least + * one character left in the refname after + * trimming, report it as a bug: + */ + if (strlen(iter->iter0->refname) <= iter->trim) + die("BUG: attempt to trim too many characters"); + iter->base.refname = iter->iter0->refname + iter->trim; + } else { + iter->base.refname = iter->iter0->refname; + } + iter->base.oid = iter->iter0->oid; iter->base.flags = iter->iter0->flags; return ITER_OK; |