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