i3-input: Avoid compiler warning (#5480)

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`.
This commit is contained in:
Orestis Floros 2023-04-22 18:59:03 +02:00 committed by GitHub
parent d06f97c4d4
commit fae2b637ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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++;
}