Skip to content

Commit 8c74ef1

Browse files
trastgitster
authored andcommitted
strbuf_grow(): maintain nul-termination even for new buffer
In the case where sb is initialized to the slopbuf (through strbuf_init(sb,0) or STRBUF_INIT), strbuf_grow() loses the terminating nul: it grows the buffer, but gives ALLOC_GROW a NULL source to avoid it being freed. So ALLOC_GROW does not copy anything to the new memory area. This subtly broke the call to strbuf_getline in read_next_command() [fast-import.c:1855], which goes strbuf_detach(&command_buf, NULL); # command_buf is now = STRBUF_INIT stdin_eof = strbuf_getline(&command_buf, stdin, '\n'); if (stdin_eof) return EOF; In strbuf_getwholeline, this did strbuf_grow(sb, 0); # loses nul-termination if (feof(fp)) return EOF; strbuf_reset(sb); # this would have nul-terminated! Valgrind found this because fast-import subsequently uses prefixcmp() on command_buf.buf, which after the EOF exit contains only uninitialized memory. Arguably strbuf_getwholeline is also broken, in that it touches the buffer before deciding whether to do any work. However, it seems more futureproof to not let the strbuf API lose the nul-termination by its own fault. So make sure that strbuf_grow() puts in a nul even if it has nowhere to copy it from. This makes strbuf_grow(sb, 0) a semantic no-op as far as readers of the buffer are concerned. Also remove the nul-termination added by strbuf_init, which is made redudant. Signed-off-by: Thomas Rast <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f696543 commit 8c74ef1

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

strbuf.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,8 @@ void strbuf_init(struct strbuf *sb, size_t hint)
3030
{
3131
sb->alloc = sb->len = 0;
3232
sb->buf = strbuf_slopbuf;
33-
if (hint) {
33+
if (hint)
3434
strbuf_grow(sb, hint);
35-
sb->buf[0] = '\0';
36-
}
3735
}
3836

3937
void strbuf_release(struct strbuf *sb)
@@ -65,12 +63,15 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
6563

6664
void strbuf_grow(struct strbuf *sb, size_t extra)
6765
{
66+
int new_buf = !sb->alloc;
6867
if (unsigned_add_overflows(extra, 1) ||
6968
unsigned_add_overflows(sb->len, extra + 1))
7069
die("you want to use way too much memory");
71-
if (!sb->alloc)
70+
if (new_buf)
7271
sb->buf = NULL;
7372
ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
73+
if (new_buf)
74+
sb->buf[0] = '\0';
7475
}
7576

7677
void strbuf_trim(struct strbuf *sb)

0 commit comments

Comments
 (0)