diff options
author | Allan McRae <allan@archlinux.org> | 2024-01-26 17:06:46 +1000 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2024-02-26 03:07:08 +0000 |
commit | c9c56be3960c7ba7ccacc7ccc992965f16b9eba0 (patch) | |
tree | 16f4b0abe9250748e93e6bc05d95bd6e5fc40f25 /src | |
parent | 1d1bb6fa1a8247242fbdd226f50265a278a12ac8 (diff) |
pacman/util.c: fix potential buffer overflow in string_length
A potential buffer overflow could occur if a detected terminal escape
sequence was not for a terminal colour (i.e. did not contain an "m").
Fix the potential buffer overflow while explicitly detecting only
terminal colour escape sequences. Any other escape sequence is
unexpected, and just gets pushed to the terminal.
Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/pacman/util.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c index 2de62dca..43854a02 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -34,6 +34,7 @@ #include <limits.h> #include <wchar.h> #include <wctype.h> +#include <ctype.h> #ifdef HAVE_TERMIOS_H #include <termios.h> /* tcflush */ #endif @@ -448,24 +449,33 @@ static char *concat_list(alpm_list_t *lst, formatfn fn) static size_t string_length(const char *s) { - int len; + size_t len; wchar_t *wcstr; if(!s || s[0] == '\0') { return 0; } - if(strstr(s, "\033")) { + if(strchr(s, '\033')) { char* replaced = malloc(sizeof(char) * strlen(s)); - int iter = 0; + size_t iter = 0; for(; *s; s++) { - if(*s == '\033') { - while(*s != 'm') { - s++; + if(*s == '\033' && *(s+1) == '[' && isdigit(s+2)) { + /* handle terminal colour escape sequences */ + const char* t = s + 3; + + while(isdigit(*t) || *t == ';') { + t++; + } + + if(*t == 'm') { + /* end of terminal colour sequence */ + s = t++; + continue; } - } else { - replaced[iter] = *s; - iter++; } + + replaced[iter] = *s; + iter++; } replaced[iter] = '\0'; len = iter; |