On 18/01/2022 06:13, Herbert Xu wrote:
This patch forces ^ to be a literal when we use fnmatch.
Fixes: 7638476c18f2 ("shell: Enable fnmatch/glob by default")
Reported-by: Christoph Anton Mitterer <calestyo@xxxxxxxxxxxx>
Suggested-by: Harald van Dijk <harald@xxxxxxxxxxx>
Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
diff --git a/src/expand.c b/src/expand.c
index aea5cc4..04bf8fb 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -47,6 +47,9 @@
#include <string.h>
#ifdef HAVE_FNMATCH
#include <fnmatch.h>
+#define FNMATCH_IS_ENABLED 1
+#else
+#define FNMATCH_IS_ENABLED 0
#endif
#ifdef HAVE_GLOB
#include <glob.h>
@@ -1693,8 +1696,11 @@ _rmescapes(char *str, int flag)
notescaped = 0;
goto copy;
}
+ if (FNMATCH_IS_ENABLED && *p == '^')
+ goto add_escape;
if (*p == (char)CTLESC) {
p++;
+add_escape:
if (notescaped)
*q++ = '\\';
}
The loop that is modified by this patch is only taken after any qchars
are seen, so for e.g.
var=abc
echo ${var#[^a]}
it has no effect. More importantly though, _rmescapes is used to modify
strings in place. This patch causes _rmescapes to try and grow strings,
which cannot ever work. A test case for this is
case aa in \a[^a]) echo match ;; esac
which fails with a segfault after this patch is applied.
Cheers,
Harald van Dijk