Hi,
On 12/01/2022 16:25, Christoph Anton Mitterer wrote:
The results for the run-circumflex seem pretty odd.
Apparently, the ^ is taken literally, but the other two are negated.
The ^ is not taken literally. The ^ in the pattern is wrongly taken as
the negation operator, and the ^ in the argument is then reported as a
match because it is neither . nor a.
This bug (you're right that it's a bug) is specific to builds that use
fnmatch(). In dash itself, ^ is always assumed as a literal. In builds
with --disable-fnmatch you get correct results. In builds with
--enable-fnmatch, because dash assumes ^ is assumed as a literal, dash
fails to escape it before passing it on to fnmatch(), and the system
fnmatch() may choose differently from dash on how to deal with unquoted
^s. What dash should do to get whatever behaviour the system fnmatch()
chooses is leave unquoted ^s unquoted, and leave quoted ^s quoted. This
can be achieved by
--- a/src/mksyntax.c
+++ b/src/mksyntax.c
@@ -178,14 +178,14 @@ main(int argc, char **argv)
add("$", "CVAR");
add("}", "CENDVAR");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
- add("!*?[=~:/-]", "CCTL");
+ add("!*?[^=~:/-]", "CCTL");
print("dqsyntax");
init();
fputs("\n/* syntax table used when in single quotes */\n", cfile);
add("\n", "CNL");
add("'", "CENDQUOTE");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
- add("!*?[=~:/-]\\", "CCTL");
+ add("!*?[^=~:/-]\\", "CCTL");
print("sqsyntax");
init();
fputs("\n/* syntax table used when in arithmetic */\n", cfile);
However, whether this is the correct approach is a matter of opinion:
dash could alternatively choose to always take ^ as a literal and always
escape it before passing it on to fnmatch(), overriding whatever
decision the libc people had taken.
Cheers,
Harald van Dijk