]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
aft: Silence format-overflow warning with gcc-10.
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 28 Apr 2021 11:17:03 +0000 (13:17 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Wed, 28 Apr 2021 11:22:25 +0000 (13:22 +0200)
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

diff --git a/aft.c b/aft.c
index eb955e019f538e3d73f38074ff657c9b86d2199d..b358c96cd9afd23bfa7f043c8add8bbf8b4bfade 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -721,7 +721,8 @@ __a_const static short unsigned get_duration_width(int seconds)
        return width + 6;
 }
 
        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;
 {
        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;
        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;
                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);
        }
                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;
        }
                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))
        if (opts->mode == LS_MODE_LONG) {
                struct ls_widths *w = &opts->widths;
                if (lls_opt_given(r_a))