Skip to content

Commit f4ef517

Browse files
peffgitster
authored andcommitted
determine_author_info(): copy getenv output
When figuring out the author name for a commit, we may end up either pointing to const storage from getenv("GIT_AUTHOR_*"), or to newly allocated storage based on an existing commit or the --author option. Using const pointers to getenv's return has two problems: 1. It is not guaranteed that the return value from getenv remains valid across multiple calls. 2. We do not know whether to free the values at the end, so we just leak them. We can solve both by duplicating the string returned by getenv(). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent f0f9662 commit f4ef517

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

builtin/commit.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -535,15 +535,26 @@ static int parse_force_date(const char *in, struct strbuf *out)
535535
return 0;
536536
}
537537

538+
static void set_ident_var(char **buf, char *val)
539+
{
540+
free(*buf);
541+
*buf = val;
542+
}
543+
544+
static char *envdup(const char *var)
545+
{
546+
const char *val = getenv(var);
547+
return val ? xstrdup(val) : NULL;
548+
}
549+
538550
static void determine_author_info(struct strbuf *author_ident)
539551
{
540552
char *name, *email, *date;
541553
struct ident_split author;
542-
struct strbuf date_buf = STRBUF_INIT;
543554

544-
name = getenv("GIT_AUTHOR_NAME");
545-
email = getenv("GIT_AUTHOR_EMAIL");
546-
date = getenv("GIT_AUTHOR_DATE");
555+
name = envdup("GIT_AUTHOR_NAME");
556+
email = envdup("GIT_AUTHOR_EMAIL");
557+
date = envdup("GIT_AUTHOR_DATE");
547558

548559
if (author_message) {
549560
struct ident_split ident;
@@ -556,15 +567,16 @@ static void determine_author_info(struct strbuf *author_ident)
556567
if (split_ident_line(&ident, a, len) < 0)
557568
die(_("commit '%s' has malformed author line"), author_message);
558569

559-
name = xmemdupz(ident.name_begin, ident.name_end - ident.name_begin);
560-
email = xmemdupz(ident.mail_begin, ident.mail_end - ident.mail_begin);
570+
set_ident_var(&name, xmemdupz(ident.name_begin, ident.name_end - ident.name_begin));
571+
set_ident_var(&email, xmemdupz(ident.mail_begin, ident.mail_end - ident.mail_begin));
572+
561573
if (ident.date_begin) {
562-
strbuf_reset(&date_buf);
574+
struct strbuf date_buf = STRBUF_INIT;
563575
strbuf_addch(&date_buf, '@');
564576
strbuf_add(&date_buf, ident.date_begin, ident.date_end - ident.date_begin);
565577
strbuf_addch(&date_buf, ' ');
566578
strbuf_add(&date_buf, ident.tz_begin, ident.tz_end - ident.tz_begin);
567-
date = date_buf.buf;
579+
set_ident_var(&date, strbuf_detach(&date_buf, NULL));
568580
}
569581
}
570582

@@ -573,15 +585,15 @@ static void determine_author_info(struct strbuf *author_ident)
573585

574586
if (split_ident_line(&ident, force_author, strlen(force_author)) < 0)
575587
die(_("malformed --author parameter"));
576-
name = xmemdupz(ident.name_begin, ident.name_end - ident.name_begin);
577-
email = xmemdupz(ident.mail_begin, ident.mail_end - ident.mail_begin);
588+
set_ident_var(&name, xmemdupz(ident.name_begin, ident.name_end - ident.name_begin));
589+
set_ident_var(&email, xmemdupz(ident.mail_begin, ident.mail_end - ident.mail_begin));
578590
}
579591

580592
if (force_date) {
581-
strbuf_reset(&date_buf);
593+
struct strbuf date_buf = STRBUF_INIT;
582594
if (parse_force_date(force_date, &date_buf))
583595
die(_("invalid date format: %s"), force_date);
584-
date = date_buf.buf;
596+
set_ident_var(&date, strbuf_detach(&date_buf, NULL));
585597
}
586598

587599
strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT));
@@ -592,7 +604,9 @@ static void determine_author_info(struct strbuf *author_ident)
592604
export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@');
593605
}
594606

595-
strbuf_release(&date_buf);
607+
free(name);
608+
free(email);
609+
free(date);
596610
}
597611

598612
static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf)

0 commit comments

Comments
 (0)