From fae2b637ee5d308e438cf366fc2c6856e23a7174 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Sat, 22 Apr 2023 18:59:03 +0200 Subject: i3-input: Avoid compiler warning (#5480) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also updates the function to use proper types, const and style. The warning: ../i3/i3-input/main.c: In function ‘finish_input’: ../i3/i3-input/main.c:187:13: warning: ‘__builtin_strncat’ specified bound depends on the length of the source argument [-Wstringop-overflow=] 187 | strncat(dest, command, inputlen); | ^ ../i3/i3-input/main.c:175:20: note: length computed here 175 | int inputlen = strlen(command); Which is triggered because gcc thinks it's bad that `input_len` (the length of the source in the copy) is used instead of a length that is inside the limits of the allocated size for the destination. However, in practice, `full_len` is always than `input_len`. --- i3-input/main.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/i3-input/main.c b/i3-input/main.c index ef9e0701..afe16ccc 100644 --- a/i3-input/main.c +++ b/i3-input/main.c @@ -163,29 +163,32 @@ static void finish_input(void) { char *command = (char *)concat_strings(glyphs_utf8, input_position); /* count the occurrences of %s in the string */ - int c; - int len = strlen(format); - int cnt = 0; - for (c = 0; c < (len - 1); c++) - if (format[c] == '%' && format[c + 1] == 's') + const size_t len = strlen(format); + size_t cnt = 0; + for (size_t c = 0; c < (len - 1); c++) { + if (format[c] == '%' && format[c + 1] == 's') { cnt++; - printf("occurrences = %d\n", cnt); + } + } + printf("occurrences = %ld\n", cnt); /* allocate space for the output */ - int inputlen = strlen(command); - char *full = scalloc(strlen(format) - (2 * cnt) /* format without all %s */ - + (inputlen * cnt) /* replaced %s */ - + 1, /* trailing NUL */ - 1); + const size_t input_len = strlen(command); + const size_t full_len = MAX(input_len, /* avoid compiler warning */ + strlen(format) - (2 * cnt) /* format without all %s */ + + (input_len * cnt) /* replaced %s */ + + 1 /* trailing NUL */ + ); + char *full = scalloc(full_len, 1); char *dest = full; - for (c = 0; c < len; c++) { - /* if this is not % or it is % but without a following 's', - * just copy the character */ - if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's') + for (size_t c = 0; c < len; c++) { + /* if this is not % or it is % but without a following 's', just copy + * the character */ + if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's') { *(dest++) = format[c]; - else { - strncat(dest, command, inputlen); - dest += inputlen; + } else { + strncat(dest, command, input_len); + dest += input_len; /* skip the following 's' of '%s' */ c++; } -- cgit v1.2.3-54-g00ecf