From da9722e3b785863ed7ce14aa9b66be9782238d85 Mon Sep 17 00:00:00 2001 From: Rene Kita Date: Sat, 24 Dec 2022 10:05:36 +0100 Subject: [PATCH] Check LESSOPEN to avoid undefined behaviour Like less, w3m can use an input preprocessor when displaying files. The preprocessor command is taken from the environment variable LESSOPEN. The command line in LESSOPEN should include one occurrence of the string "%s", which will be replaced by the filename when the input preprocessor command is invoked. Giving more than one "%s" - or a any other conversion specifier - will lead to undefined behaviour. Add a check to make sure the command given has only one "%s". This fixes https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=991608 --- file.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/file.c b/file.c index c745414..353ae8a 100644 --- a/file.c +++ b/file.c @@ -8776,13 +8776,14 @@ uncompress_stream(URLFile *uf, char **src) #endif /* __MINGW32_VERSION */ } + static FILE * lessopen_stream(char *path) { char *lessopen; FILE *fp; Str tmpf; - int c; + int c, n = 0; lessopen = getenv("LESSOPEN"); if (lessopen == NULL || lessopen[0] == '\0') @@ -8793,6 +8794,24 @@ lessopen_stream(char *path) /* pipe mode */ ++lessopen; + + /* LESSOPEN must contain one conversion specifier for strings ('%s'). */ + for (const char *f = lessopen; *f; f++) { + if (*f == '%') { + if (f[1] == '%') /* Literal % */ + f++; + else if (*++f == 's') { + if (n) + return NULL; + n++; + } + else + return NULL; + } + } + if (!n) + return NULL; + tmpf = Sprintf(lessopen, shell_quote(path)); fp = popen(tmpf->ptr, "r"); if (fp == NULL) {