diff --git a/ext/standard/tests/file/glob_bracket_negation.phpt b/ext/standard/tests/file/glob_bracket_negation.phpt new file mode 100644 index 000000000000..3f5ef513789e --- /dev/null +++ b/ext/standard/tests/file/glob_bracket_negation.phpt @@ -0,0 +1,30 @@ +--TEST-- +glob() negates a bracket expression that starts with "!" or "^" +--FILE-- + +--CLEAN-- + +--EXPECT-- +[!a]: ! ^ b c +[^a]: ! ^ b c +[!a-b]: ! ^ c +[^a-b]: ! ^ c +[!]a]: ! ^ b c +[^]a]: ! ^ b c +[a^]: ^ a diff --git a/main/php_glob.c b/main/php_glob.c index 8edfb8326da4..af087c4530a6 100644 --- a/main/php_glob.c +++ b/main/php_glob.c @@ -107,6 +107,7 @@ #include "charclass.h" +#define CIRCUMFLEX '^' #define DOLLAR '$' #define DOT '.' #define EOS '\0' @@ -566,6 +567,12 @@ static int glob0(const Char *pattern, php_glob_t *pglob, struct glob_lim *limitp switch (c) { case LBRACKET: c = *qpatnext; + /* + * Not in OpenBSD's glob(), keep it when syncing: like fnmatch(), + * treat a leading '^' as '!'. + */ + if (c == CIRCUMFLEX) + c = NOT; if (c == NOT) ++qpatnext; if (*qpatnext == EOS ||