Synopsis 1: Setting DEBUG breaks switch statement in `match' Description 1: Setting `DEBUG' causes `Char' to be defined `char' instead of `u_short' which breaks the `switch' statement at glob.c:902 causing meta characters to be treated literally. How-To-Repeat: Compile glob.c with ``-DDEBUG'' and use it with any pattern containing a meta character. For example "/dev/nul[l]" will fail. Fix: One way that can be fixed by either defining `Char' as `u_char' or getting rid of the alternative definitions. I was unable to find anything that breaks from just using the `u_short' definitions for both cases. Both of those fixed the behavior described above which was helpful for the other bugs.
Synopsis 2: The `alnum' character class is read as '\0' in `glob2' Description 2: Since character classes are stored as raw indices the `alnum' character class is read as '\0' at various points. Particularly at glob.c:660, but also at glob.c:1052, causing the pattern to be treated as shorter than it is. How-To-Repeat: The "/dev/[[:alnum:]]ull" pattern fails where the "/dev/[[:alpha:]]ull" pattern succeeds. See below for a test script. Fix: One quick way to fix that is to store the index offset (such as 'A') so that it is never zero, or with the meta bit set. Both of those fixed the example above. Also, handling `M_CLASS' at glob:660 and glob:1052 (the locations mentioned above) seemed to fix the issue, but I am still unsure if there are more locations that would need to be modified. Synopsis 3: Character sets break in curly braces. Description 3: The `pl' variable is used to keep track of the initial curly brace at glob.c:285 but is overwritten to keep track of the initial square bracket at glob.c:289 which causes glob.c:315 to copy starting at the square bracket instead of the curly brace. How-To-Repeat: The test pattern "/dev/{nul[l]}" turns into "/dev/[l]" which fails. See the test script below. Fix: Adding an additional ``const Char *'' variable to use for the square brackets fixed the example above. $ cc -xc -o glob - <<EOF #include <stdio.h> #include <glob.h> int main(int argc, char *argv[]) { glob_t g; int i, j; for (i = 1; i < argc; i++) { if (glob(argv[i], GLOB_BRACE, NULL, &g) == 0) for (j = 0; j < g.gl_matchc; j++) (void)printf("%s\n", g.gl_pathv[j]); } return (0); } EOF $ ./glob '/dev/[[:alpha:]]ero' '/dev/[[:alnum:]]ull' # Should print both /dev/zero $ ./glob '/dev/{[z]ero}' '/dev/{nul[l]}' # Should print both /dev/zero