Skip to content

Commit bccce0f

Browse files
jiangxingitster
authored andcommitted
blame: fix broken time_buf paddings in relative timestamp
Command `git blame --date relative` aligns the date field with a fixed-width (defined by blame_date_width), and if time_str is shorter than that, it adds spaces for padding. But there are two bugs in the following codes: time_len = strlen(time_str); ... memset(time_buf + time_len, ' ', blame_date_width - time_len); 1. The type of blame_date_width is size_t, which is unsigned. If time_len is greater than blame_date_width, the result of "blame_date_width - time_len" will never be a negative number, but a really big positive number, and will cause memory overwrite. This bug can be triggered if either l10n message for function show_date_relative() in date.c is longer than 30 characters, then `git blame --date relative` may exit abnormally. 2. When show blame information with relative time, the UTF-8 characters in time_str will break the alignment of columns after the date field. This is because the time_buf padding with spaces should have a constant display width, not a fixed strlen size. So we should call utf8_strwidth() instead of strlen() for width calibration. Helped-by: Nguyễn Thái Ngọc Duy <[email protected]> Helped-by: Eric Sunshine <[email protected]> Signed-off-by: Jiang Xin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cc29195 commit bccce0f

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

builtin/blame.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,22 +1556,29 @@ static void assign_blame(struct scoreboard *sb, int opt)
15561556
static const char *format_time(unsigned long time, const char *tz_str,
15571557
int show_raw_time)
15581558
{
1559-
static char time_buf[128];
1559+
static struct strbuf time_buf = STRBUF_INIT;
15601560

1561+
strbuf_reset(&time_buf);
15611562
if (show_raw_time) {
1562-
snprintf(time_buf, sizeof(time_buf), "%lu %s", time, tz_str);
1563+
strbuf_addf(&time_buf, "%lu %s", time, tz_str);
15631564
}
15641565
else {
15651566
const char *time_str;
1566-
int time_len;
1567+
size_t time_width;
15671568
int tz;
15681569
tz = atoi(tz_str);
15691570
time_str = show_date(time, tz, blame_date_mode);
1570-
time_len = strlen(time_str);
1571-
memcpy(time_buf, time_str, time_len);
1572-
memset(time_buf + time_len, ' ', blame_date_width - time_len);
1571+
strbuf_addstr(&time_buf, time_str);
1572+
/*
1573+
* Add space paddings to time_buf to display a fixed width
1574+
* string, and use time_width for display width calibration.
1575+
*/
1576+
for (time_width = utf8_strwidth(time_str);
1577+
time_width < blame_date_width;
1578+
time_width++)
1579+
strbuf_addch(&time_buf, ' ');
15731580
}
1574-
return time_buf;
1581+
return time_buf.buf;
15751582
}
15761583

15771584
#define OUTPUT_ANNOTATE_COMPAT 001

0 commit comments

Comments
 (0)