Message ID | YeZadfOkUDdN7JqS@gondor.apana.org.au (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Herbert Xu |
Headers | show |
Series | expand: Always quote caret when using fnmatch | expand |
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@scientia.org> > Suggested-by: Harald van Dijk <harald@gigawatt.nl> > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> > > 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
Hey. Just for confirmation: Would that also be an issue in fnmatch() (i.e. should it be forwarded?) or really just something in dash? Cheers, Chris.
On 1/18/22 9:29 AM, Christoph Anton Mitterer wrote: > Hey. > > Just for confirmation: > > Would that also be an issue in fnmatch() (i.e. should it be forwarded?) > or really just something in dash? The behavior of an unquoted carat as the first character in a bracket expression is unspecified. Dash can't count on any particular behavior.
Christoph Anton Mitterer <calestyo@scientia.org> wrote: > Hey. > > Just for confirmation: > > Would that also be an issue in fnmatch() (i.e. should it be forwarded?) > or really just something in dash? No I don't think this is an fnmatch issue. It's dash's fault for not quoting the caret before passing it to glibc. Thanks,
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++ = '\\'; }