summaryrefslogtreecommitdiff
path: root/openbsd-compat/glob.c
diff options
context:
space:
mode:
Diffstat (limited to 'openbsd-compat/glob.c')
-rw-r--r--openbsd-compat/glob.c69
1 files changed, 60 insertions, 9 deletions
diff --git a/openbsd-compat/glob.c b/openbsd-compat/glob.c
index 0341225cd..742b4b954 100644
--- a/openbsd-compat/glob.c
+++ b/openbsd-compat/glob.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: glob.c,v 1.35 2011/01/12 01:53:14 djm 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.
@@ -66,6 +66,7 @@
66#include <dirent.h> 66#include <dirent.h>
67#include <ctype.h> 67#include <ctype.h>
68#include <errno.h> 68#include <errno.h>
69#include <limits.h>
69#include <pwd.h> 70#include <pwd.h>
70#include <stdlib.h> 71#include <stdlib.h>
71#include <string.h> 72#include <string.h>
@@ -132,13 +133,22 @@ typedef char Char;
132#define GLOB_LIMIT_STAT 128 133#define GLOB_LIMIT_STAT 128
133#define GLOB_LIMIT_READDIR 16384 134#define GLOB_LIMIT_READDIR 16384
134 135
136/* Limit of recursion during matching attempts. */
137#define GLOB_LIMIT_RECUR 64
138
135struct glob_lim { 139struct glob_lim {
136 size_t glim_malloc; 140 size_t glim_malloc;
137 size_t glim_stat; 141 size_t glim_stat;
138 size_t glim_readdir; 142 size_t glim_readdir;
139}; 143};
140 144
145struct glob_path_stat {
146 char *gps_path;
147 struct stat *gps_stat;
148};
149
141static int compare(const void *, const void *); 150static int compare(const void *, const void *);
151static int compare_gps(const void *, const void *);
142static int g_Ctoc(const Char *, char *, u_int); 152static int g_Ctoc(const Char *, char *, u_int);
143static int g_lstat(Char *, struct stat *, glob_t *); 153static int g_lstat(Char *, struct stat *, glob_t *);
144static DIR *g_opendir(Char *, glob_t *); 154static DIR *g_opendir(Char *, glob_t *);
@@ -158,7 +168,7 @@ static const Char *
158static int globexp1(const Char *, glob_t *, struct glob_lim *); 168static int globexp1(const Char *, glob_t *, struct glob_lim *);
159static int globexp2(const Char *, const Char *, glob_t *, 169static int globexp2(const Char *, const Char *, glob_t *,
160 struct glob_lim *); 170 struct glob_lim *);
161static int match(Char *, Char *, Char *); 171static int match(Char *, Char *, Char *, int);
162#ifdef DEBUG 172#ifdef DEBUG
163static void qprintf(const char *, Char *); 173static void qprintf(const char *, Char *);
164#endif 174#endif
@@ -172,6 +182,9 @@ glob(const char *pattern, int flags, int (*errfunc)(const char *, int),
172 Char *bufnext, *bufend, patbuf[MAXPATHLEN]; 182 Char *bufnext, *bufend, patbuf[MAXPATHLEN];
173 struct glob_lim limit = { 0, 0, 0 }; 183 struct glob_lim limit = { 0, 0, 0 };
174 184
185 if (strnlen(pattern, PATH_MAX) == PATH_MAX)
186 return(GLOB_NOMATCH);
187
175 patnext = (u_char *) pattern; 188 patnext = (u_char *) pattern;
176 if (!(flags & GLOB_APPEND)) { 189 if (!(flags & GLOB_APPEND)) {
177 pglob->gl_pathc = 0; 190 pglob->gl_pathc = 0;
@@ -548,9 +561,32 @@ glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
548 else 561 else
549 return(GLOB_NOMATCH); 562 return(GLOB_NOMATCH);
550 } 563 }
551 if (!(pglob->gl_flags & GLOB_NOSORT)) 564 if (!(pglob->gl_flags & GLOB_NOSORT)) {
552 qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, 565 if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
553 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 }
554 return(0); 590 return(0);
555} 591}
556 592
@@ -561,6 +597,15 @@ compare(const void *p, const void *q)
561} 597}
562 598
563static 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
564glob1(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)
565{ 610{
566 Char pathbuf[MAXPATHLEN]; 611 Char pathbuf[MAXPATHLEN];
@@ -697,7 +742,8 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
697 errno = 0; 742 errno = 0;
698 *pathend++ = SEP; 743 *pathend++ = SEP;
699 *pathend = EOS; 744 *pathend = EOS;
700 return(GLOB_NOSPACE); 745 err = GLOB_NOSPACE;
746 break;
701 } 747 }
702 748
703 /* Initial DOT must be matched literally. */ 749 /* Initial DOT must be matched literally. */
@@ -713,7 +759,7 @@ glob3(Char *pathbuf, Char *pathbuf_last, Char *pathend, Char *pathend_last,
713 break; 759 break;
714 } 760 }
715 761
716 if (!match(pathend, pattern, restpattern)) { 762 if (!match(pathend, pattern, restpattern, GLOB_LIMIT_RECUR)) {
717 *pathend = EOS; 763 *pathend = EOS;
718 continue; 764 continue;
719 } 765 }
@@ -850,19 +896,24 @@ globextend(const Char *path, glob_t *pglob, struct glob_lim *limitp,
850 * pattern causes a recursion level. 896 * pattern causes a recursion level.
851 */ 897 */
852static int 898static int
853match(Char *name, Char *pat, Char *patend) 899match(Char *name, Char *pat, Char *patend, int recur)
854{ 900{
855 int ok, negate_range; 901 int ok, negate_range;
856 Char c, k; 902 Char c, k;
857 903
904 if (recur-- == 0)
905 return(GLOB_NOSPACE);
906
858 while (pat < patend) { 907 while (pat < patend) {
859 c = *pat++; 908 c = *pat++;
860 switch (c & M_MASK) { 909 switch (c & M_MASK) {
861 case M_ALL: 910 case M_ALL:
911 while (pat < patend && (*pat & M_MASK) == M_ALL)
912 pat++; /* eat consecutive '*' */
862 if (pat == patend) 913 if (pat == patend)
863 return(1); 914 return(1);
864 do { 915 do {
865 if (match(name, pat, patend)) 916 if (match(name, pat, patend, recur))
866 return(1); 917 return(1);
867 } while (*name++ != EOS); 918 } while (*name++ != EOS);
868 return(0); 919 return(0);