Re: [RFC] cocci: .buf in a strbuf object can never be NULL
- From
René Scharfe <l.s.r@web.de>
- Date
- Mar 21, 2026, 20:47 UTC
- Message-ID
- <3e387439-c066-4e45-b28b-43f77c8824d6@web.de>
- In-Reply-To
- <20260319233546.GA3632561@coredump.intra.peff.net>
On 3/20/26 12:35 AM, Jeff King wrote:
Show 25 quoted lines
>
> @@ -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);
> + }
> return EOF;
> }
> #else
>
> So I don't know that it makes anything simpler. We have to copy the
> values back into the strbuf either way, and we still have to handle
> restoring the strbuf invariants. Even the strbuf_init() case is still
> needed, because we don't know whether getdelim() just didn't allocate
> (in which case we could leave the strbuf alone) or if it actually ate
> the allocation we passed in (which was just a copy of sb->buf).And yet this function can turn an empty strbuf into an allocated one without rolling it back on error, leaving code similar to this silly example here leaking:
int copy_one_line(FILE *in, FILE *out, int term)
{
struct strbuf sb = STRBUF_INIT;
if (strbuf_getwholeline(&sb, in, term))
return -1;
fwrite(sb.buf, 1, sb.len, out);
strbuf_release(&sb);
return 0;
}Some strbuf functions restore the original state in such a case by calling strbuf_release(), strbuf_getwholeline() doesn't. If we are OK with that then it could be simplified by growing the buffer upfront:
int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term)
{
ssize_t r;strbuf_grow(sb, 0); errno = 0; r = getdelim(&sb->buf, &sb->alloc, term, fp);
if (r > 0) {
sb->len = r;
return 0;
} assert(r == -1);
if (errno == ENOMEM)
die("Out of memory, getdelim failed");
strbuf_reset(sb);
return EOF;
}René