From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: Re: [RFC] cocci: .buf in a strbuf object can never be NULL
Date: Fri, 20 Mar 2026 00:18:03 -0400 [thread overview]
Message-ID: <20260320041803.GA18125@coredump.intra.peff.net> (raw)
In-Reply-To: <xmqqcy0zgtmu.fsf@gitster.g>
On Thu, Mar 19, 2026 at 06:46:33PM -0700, Junio C Hamano wrote:
> > diff --git a/strbuf.c b/strbuf.c
> > index 3939863cf3..0333aea261 100644
> > --- a/strbuf.c
> > +++ b/strbuf.c
> > @@ -631,6 +631,8 @@ int strbuf_getcwd(struct strbuf *sb)
> > #ifdef HAVE_GETDELIM
> > int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
> > {
> > + char *buf;
> > + size_t alloc;
> > ssize_t r;
> >
> > if (feof(fp))
> > @@ -639,12 +641,14 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
> > strbuf_reset(sb);
> >
> > /* Translate slopbuf to NULL, as we cannot call realloc on it */
> > - if (!sb->alloc)
> > - sb->buf = NULL;
> > + alloc = sb->alloc;
> > + buf = alloc ? sb->buf : NULL;
> > errno = 0;
>
> I actually was hoping that all lines in this hunk before this point
> can be removed, i.e., strbuf_release(sb), buf = NULL, alloc = 0.
I'm not quite sure what you mean. The function right now looks like:
ssize_t r;
if (feof(fp))
return EOF;
strbuf_reset(sb);
/* Translate slopbuf to NULL, as we cannot call realloc on it */
if (!sb->alloc)
sb->buf = NULL;
errno = 0;
I think the strbuf_reset() could go away even without any other changes.
We always adjust sb->len in the end to match what happened with
getdelim(), so there is no point in doing it up front.
We could strbuf_release() and set buf to NULL, but that would defeat the
purpose of the function, wouldn't it? We want to reuse sb->buf in each
call, not allocate it fresh each time. I.e., in a loop like:
while (strbuf_getline(&sb) != EOF) {
...look at sb.buf...
}
we want to use the same buffer over and over.
> > @@ -669,10 +673,13 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
> > * we can just re-init, but otherwise we should make sure that our
> > * length is empty, and that the result is NUL-terminated.
> > */
> > - if (!sb->buf)
> > + if (!buf)
> > strbuf_init(sb, 0);
> > - else
> > - strbuf_reset(sb);
> > + else {
> > + sb->buf = buf;
> > + sb->alloc = alloc;
> > + strbuf_reset(&sb);
> > + }
>
> I do not get all these conditionals. This is an EOF code path; we
> have no data in buf to return. We resetted the caller's strbuf
> already. Can't we return buf (if allocated) to the system and
> return without doing any further damage to sb at this point?
The conditional is trying to keep any allocated buffer returned from
getdelim() attached to the strbuf. Since this is EOF (or error), I agree
it would probably be OK to just free it. Even in a loop like the one
above, the loop will generally end at EOF, and we don't care about
reusing the buffer further.
But it's not quite enough to just do:
free(buf);
Because "buf" is a copy of sb->buf, and we handed "buf" off to
getdelim(), we need to make sure sb->buf is not still pointing there. I
think it would be enough to do:
free(buf);
strbuf_init(sb, 0);
If we did a strbuf_release() at the top of the function then that is not
a concern (you know that sb->buf is pointing at the slopbuf). But I
don't think that is a good idea for the reason I gave above.
-Peff
next prev parent reply other threads:[~2026-03-20 4:18 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-19 7:15 [PATCH] rerere: update to modern representation of empty strbufs Junio C Hamano
2026-03-19 7:57 ` Patrick Steinhardt
2026-03-19 22:14 ` [RFC] cocci: .buf in a strbuf object can never be NULL Junio C Hamano
2026-03-19 23:35 ` Jeff King
2026-03-20 1:46 ` Junio C Hamano
2026-03-20 4:18 ` Jeff King [this message]
2026-03-20 5:45 ` Junio C Hamano
2026-03-20 5:57 ` Jeff King
2026-03-20 6:06 ` Junio C Hamano
2026-03-20 6:18 ` Jeff King
2026-03-21 13:14 ` René Scharfe
2026-03-21 16:41 ` Jeff King
2026-03-21 20:47 ` René Scharfe
2026-03-21 21:18 ` Jeff King
2026-03-21 23:41 ` René Scharfe
2026-03-22 1:44 ` Jeff King
2026-03-22 1:22 ` Junio C Hamano
2026-03-22 1:40 ` Jeff King
2026-03-21 16:24 ` Junio C Hamano
2026-03-21 16:39 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260320041803.GA18125@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox