aboutsummaryrefslogtreecommitdiffstats
path: root/lib/glob/glob.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/glob/glob.c')
-rw-r--r--lib/glob/glob.c59
1 files changed, 52 insertions, 7 deletions
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);
}