From 3ccea2ef0eff8e9acc5d34528645d3e29bc9a4f9 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Wed, 28 Apr 2021 13:17:03 +0200 Subject: [PATCH] aft: Silence format-overflow warning with gcc-10. aft.c: In function 'print_list_item': aft.c:736:17: warning: '%*u' directive writing between 1 and 65529 bytes into a region of size 30 [-Wformat-overflow=] 736 | sprintf(buf, "%*u:%02u:%02d", max_width - 6, hours, mins, | ^~~ aft.c:736:16: note: directive argument in the range [1, 4294967295] 736 | sprintf(buf, "%*u:%02u:%02d", max_width - 6, hours, mins, | ^~~~~~~~~~~~~~~ aft.c:736:16: note: directive argument in the range [-59, 59] aft.c:736:3: note: 'sprintf' output between 8 and 65545 bytes into a destination of size 30 736 | sprintf(buf, "%*u:%02u:%02d", max_width - 6, hours, mins, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 737 | seconds % 60); | ~~~~~~~~~~~~~ The code is correct but gcc can't prove it. Silence the warning by passing the size of the buffer and asserting that it won't overflow before printing to it. --- aft.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/aft.c b/aft.c index eb955e01..b358c96c 100644 --- a/aft.c +++ b/aft.c @@ -721,7 +721,8 @@ __a_const static short unsigned get_duration_width(int seconds) return width + 6; } -static void get_duration_buf(int seconds, char *buf, struct ls_options *opts) +static void get_duration_buf(int seconds, char *buf, size_t bufsize, + struct ls_options *opts) { unsigned hours = seconds / 3600, mins = (seconds % 3600) / 60; short unsigned max_width; @@ -729,10 +730,12 @@ static void get_duration_buf(int seconds, char *buf, struct ls_options *opts) if (!hours) { /* m:ss or mm:ss */ max_width = opts->mode == LS_MODE_LONG? opts->widths.duration_width : 4; + assert(max_width < bufsize - 1); sprintf(buf, "%*u:%02d", max_width - 3, mins, seconds % 60); } else { /* more than one hour => h:mm:ss, hh:mm:ss, hhh:mm:ss, ... */ max_width = opts->mode == LS_MODE_LONG? opts->widths.duration_width : 7; + assert(max_width < bufsize - 1); sprintf(buf, "%*u:%02u:%02d", max_width - 6, hours, mins, seconds % 60); } @@ -856,7 +859,8 @@ static int print_list_item(struct ls_data *d, struct ls_options *opts, if (ret < 0) goto out; } - get_duration_buf(afhi->seconds_total, duration_buf, opts); + get_duration_buf(afhi->seconds_total, duration_buf, + sizeof(duration_buf), opts); if (opts->mode == LS_MODE_LONG) { struct ls_widths *w = &opts->widths; if (lls_opt_given(r_a)) -- 2.39.2