summaryrefslogtreecommitdiff
path: root/strbuf.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2012-10-18 06:00:12 -0400
committerJunio C Hamano <gitster@pobox.com>2012-10-18 09:40:15 -0700
commit08ad56f3f0c1df8f75bac84bcef0d9d0c9b4d20f (patch)
treece27466c7455ee68fb1ac2b6f6d03367fcdb72bb /strbuf.c
parent785ee4960c3d334cbc2b17ab74d2cebdf1b4db64 (diff)
downloadgit-08ad56f3f0c1df8f75bac84bcef0d9d0c9b4d20f.tar.gz
strbuf: always return a non-NULL value from strbuf_detach
The current behavior is to return NULL when strbuf did not actually allocate a string. This can be quite surprising to callers, though, who may feed the strbuf from arbitrary data and expect to always get a valid value. In most cases, it does not make a difference because calling any strbuf function will cause an allocation (even if the function ends up not inserting any data). But if the code is structured like: struct strbuf buf = STRBUF_INIT; if (some_condition) strbuf_addstr(&buf, some_string); return strbuf_detach(&buf, NULL); then you may or may not return NULL, depending on the condition. This can cause us to segfault in http-push (when fed an empty URL) and in http-backend (when an empty parameter like "foo=bar&&" is in the $QUERY_STRING). This patch forces strbuf_detach to allocate an empty NUL-terminated string when it is called on a strbuf that has not been allocated. I investigated all call-sites of strbuf_detach. The majority are either not affected by the change (because they call a strbuf_* function unconditionally), or can handle the empty string just as easily as NULL. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'strbuf.c')
-rw-r--r--strbuf.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/strbuf.c b/strbuf.c
index 5135d5950d..5427cfdc65 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -44,7 +44,9 @@ void strbuf_release(struct strbuf *sb)
char *strbuf_detach(struct strbuf *sb, size_t *sz)
{
- char *res = sb->alloc ? sb->buf : NULL;
+ char *res;
+ strbuf_grow(sb, 0);
+ res = sb->buf;
if (sz)
*sz = sb->len;
strbuf_init(sb, 0);