diff --git a/ChangeLog b/ChangeLog index 8cfa6e9a37..e6d312153e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2016-10-31 Andreas Schwab + + [BZ #20707] + * posix/glob.c (glob): Initialize pglob before checking for + GLOB_BRACE. Don't call glob recursively if pattern contains no + valid brace expression despite GLOB_BRACE. + * posix/globtest.sh: Test it. + 2016-10-28 Carlos O'Donell [BZ #20729] diff --git a/posix/glob.c b/posix/glob.c index ea4b0b61eb..e357195a72 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -312,6 +312,28 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), also makes all the code that uses gl_offs simpler. */ pglob->gl_offs = 0; + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_pathv = NULL; + else + { + size_t i; + + if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *)) + return GLOB_NOSPACE; + + pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) + * sizeof (char *)); + if (pglob->gl_pathv == NULL) + return GLOB_NOSPACE; + + for (i = 0; i <= pglob->gl_offs; ++i) + pglob->gl_pathv[i] = NULL; + } + } + if (flags & GLOB_BRACE) { const char *begin; @@ -359,14 +381,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { onealt = (char *) malloc (pattern_len); if (onealt == NULL) - { - if (!(flags & GLOB_APPEND)) - { - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - } - return GLOB_NOSPACE; - } + return GLOB_NOSPACE; } /* We know the prefix for all sub-patterns. */ @@ -383,7 +398,8 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (__glibc_unlikely (!alloca_onealt)) #endif free (onealt); - return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + flags &= ~GLOB_BRACE; + goto no_brace; } /* Now find the end of the whole brace expression. */ @@ -404,14 +420,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), points past the final }. We will accumulate result names from recursive runs for each brace alternative in the buffer using GLOB_APPEND. */ - - if (!(flags & GLOB_APPEND)) - { - /* This call is to set a new vector, so clear out the - vector so we can append to it. */ - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - } firstc = pglob->gl_pathc; p = begin + 1; @@ -463,28 +471,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } } - if (!(flags & GLOB_APPEND)) - { - pglob->gl_pathc = 0; - if (!(flags & GLOB_DOOFFS)) - pglob->gl_pathv = NULL; - else - { - size_t i; - - if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *)) - return GLOB_NOSPACE; - - pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) - * sizeof (char *)); - if (pglob->gl_pathv == NULL) - return GLOB_NOSPACE; - - for (i = 0; i <= pglob->gl_offs; ++i) - pglob->gl_pathv[i] = NULL; - } - } - + no_brace: oldcount = pglob->gl_pathc + pglob->gl_offs; /* Find the filename. */ diff --git a/posix/globtest.sh b/posix/globtest.sh index 73fe11bd76..e280f7d2b3 100755 --- a/posix/globtest.sh +++ b/posix/globtest.sh @@ -794,6 +794,22 @@ if test $failed -ne 0; then result=1 fi +# Test GLOB_BRACE and GLIB_DOOFFS with malloc checking +failed=0 +${test_wrapper_env} \ +MALLOC_PERTURB_=65 \ +${test_via_rtld_prefix} \ +${common_objpfx}posix/globtest -b -o "$testdir" "file{1,2}" > $testout || failed=1 +cat <<"EOF" | $CMP - $testout >> $logfile || failed=1 +`abc' +`file1' +`file2' +EOF +if test $failed -ne 0; then + echo "GLOB_BRACE+GLOB_DOOFFS test failed" >> $logfile + result=1 +fi + if test $result -eq 0; then chmod 777 $testdir/noread rm -fr $testdir $testout