diff options
Diffstat (limited to 'lib/glob')
-rw-r--r-- | lib/glob/Makefile.in | 2 | ||||
-rw-r--r-- | lib/glob/glob.c | 59 | ||||
-rw-r--r-- | lib/glob/glob_loop.c | 2 | ||||
-rw-r--r-- | lib/glob/sm_loop.c | 17 | ||||
-rw-r--r-- | lib/glob/smatch.c | 10 | ||||
-rw-r--r-- | lib/glob/xmbsrtowcs.c | 19 |
6 files changed, 85 insertions, 24 deletions
diff --git a/lib/glob/Makefile.in b/lib/glob/Makefile.in index cddfd3f..9bb4dd3 100644 --- a/lib/glob/Makefile.in +++ b/lib/glob/Makefile.in @@ -4,7 +4,7 @@ # # #################################################################### # -# Copyright (C) 1996 Free Software Foundation, Inc. +# Copyright (C) 1996-2005 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff --git a/lib/glob/glob.c b/lib/glob/glob.c index a62054e..9a2d833 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -1,6 +1,6 @@ /* glob.c -- file-name wildcard pattern matching for Bash. - Copyright (C) 1985-2002 Free Software Foundation, Inc. + Copyright (C) 1985-2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -66,6 +66,12 @@ # define FREE(x) if (x) free (x) #endif +/* Don't try to alloca() more than this much memory for `struct globval' + in glob_vector() */ +#ifndef ALLOCA_MAX +# define ALLOCA_MAX 100000 +#endif + extern void throw_to_top_level __P((void)); extern int test_eaccess __P((char *, int)); @@ -127,13 +133,13 @@ glob_pattern_p (pattern) int r; if (MB_CUR_MAX == 1) - return (internal_glob_pattern_p (pattern)); + return (internal_glob_pattern_p ((unsigned char *)pattern)); /* Convert strings to wide chars, and call the multibyte version. */ n = xdupmbstowcs (&wpattern, NULL, pattern); if (n == (size_t)-1) /* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */ - return (internal_glob_pattern_p (pattern)); + return (internal_glob_pattern_p ((unsigned char *)pattern)); r = internal_glob_wpattern_p (wpattern); free (wpattern); @@ -347,10 +353,14 @@ glob_vector (pat, dir, flags) register char **name_vector; register unsigned int i; int mflags; /* Flags passed to strmatch (). */ + int nalloca; + struct globval *firstmalloc, *tmplink; lastlink = 0; count = lose = skip = 0; + firstmalloc = 0; + /* If PAT is empty, skip the loop, but return one (empty) filename. */ if (pat == 0 || *pat == '\0') { @@ -488,8 +498,18 @@ glob_vector (pat, dir, flags) if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH) { + if (nalloca < ALLOCA_MAX) + { + nextlink = (struct globval *) alloca (sizeof (struct globval)); + nalloca += sizeof (struct globval); + } + else + { + nextlink = (struct globval *) malloc (sizeof (struct globval)); + if (firstmalloc == 0) + firstmalloc = nextlink; + } nextname = (char *) malloc (D_NAMLEN (dp) + 1); - nextlink = (struct globval *) alloca (sizeof (struct globval)); if (nextlink == 0 || nextname == 0) { lose = 1; @@ -515,11 +535,20 @@ glob_vector (pat, dir, flags) /* Have we run out of memory? */ if (lose) { + tmplink = 0; + /* Here free the strings we have got. */ while (lastlink) { + if (firstmalloc) + { + if (lastlink == firstmalloc) + firstmalloc = 0; + tmplink = lastlink; + } free (lastlink->name); lastlink = lastlink->next; + FREE (tmplink); } QUIT; @@ -528,13 +557,29 @@ glob_vector (pat, dir, flags) } /* Copy the name pointers from the linked list into the vector. */ - for (i = 0; i < count; ++i) + for (tmplink = lastlink, i = 0; i < count; ++i) { - name_vector[i] = lastlink->name; - lastlink = lastlink->next; + name_vector[i] = tmplink->name; + tmplink = tmplink->next; } name_vector[count] = NULL; + + /* If we allocated some of the struct globvals, free them now. */ + if (firstmalloc) + { + tmplink = 0; + while (lastlink) + { + tmplink = lastlink; + if (lastlink == firstmalloc) + lastlink = firstmalloc = 0; + else + lastlink = lastlink->next; + free (tmplink); + } + } + return (name_vector); } diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c index 8010df7..253cac9 100644 --- a/lib/glob/glob_loop.c +++ b/lib/glob/glob_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2002 Free Software Foundation, Inc. +/* Copyright (C) 1991-2005 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. diff --git a/lib/glob/sm_loop.c b/lib/glob/sm_loop.c index a8b70f7..6e8cf3a 100644 --- a/lib/glob/sm_loop.c +++ b/lib/glob/sm_loop.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2004 Free Software Foundation, Inc. +/* Copyright (C) 1991-2005 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -358,7 +358,7 @@ BRACKMATCH (p, test, flags) { bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR)); *(ccname + (close - p - 1)) = L('\0'); - pc = IS_CCLASS (test, ccname); + pc = IS_CCLASS (test, (XCHAR *)ccname); } if (pc == -1) pc = 0; @@ -522,11 +522,11 @@ PATSCAN (string, end, delim) CHAR *string, *end; INT delim; { - int pnest, bnest; + int pnest, bnest, skip; INT cchar; CHAR *s, c, *bfirst; - pnest = bnest = 0; + pnest = bnest = skip = 0; cchar = 0; bfirst = NULL; @@ -534,8 +534,17 @@ PATSCAN (string, end, delim) { if (s >= end) return (s); + if (skip) + { + skip = 0; + continue; + } switch (c) { + case L('\\'): + skip = 1; + break; + case L('\0'): return ((CHAR *)NULL); diff --git a/lib/glob/smatch.c b/lib/glob/smatch.c index d0b7403..12fde3d 100644 --- a/lib/glob/smatch.c +++ b/lib/glob/smatch.c @@ -1,7 +1,7 @@ /* strmatch.c -- ksh-like extended pattern matching for the shell and filename globbing. */ -/* Copyright (C) 1991-2002 Free Software Foundation, Inc. +/* Copyright (C) 1991-2005 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -93,14 +93,16 @@ collequiv (c1, c2) static int collsym (s, len) - char *s; + CHAR *s; int len; { register struct _collsym *csp; + char *x; + x = (char *)s; for (csp = posix_collsyms; csp->name; csp++) { - if (STREQN(csp->name, s, len) && csp->name[len] == '\0') + if (STREQN(csp->name, x, len) && csp->name[len] == '\0') return (csp->code); } if (len == 1) @@ -366,7 +368,7 @@ xstrmatch (pattern, string, flags) wchar_t *wpattern, *wstring; if (MB_CUR_MAX == 1) - return (internal_strmatch (pattern, string, flags)); + return (internal_strmatch ((unsigned char *)pattern, (unsigned char *)string, flags)); n = xdupmbstowcs (&wpattern, NULL, pattern); if (n == (size_t)-1 || n == (size_t)-2) diff --git a/lib/glob/xmbsrtowcs.c b/lib/glob/xmbsrtowcs.c index f1703bc..f8c29b9 100644 --- a/lib/glob/xmbsrtowcs.c +++ b/lib/glob/xmbsrtowcs.c @@ -1,6 +1,6 @@ /* xmbsrtowcs.c -- replacement function for mbsrtowcs */ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002-2004 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. @@ -54,7 +54,7 @@ xmbsrtowcs (dest, src, len, pstate) ps = &local_state; } - n = strlen(*src); + n = strlen (*src); if (dest == NULL) { @@ -62,19 +62,22 @@ xmbsrtowcs (dest, src, len, pstate) const char *mbs; mbstate_t psbuf; + /* It doesn't matter if malloc fails here, since mbsrtowcs should do + the right thing with a NULL first argument. */ wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t)); mbs = *src; psbuf = *ps; wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf); - free (wsbuf); + if (wsbuf) + free (wsbuf); return wclength; } for (wclength = 0; wclength < len; wclength++, dest++) { - if(mbsinit(ps)) + if (mbsinit(ps)) { if (**src == '\0') { @@ -166,10 +169,11 @@ xdupmbstowcs (destp, indicesp, src) p = src; wcnum = 0; - do { + do + { size_t mblength; /* Byte length of one multibyte character. */ - if(mbsinit (&state)) + if (mbsinit (&state)) { if (*p == '\0') { @@ -230,7 +234,8 @@ xdupmbstowcs (destp, indicesp, src) wsbuf[wcnum - 1] = wc; indices[wcnum - 1] = (char *)p; p += mblength; - } while (MB_NULLWCH (wc) == 0); + } + while (MB_NULLWCH (wc) == 0); /* Return the length of the wide character string, not including `\0'. */ *destp = wsbuf; |