X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=glob.c;h=9673626531776c465f47e40f3efd9cb33d099e96;hb=bae76b8ef69fd40419f9031b57b3e7c21e407843;hp=5319c130c306a74c1131a7f6018b697e5c5906bf;hpb=98decbe90438de26497d15e69e991172fc28266b;p=debian%2Fsudo diff --git a/glob.c b/glob.c index 5319c13..9673626 100644 --- a/glob.c +++ b/glob.c @@ -1,6 +1,5 @@ -/* $OpenBSD: glob.c,v 1.23 2004/05/18 02:05:52 jfb Exp $ */ - /* + * Copyright (c) 2008-2010 Todd C. Miller * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. * @@ -70,11 +69,10 @@ #endif /* HAVE_MALLOC_H && !STDC_HEADERS */ #ifdef HAVE_STRING_H # include -#else -# ifdef HAVE_STRINGS_H -# include -# endif #endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ @@ -99,6 +97,7 @@ #include #include "emul/glob.h" +#include "emul/charclass.h" #define DOLLAR '$' #define DOT '.' @@ -147,6 +146,7 @@ typedef char Char; #define M_ONE META('?') #define M_RNG META('-') #define M_SET META('[') +#define M_CLASS META(':') #define ismeta(c) (((c)&M_QUOTE) != 0) @@ -154,7 +154,8 @@ static int compare __P((const void *, const void *)); static int g_Ctoc __P((const Char *, char *, unsigned int)); static int g_lstat __P((Char *, struct stat *, glob_t *)); static DIR *g_opendir __P((Char *, glob_t *)); -static Char *g_strchr __P((Char *, int)); +static Char *g_strchr __P((const Char *, int)); +static int g_strncmp __P((const Char *, const char *, size_t)); static int g_stat __P((Char *, struct stat *, glob_t *)); static int glob0 __P((const Char *, glob_t *)); static int glob1 __P((Char *, Char *, glob_t *)); @@ -172,6 +173,9 @@ static int match __P((Char *, Char *, Char *)); static void qprintf __P((const char *, Char *)); #endif +extern struct passwd *sudo_getpwnam __P((const char *)); +extern struct passwd *sudo_getpwuid __P((uid_t)); + int glob(pattern, flags, errfunc, pglob) const char *pattern; @@ -235,7 +239,7 @@ globexp1(pattern, pglob) if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob); - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv)) return rv; @@ -385,7 +389,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob) * first and then trying the password file */ if ((h = getenv("HOME")) == NULL) { - if ((pwd = getpwuid(getuid())) == NULL) + if ((pwd = sudo_getpwuid(getuid())) == NULL) return pattern; else h = pwd->pw_dir; @@ -394,7 +398,7 @@ globtilde(pattern, patbuf, patbuf_len, pglob) /* * Expand a ~user */ - if ((pwd = getpwnam((char*) patbuf)) == NULL) + if ((pwd = sudo_getpwnam((char*) patbuf)) == NULL) return pattern; else h = pwd->pw_dir; @@ -412,6 +416,52 @@ globtilde(pattern, patbuf, patbuf_len, pglob) return patbuf; } +static int +g_strncmp(s1, s2, n) + const Char *s1; + const char *s2; + size_t n; +{ + int rv = 0; + + while (n--) { + rv = *(Char *)s1 - *(const unsigned char *)s2++; + if (rv) + break; + if (*s1++ == '\0') + break; + } + return rv; +} + +static int +g_charclass(patternp, bufnextp) + const Char **patternp; + Char **bufnextp; +{ + const Char *pattern = *patternp + 1; + Char *bufnext = *bufnextp; + const Char *colon; + struct cclass *cc; + size_t len; + + if ((colon = g_strchr(pattern, ':')) == NULL || colon[1] != ']') + return 1; /* not a character class */ + + len = (size_t)(colon - pattern); + for (cc = cclasses; cc->name != NULL; cc++) { + if (!g_strncmp(pattern, cc->name, len) && cc->name[len] == '\0') + break; + } + if (cc->name == NULL) + return -1; /* invalid character class */ + *bufnext++ = M_CLASS; + *bufnext++ = (Char)(cc - &cclasses[0]); + *bufnextp = bufnext; + *patternp += len + 3; + + return 0; +} /* * The main glob() routine: compiles the pattern (optionally processing @@ -441,7 +491,7 @@ glob0(pattern, pglob) if (c == NOT) ++qpatnext; if (*qpatnext == EOS || - g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; @@ -452,6 +502,20 @@ glob0(pattern, pglob) *bufnext++ = M_NOT; c = *qpatnext++; do { + if (c == LBRACKET && *qpatnext == ':') { + do { + err = g_charclass(&qpatnext, + &bufnext); + if (err) + break; + c = *qpatnext++; + } while (c == LBRACKET && *qpatnext == ':'); + if (err == -1 && + !(pglob->gl_flags & GLOB_NOCHECK)) + return GLOB_NOMATCH; + if (c == RBRACKET) + break; + } *bufnext++ = CHAR(c); if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) { @@ -749,13 +813,21 @@ match(name, pat, patend) return(0); if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) ++pat; - while (((c = *pat++) & M_MASK) != M_END) + while (((c = *pat++) & M_MASK) != M_END) { + if ((c & M_MASK) == M_CLASS) { + int idx = *pat & M_MASK; + if (idx < NCCLASSES && + cclasses[idx].isctype(k)) + ok = 1; + ++pat; + } if ((*pat & M_MASK) == M_RNG) { if (c <= k && k <= pat[1]) ok = 1; pat += 2; } else if (c == k) ok = 1; + } if (ok == negate_range) return(0); break; @@ -831,12 +903,12 @@ g_stat(fn, sb, pglob) static Char * g_strchr(str, ch) - Char *str; + const Char *str; int ch; { do { if (*str == ch) - return (str); + return ((Char *)str); } while (*str++); return (NULL); }