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>
This commit is contained in:
Allan McRae 2024-01-26 17:06:46 +10:00
parent 1d1bb6fa1a
commit c9c56be396

View file

@ -34,6 +34,7 @@
#include <limits.h> #include <limits.h>
#include <wchar.h> #include <wchar.h>
#include <wctype.h> #include <wctype.h>
#include <ctype.h>
#ifdef HAVE_TERMIOS_H #ifdef HAVE_TERMIOS_H
#include <termios.h> /* tcflush */ #include <termios.h> /* tcflush */
#endif #endif
@ -448,25 +449,34 @@ static char *concat_list(alpm_list_t *lst, formatfn fn)
static size_t string_length(const char *s) static size_t string_length(const char *s)
{ {
int len; size_t len;
wchar_t *wcstr; wchar_t *wcstr;
if(!s || s[0] == '\0') { if(!s || s[0] == '\0') {
return 0; return 0;
} }
if(strstr(s, "\033")) { if(strchr(s, '\033')) {
char* replaced = malloc(sizeof(char) * strlen(s)); char* replaced = malloc(sizeof(char) * strlen(s));
int iter = 0; size_t iter = 0;
for(; *s; s++) { for(; *s; s++) {
if(*s == '\033') { if(*s == '\033' && *(s+1) == '[' && isdigit(s+2)) {
while(*s != 'm') { /* handle terminal colour escape sequences */
s++; const char* t = s + 3;
while(isdigit(*t) || *t == ';') {
t++;
} }
} else {
if(*t == 'm') {
/* end of terminal colour sequence */
s = t++;
continue;
}
}
replaced[iter] = *s; replaced[iter] = *s;
iter++; iter++;
} }
}
replaced[iter] = '\0'; replaced[iter] = '\0';
len = iter; len = iter;
wcstr = calloc(len, sizeof(wchar_t)); wcstr = calloc(len, sizeof(wchar_t));