summaryrefslogtreecommitdiff
path: root/openbsd-compat/glob.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-09-22 21:22:21 +1000
committerDamien Miller <djm@mindrot.org>2011-09-22 21:22:21 +1000
commite128a50e35eb4eabcf234ada07f07b8749b5e49c (patch)
tree327a45dccfa1654f7ba2b74a4c1fad20eef324e7 /openbsd-compat/glob.c
parentc4bf7dde9231194f4e38140a46e9957758317cb5 (diff)
- 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@
Diffstat (limited to 'openbsd-compat/glob.c')
-rw-r--r--openbsd-compat/glob.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c
index 85fccf4d1..742b4b954 100644
--- a/openbsd-compat/glob.c
+++ b/openbsd-compat/glob.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: glob.c,v 1.37 2011/09/20 10:18:46 stsp Exp $ */ 1/* $OpenBSD: glob.c,v 1.38 2011/09/22 06:27:29 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1989, 1993 3 * Copyright (c) 1989, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -133,16 +133,22 @@ typedef char Char;
133#define GLOB_LIMIT_STAT 128 133#define GLOB_LIMIT_STAT 128
134#define GLOB_LIMIT_READDIR 16384 134#define GLOB_LIMIT_READDIR 16384
135 135
136/* Limit of recursion during matching attempts. */
137#define GLOB_LIMIT_RECUR 64
138
136struct glob_lim { 139struct glob_lim {
137 size_t glim_malloc; 140 size_t glim_malloc;
138 size_t glim_stat; 141 size_t glim_stat;
139 size_t glim_readdir; 142 size_t glim_readdir;
140}; 143};
141 144
142/* Limit of recursion during matching attempts. */ 145struct glob_path_stat {
143#define GLOB_LIMIT_RECUR 64 146 char *gps_path;
147 struct stat *gps_stat;
148};
144 149
145static int compare(const void *, const void *); 150static int compare(const void *, const void *);
151static int compare_gps(const void *, const void *);
146static int g_Ctoc(const Char *, char *, u_int); 152static int g_Ctoc(const Char *, char *, u_int);
147static int g_lstat(Char *, struct stat *, glob_t *); 153static int g_lstat(Char *, struct stat *, glob_t *);
148static DIR *g_opendir(Char *, glob_t *); 154static DIR *g_opendir(Char *, glob_t *);
@@ -555,9 +561,32 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
555 else 561 else
556 return(GLOB_NOMATCH); 562 return(GLOB_NOMATCH);
557 } 563 }
558 if (!(pglob->gl_flags & GLOB_NOSORT)) 564 if (!(pglob->gl_flags & GLOB_NOSORT)) {
559 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, 565 if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
560 pglob->gl_pathc - oldpathc, sizeof(char *), compare); 566 /* Keep the paths and stat info synced during sort */
567 struct glob_path_stat *path_stat;
568 int i;
569 int n = pglob->gl_pathc - oldpathc;
570 int o = pglob->gl_offs + oldpathc;
571
572 if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL)
573 return GLOB_NOSPACE;
574 for (i = 0; i < n; i++) {
575 path_stat[i].gps_path = pglob->gl_pathv[o + i];
576 path_stat[i].gps_stat = pglob->gl_statv[o + i];
577 }
578 qsort(path_stat, n, sizeof(*path_stat), compare_gps);
579 for (i = 0; i < n; i++) {
580 pglob->gl_pathv[o + i] = path_stat[i].gps_path;
581 pglob->gl_statv[o + i] = path_stat[i].gps_stat;
582 }
583 free(path_stat);
584 } else {
585 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
586 pglob->gl_pathc - oldpathc, sizeof(char *),
587 compare);
588 }
589 }
561 return(0); 590 return(0);
562} 591}
563 592
@@ -568,6 +597,15 @@ compare(const void *p, const void *q)
568} 597}
569 598
570static int 599static int
600compare_gps(const void *_p, const void *_q)
601{
602 const struct glob_path_stat *p = (const struct glob_path_stat *)_p;
603 const struct glob_path_stat *q = (const struct glob_path_stat *)_q;
604
605 return(strcmp(p->gps_path, q->gps_path));
606}
607
608static int
571glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp) 609glob1(Char *pattern, Char *pattern_last, glob_t *pglob, struct glob_lim *limitp)
572{ 610{
573 Char pathbuf[MAXPATHLEN]; 611 Char pathbuf[MAXPATHLEN];