]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- djm@cvs.openbsd.org 2011/09/22 06:27:29
authorDamien Miller <djm@mindrot.org>
Thu, 22 Sep 2011 11:22:21 +0000 (21:22 +1000)
committerDamien Miller <djm@mindrot.org>
Thu, 22 Sep 2011 11:22:21 +0000 (21:22 +1000)
     [glob.c]
     fix GLOB_KEEPSTAT without GLOB_NOSORT; the implicit sort was being
     applied only to the gl_pathv vector and not the corresponding gl_statv
     array. reported in OpenSSH bz#1935; feedback and okay matthew@

ChangeLog
openbsd-compat/glob.c

index 98427ee3dab444f53274e3983a5f6328c97a8d12..5c94171c54b1f70a34d0dd964e979e37546b3026 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
      In glob(3), limit recursion during matching attempts. Similar to
      fnmatch fix. Also collapse consecutive '*' (from NetBSD).
      ok miod deraadt
+   - djm@cvs.openbsd.org 2011/09/22 06:27:29
+     [glob.c]
+     fix GLOB_KEEPSTAT without GLOB_NOSORT; the implicit sort was being
+     applied only to the gl_pathv vector and not the corresponding gl_statv
+     array. reported in OpenSSH bz#1935; feedback and okay matthew@
 
 20110909
  - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng.  From
index 85fccf4d177a11097be4bffd6d6af490287540d0..742b4b954a32f66a6afff4b1727f7bdcd141096e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: glob.c,v 1.37 2011/09/20 10:18:46 stsp Exp $ */
+/*     $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */
 /*
  * Copyright (c) 1989, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -133,16 +133,22 @@ typedef char Char;
 #define        GLOB_LIMIT_STAT         128
 #define        GLOB_LIMIT_READDIR      16384
 
+/* Limit of recursion during matching attempts. */
+#define GLOB_LIMIT_RECUR       64
+
 struct glob_lim {
        size_t  glim_malloc;
        size_t  glim_stat;
        size_t  glim_readdir;
 };
 
-/* Limit of recursion during matching attempts. */
-#define GLOB_LIMIT_RECUR       64
+struct glob_path_stat {
+       char            *gps_path;
+       struct stat     *gps_stat;
+};
 
 static int      compare(const void *, const void *);
+static int      compare_gps(const void *, const void *);
 static int      g_Ctoc(const Char *, char *, u_int);
 static int      g_lstat(Char *, struct stat *, glob_t *);
 static DIR     *g_opendir(Char *, glob_t *);
@@ -555,9 +561,32 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
                else
                        return(GLOB_NOMATCH);
        }
-       if (!(pglob->gl_flags & GLOB_NOSORT))
-               qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
-                   pglob->gl_pathc - oldpathc, sizeof(char *), compare);
+       if (!(pglob->gl_flags & GLOB_NOSORT)) {
+               if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
+                       /* Keep the paths and stat info synced during sort */
+                       struct glob_path_stat *path_stat;
+                       int i;
+                       int n = pglob->gl_pathc - oldpathc;
+                       int o = pglob->gl_offs + oldpathc;
+
+                       if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL)
+                               return GLOB_NOSPACE;
+                       for (i = 0; i < n; i++) {
+                               path_stat[i].gps_path = pglob->gl_pathv[o + i];
+                               path_stat[i].gps_stat = pglob->gl_statv[o + i];
+                       }
+                       qsort(path_stat, n, sizeof(*path_stat), compare_gps);
+                       for (i = 0; i < n; i++) {
+                               pglob->gl_pathv[o + i] = path_stat[i].gps_path;
+                               pglob->gl_statv[o + i] = path_stat[i].gps_stat;
+                       }
+                       free(path_stat);
+               } else {
+                       qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
+                           pglob->gl_pathc - oldpathc, sizeof(char *),
+                           compare);
+               }
+       }
        return(0);
 }
 
@@ -567,6 +596,15 @@ compare(const void *p, const void *q)
        return(strcmp(*(char **)p, *(char **)q));
 }
 
+static int
+compare_gps(const void *_p, const void *_q)
+{
+       const struct glob_path_stat *p = (const struct glob_path_stat *)_p;
+       const struct glob_path_stat *q = (const struct glob_path_stat *)_q;
+
+       return(strcmp(p->gps_path, q->gps_path));
+}
+
 static int
 glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
 {