r2068 - in glibc-package/trunk/debian: . patches patches/any
Author: madcoder
Date: 2007-04-15 00:45:03 +0000 (Sun, 15 Apr 2007)
New Revision: 2068
Added:
glibc-package/trunk/debian/patches/any/cvs-glob-c.diff
Modified:
glibc-package/trunk/debian/changelog
glibc-package/trunk/debian/patches/series
Log:
Closes: #234880 (glob)
* patches/any/cvs-glob-c.diff: fixes glob wrt \/ escapes (among other
fixes). Closes: #234880.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Modified: glibc-package/trunk/debian/changelog
===================================================================
--- glibc-package/trunk/debian/changelog 2007-04-14 23:48:38 UTC (rev 2067)
+++ glibc-package/trunk/debian/changelog 2007-04-15 00:45:03 UTC (rev 2068)
@@ -2,6 +2,8 @@
* patches/any/submitted-unistd_XOPEN_VERSION.diff: set _XOPEN_VERSION to 600
when __USE_XOPEN2K is set. Closes: #203412.
+ * patches/any/cvs-glob-c.diff: fixes glob wrt \/ escapes (among other
+ fixes). Closes: #234880.
-- Pierre Habouzit <madcoder@debian.org> Sun, 15 Apr 2007 01:46:38 +0200
Added: glibc-package/trunk/debian/patches/any/cvs-glob-c.diff
===================================================================
--- glibc-package/trunk/debian/patches/any/cvs-glob-c.diff 2007-04-14 23:48:38 UTC (rev 2067)
+++ glibc-package/trunk/debian/patches/any/cvs-glob-c.diff 2007-04-15 00:45:03 UTC (rev 2068)
@@ -0,0 +1,586 @@
+===================================================================
+RCS file: /cvs/glibc/libc/posix/glob.c,v
+retrieving revision 1.72
+retrieving revision 1.73
+Index: glibc-2.5/posix/glob.c
+===================================================================
+--- glibc-2.5.orig/posix/glob.c 2007-04-13 13:31:26.629689784 +0200
++++ glibc-2.5/posix/glob.c 2007-04-15 02:43:02.147008076 +0200
+@@ -1,4 +1,5 @@
+-/* Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
++/* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006, 2007
++ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+@@ -192,9 +193,15 @@
+
+ #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
+
++#ifndef attribute_hidden
++# define attribute_hidden
++#endif
++
+ static int glob_in_dir (const char *pattern, const char *directory,
+ int flags, int (*errfunc) (const char *, int),
+ glob_t *pglob);
++extern int __glob_pattern_type (const char *pattern, int quote)
++ attribute_hidden;
+
+ #if !defined _LIBC || !defined GLOB_ONLY_P
+ static int prefix_array (const char *prefix, char **array, size_t n) __THROW;
+@@ -250,6 +257,9 @@
+ size_t dirlen;
+ int status;
+ size_t oldcount;
++ int meta;
++ int dirname_modified;
++ glob_t dirs;
+
+ if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
+ {
+@@ -418,6 +428,7 @@
+ if (filename == NULL)
+ filename = strchr (pattern, ':');
+ #endif /* __MSDOS__ || WINDOWS32 */
++ dirname_modified = 0;
+ if (filename == NULL)
+ {
+ /* This can mean two things: a simple name or "~name". The latter
+@@ -486,10 +497,32 @@
+ && dirlen > 1)
+ /* "pattern/". Expand "pattern", appending slashes. */
+ {
++ int orig_flags = flags;
++ if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
++ {
++ /* "pattern\\/". Remove the final backslash if it hasn't
++ been quoted. */
++ char *p = (char *) &dirname[dirlen - 1];
++
++ while (p > dirname && p[-1] == '\\') --p;
++ if ((&dirname[dirlen] - p) & 1)
++ {
++ *(char *) &dirname[--dirlen] = '\0';
++ flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
++ }
++ }
+ int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
+ if (val == 0)
+ pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
+ | (flags & GLOB_MARK));
++ else if (val == GLOB_NOMATCH && flags != orig_flags)
++ {
++ /* Make sure globfree (&dirs); is a nop. */
++ dirs.gl_pathv = NULL;
++ flags = orig_flags;
++ oldcount = pglob->gl_pathc + pglob->gl_offs;
++ goto no_matches;
++ }
+ return val;
+ }
+ }
+@@ -517,7 +550,9 @@
+ #ifndef VMS
+ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
+ {
+- if (dirname[1] == '\0' || dirname[1] == '/')
++ if (dirname[1] == '\0' || dirname[1] == '/'
++ || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\'
++ && (dirname[2] == '\0' || dirname[2] == '/')))
+ {
+ /* Look up home directory. */
+ const char *home_dir = getenv ("HOME");
+@@ -594,7 +629,10 @@
+ # endif
+ /* Now construct the full directory. */
+ if (dirname[1] == '\0')
+- dirname = home_dir;
++ {
++ dirname = home_dir;
++ dirlen = strlen (dirname);
++ }
+ else
+ {
+ char *newp;
+@@ -603,7 +641,9 @@
+ mempcpy (mempcpy (newp, home_dir, home_len),
+ &dirname[1], dirlen);
+ dirname = newp;
++ dirlen += home_len - 1;
+ }
++ dirname_modified = 1;
+ }
+ # if !defined _AMIGA && !defined WINDOWS32
+ else
+@@ -611,15 +651,52 @@
+ char *end_name = strchr (dirname, '/');
+ const char *user_name;
+ const char *home_dir;
++ char *unescape = NULL;
+
++ if (!(flags & GLOB_NOESCAPE))
++ {
++ if (end_name == NULL)
++ {
++ unescape = strchr (dirname, '\\');
++ if (unescape)
++ end_name = strchr (unescape, '\0');
++ }
++ else
++ unescape = memchr (dirname, '\\', end_name - dirname);
++ }
+ if (end_name == NULL)
+ user_name = dirname + 1;
+ else
+ {
+ char *newp;
+ newp = (char *) __alloca (end_name - dirname);
+- *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
+- = '\0';
++ if (unescape != NULL)
++ {
++ char *p = mempcpy (newp, dirname + 1,
++ unescape - dirname - 1);
++ char *q = unescape;
++ while (*q != '\0')
++ {
++ if (*q == '\\')
++ {
++ if (q[1] == '\0')
++ {
++ /* "~fo\\o\\" unescape to user_name "foo\\",
++ but "~fo\\o\\/" unescape to user_name
++ "foo". */
++ if (filename == NULL)
++ *p++ = '\\';
++ break;
++ }
++ ++q;
++ }
++ *p++ = *q++;
++ }
++ *p = '\0';
++ }
++ else
++ *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
++ = '\0';
+ user_name = newp;
+ }
+
+@@ -673,6 +750,8 @@
+ *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
+ end_name, rest_len)) = '\0';
+ dirname = newp;
++ dirlen = home_len + rest_len;
++ dirname_modified = 1;
+ }
+ else
+ if (flags & GLOB_TILDE_CHECK)
+@@ -714,9 +793,22 @@
+ }
+ pglob->gl_pathv = new_gl_pathv;
+
+- pglob->gl_pathv[newcount] = strdup (dirname);
+- if (pglob->gl_pathv[newcount] == NULL)
+- goto nospace;
++ if (flags & GLOB_MARK)
++ {
++ char *p;
++ pglob->gl_pathv[newcount] = malloc (dirlen + 2);
++ if (pglob->gl_pathv[newcount] == NULL)
++ goto nospace;
++ p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
++ p[0] = '/';
++ p[1] = '\0';
++ }
++ else
++ {
++ pglob->gl_pathv[newcount] = strdup (dirname);
++ if (pglob->gl_pathv[newcount] == NULL)
++ goto nospace;
++ }
+ pglob->gl_pathv[++newcount] = NULL;
+ ++pglob->gl_pathc;
+ pglob->gl_flags = flags;
+@@ -728,14 +820,30 @@
+ return GLOB_NOMATCH;
+ }
+
+- if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
++ meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
++ /* meta is 1 if correct glob pattern containing metacharacters.
++ If meta has bit (1 << 2) set, it means there was an unterminated
++ [ which we handle the same, using fnmatch. Broken unterminated
++ pattern bracket expressions ought to be rare enough that it is
++ not worth special casing them, fnmatch will do the right thing. */
++ if (meta & 5)
+ {
+ /* The directory name contains metacharacters, so we
+ have to glob for the directory, and then glob for
+ the pattern in each directory found. */
+- glob_t dirs;
+ size_t i;
+
++ if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\')
++ {
++ /* "foo\\/bar". Remove the final backslash from dirname
++ if it has not been quoted. */
++ char *p = (char *) &dirname[dirlen - 1];
++
++ while (p > dirname && p[-1] == '\\') --p;
++ if ((&dirname[dirlen] - p) & 1)
++ *(char *) &dirname[--dirlen] = '\0';
++ }
++
+ if ((flags & GLOB_ALTDIRFUNC) != 0)
+ {
+ /* Use the alternative access functions also in the recursive
+@@ -748,12 +856,16 @@
+ }
+
+ status = glob (dirname,
+- ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE
++ ((flags & (GLOB_ERR | GLOB_NOESCAPE
+ | GLOB_ALTDIRFUNC))
+ | GLOB_NOSORT | GLOB_ONLYDIR),
+ errfunc, &dirs);
+ if (status != 0)
+- return status;
++ {
++ if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
++ return status;
++ goto no_matches;
++ }
+
+ /* We have successfully globbed the preceding directory name.
+ For each name we found, call glob_in_dir on it and FILENAME,
+@@ -811,6 +923,7 @@
+ flag was set we must return the input pattern itself. */
+ if (pglob->gl_pathc + pglob->gl_offs == oldcount)
+ {
++ no_matches:
+ /* No matches. */
+ if (flags & GLOB_NOCHECK)
+ {
+@@ -854,10 +967,44 @@
+ else
+ {
+ int old_pathc = pglob->gl_pathc;
++ int orig_flags = flags;
+
++ if (meta & 2)
++ {
++ char *p = strchr (dirname, '\\'), *q;
++ /* We need to unescape the dirname string. It is certainly
++ allocated by alloca, as otherwise filename would be NULL
++ or dirname wouldn't contain backslashes. */
++ q = p;
++ do
++ {
++ if (*p == '\\')
++ {
++ *q = *++p;
++ --dirlen;
++ }
++ else
++ *q = *p;
++ ++q;
++ }
++ while (*p++ != '\0');
++ dirname_modified = 1;
++ }
++ if (dirname_modified)
++ flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC);
+ status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
+ if (status != 0)
+- return status;
++ {
++ if (status == GLOB_NOMATCH && flags != orig_flags
++ && pglob->gl_pathc + pglob->gl_offs == oldcount)
++ {
++ /* Make sure globfree (&dirs); is a nop. */
++ dirs.gl_pathv = NULL;
++ flags = orig_flags;
++ goto no_matches;
++ }
++ return status;
++ }
+
+ if (dirlen > 0)
+ {
+@@ -1015,15 +1162,13 @@
+
+ /* We must not compile this function twice. */
+ #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
+-/* Return nonzero if PATTERN contains any metacharacters.
+- Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
+ int
+-__glob_pattern_p (pattern, quote)
++__glob_pattern_type (pattern, quote)
+ const char *pattern;
+ int quote;
+ {
+ register const char *p;
+- int open = 0;
++ int ret = 0;
+
+ for (p = pattern; *p != '\0'; ++p)
+ switch (*p)
+@@ -1033,21 +1178,35 @@
+ return 1;
+
+ case '\\':
+- if (quote && p[1] != '\0')
+- ++p;
++ if (quote)
++ {
++ if (p[1] != '\0')
++ ++p;
++ ret |= 2;
++ }
+ break;
+
+ case '[':
+- open = 1;
++ ret |= 4;
+ break;
+
+ case ']':
+- if (open)
++ if (ret & 4)
+ return 1;
+ break;
+ }
+
+- return 0;
++ return ret;
++}
++
++/* Return nonzero if PATTERN contains any metacharacters.
++ Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
++int
++__glob_pattern_p (pattern, quote)
++ const char *pattern;
++ int quote;
++{
++ return __glob_pattern_type (pattern, quote) == 1;
+ }
+ # ifdef _LIBC
+ weak_alias (__glob_pattern_p, glob_pattern_p)
+@@ -1109,7 +1268,7 @@
+ init_names.next = NULL;
+ init_names.count = INITIAL_COUNT;
+
+- meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
++ meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
+ if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
+ {
+ /* We need not do any tests. The PATTERN contains no meta
+@@ -1117,8 +1276,7 @@
+ result will always contain exactly one name. */
+ flags |= GLOB_NOCHECK;
+ }
+- else if (meta == 0 &&
+- ((flags & GLOB_NOESCAPE) || strchr (pattern, '\\') == NULL))
++ else if (meta == 0)
+ {
+ /* Since we use the normal file functions we can also use stat()
+ to verify the file is there. */
+@@ -1139,119 +1297,104 @@
+ }
+ else
+ {
+- if (pattern[0] == '\0')
++ stream = ((flags & GLOB_ALTDIRFUNC)
++ ? (*pglob->gl_opendir) (directory)
++ : opendir (directory));
++ if (stream == NULL)
+ {
+- /* This is a special case for matching directories like in
+- "*a/". */
+- names->name[cur] = (char *) malloc (1);
+- if (names->name[cur] == NULL)
+- goto memory_error;
+- *names->name[cur++] = '\0';
+- nfound = 1;
+- meta = 0;
++ if (errno != ENOTDIR
++ && ((errfunc != NULL && (*errfunc) (directory, errno))
++ || (flags & GLOB_ERR)))
++ return GLOB_ABORTED;
+ }
+ else
+ {
+- stream = ((flags & GLOB_ALTDIRFUNC)
+- ? (*pglob->gl_opendir) (directory)
+- : opendir (directory));
+- if (stream == NULL)
+- {
+- if (errno != ENOTDIR
+- && ((errfunc != NULL && (*errfunc) (directory, errno))
+- || (flags & GLOB_ERR)))
+- return GLOB_ABORTED;
+- meta = 0;
+- }
+- else
+- {
+- int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
+- | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
++ int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
++ | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
+ #if defined _AMIGA || defined VMS
+- | FNM_CASEFOLD
++ | FNM_CASEFOLD
+ #endif
+- );
+- flags |= GLOB_MAGCHAR;
++ );
++ flags |= GLOB_MAGCHAR;
+
+- while (1)
+- {
+- const char *name;
+- size_t len;
++ while (1)
++ {
++ const char *name;
++ size_t len;
+ #if defined _LIBC && !defined COMPILE_GLOB64
+- struct dirent64 *d;
+- union
+- {
+- struct dirent64 d64;
+- char room [offsetof (struct dirent64, d_name[0])
+- + NAME_MAX + 1];
+- }
+- d64buf;
++ struct dirent64 *d;
++ union
++ {
++ struct dirent64 d64;
++ char room [offsetof (struct dirent64, d_name[0])
++ + NAME_MAX + 1];
++ }
++ d64buf;
+
+- if (flags & GLOB_ALTDIRFUNC)
++ if (flags & GLOB_ALTDIRFUNC)
++ {
++ struct dirent *d32 = (*pglob->gl_readdir) (stream);
++ if (d32 != NULL)
+ {
+- struct dirent *d32 = (*pglob->gl_readdir) (stream);
+- if (d32 != NULL)
+- {
+- CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
+- d = &d64buf.d64;
+- }
+- else
+- d = NULL;
++ CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
++ d = &d64buf.d64;
+ }
+ else
+- d = __readdir64 (stream);
++ d = NULL;
++ }
++ else
++ d = __readdir64 (stream);
+ #else
+- struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
+- ? ((struct dirent *)
+- (*pglob->gl_readdir) (stream))
+- : __readdir (stream));
++ struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
++ ? ((struct dirent *)
++ (*pglob->gl_readdir) (stream))
++ : __readdir (stream));
+ #endif
+- if (d == NULL)
+- break;
+- if (! REAL_DIR_ENTRY (d))
+- continue;
++ if (d == NULL)
++ break;
++ if (! REAL_DIR_ENTRY (d))
++ continue;
+
+- /* If we shall match only directories use the information
+- provided by the dirent call if possible. */
+- if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
+- continue;
++ /* If we shall match only directories use the information
++ provided by the dirent call if possible. */
++ if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
++ continue;
+
+- name = d->d_name;
++ name = d->d_name;
+
+- if (fnmatch (pattern, name, fnm_flags) == 0)
++ if (fnmatch (pattern, name, fnm_flags) == 0)
++ {
++ /* If the file we found is a symlink we have to
++ make sure the target file exists. */
++ if (!DIRENT_MIGHT_BE_SYMLINK (d)
++ || link_exists_p (directory, dirlen, name, pglob,
++ flags))
+ {
+- /* If the file we found is a symlink we have to
+- make sure the target file exists. */
+- if (!DIRENT_MIGHT_BE_SYMLINK (d)
+- || link_exists_p (directory, dirlen, name, pglob,
+- flags))
++ if (cur == names->count)
+ {
+- if (cur == names->count)
+- {
+- struct globnames *newnames;
+- size_t count = names->count * 2;
+- size_t size = (sizeof (struct globnames)
+- + ((count - INITIAL_COUNT)
+- * sizeof (char *)));
+- allocasize += size;
+- if (__libc_use_alloca (allocasize))
+- newnames = names_alloca = __alloca (size);
+- else if ((newnames = malloc (size))
+- == NULL)
+- goto memory_error;
+- newnames->count = count;
+- newnames->next = names;
+- names = newnames;
+- cur = 0;
+- }
+- len = NAMLEN (d);
+- names->name[cur] = (char *) malloc (len + 1);
+- if (names->name[cur] == NULL)
++ struct globnames *newnames;
++ size_t count = names->count * 2;
++ size_t size = (sizeof (struct globnames)
++ + ((count - INITIAL_COUNT)
++ * sizeof (char *)));
++ allocasize += size;
++ if (__libc_use_alloca (allocasize))
++ newnames = names_alloca = __alloca (size);
++ else if ((newnames = malloc (size))
++ == NULL)
+ goto memory_error;
+- *((char *) mempcpy (names->name[cur++], name, len))
+- = '\0';
+- ++nfound;
++ newnames->count = count;
++ newnames->next = names;
++ names = newnames;
++ cur = 0;
+ }
++ len = NAMLEN (d);
++ names->name[cur] = (char *) malloc (len + 1);
++ if (names->name[cur] == NULL)
++ goto memory_error;
++ *((char *) mempcpy (names->name[cur++], name, len))
++ = '\0';
++ ++nfound;
+ }
+ }
+ }
Modified: glibc-package/trunk/debian/patches/series
===================================================================
--- glibc-package/trunk/debian/patches/series 2007-04-14 23:48:38 UTC (rev 2067)
+++ glibc-package/trunk/debian/patches/series 2007-04-15 00:45:03 UTC (rev 2068)
@@ -138,3 +138,4 @@
any/submitted-clock-settime.diff -p0
any/submitted-date-and-unknown-tz.diff -p0
any/submitted-unistd_XOPEN_VERSION.diff
+any/cvs-glob-c.diff
Reply to: