1*** lib/fnmatch_loop.c.bak	2006-07-11 13:54:17.000000000 +0200
2--- lib/fnmatch_loop.c	2006-07-30 21:03:04.000000000 +0200
3***************
4*** 1003,1022 ****
5    struct patternlist
6    {
7      struct patternlist *next;
8      CHAR str[1];
9    } *list = NULL;
10    struct patternlist **lastp = &list;
11    size_t pattern_len = STRLEN (pattern);
12    const CHAR *p;
13    const CHAR *rs;
14    enum { ALLOCA_LIMIT = 8000 };
15  
16    /* Parse the pattern.  Store the individual parts in the list.  */
17    level = 0;
18    for (startp = p = pattern + 1; ; ++p)
19      if (*p == L_('\0'))
20        /* This is an invalid pattern.  */
21!       return -1;
22      else if (*p == L_('['))
23        {
24  	/* Handle brackets special.  */
25--- 1003,1028 ----
26    struct patternlist
27    {
28      struct patternlist *next;
29+     int malloced;
30      CHAR str[1];
31    } *list = NULL;
32    struct patternlist **lastp = &list;
33    size_t pattern_len = STRLEN (pattern);
34    const CHAR *p;
35    const CHAR *rs;
36+ #if HAVE_ALLOCA || defined _LIBC
37    enum { ALLOCA_LIMIT = 8000 };
38+ #else
39+   enum { ALLOCA_LIMIT = 0 };
40+ #endif
41+   int retval;
42  
43    /* Parse the pattern.  Store the individual parts in the list.  */
44    level = 0;
45    for (startp = p = pattern + 1; ; ++p)
46      if (*p == L_('\0'))
47        /* This is an invalid pattern.  */
48!       goto failed;
49      else if (*p == L_('['))
50        {
51  	/* Handle brackets special.  */
52***************
53*** 1034,1040 ****
54  	while (*p != L_(']'))
55  	  if (*p++ == L_('\0'))
56  	    /* This is no valid pattern.  */
57! 	    return -1;
58        }
59      else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
60  	      || *p == L_('!')) && p[1] == L_('('))
61--- 1040,1046 ----
62  	while (*p != L_(']'))
63  	  if (*p++ == L_('\0'))
64  	    /* This is no valid pattern.  */
65! 	    goto failed;
66        }
67      else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@')
68  	      || *p == L_('!')) && p[1] == L_('('))
69***************
70*** 1057,1067 ****
71  	    plensize = plen * sizeof (CHAR);				      \
72  	    newpsize = offsetof (struct patternlist, str) + plensize;	      \
73  	    if ((size_t) -1 / sizeof (CHAR) < plen			      \
74! 		|| newpsize < offsetof (struct patternlist, str)	      \
75! 		|| ALLOCA_LIMIT <= newpsize)				      \
76! 	      return -1;						      \
77! 	    newp = (struct patternlist *) alloca (newpsize);		      \
78! 	    *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');    \
79  	    newp->next = NULL;						      \
80  	    *lastp = newp;						      \
81  	    lastp = &newp->next
82--- 1063,1083 ----
83  	    plensize = plen * sizeof (CHAR);				      \
84  	    newpsize = offsetof (struct patternlist, str) + plensize;	      \
85  	    if ((size_t) -1 / sizeof (CHAR) < plen			      \
86! 		|| newpsize < offsetof (struct patternlist, str))	      \
87! 	      goto failed;						      \
88! 	    if (newpsize < ALLOCA_LIMIT)				      \
89! 	      {								      \
90! 		newp = (struct patternlist *) alloca (newpsize);	      \
91! 		newp->malloced = 0;					      \
92! 	      }								      \
93! 	    else							      \
94! 	      {								      \
95! 		newp = (struct patternlist *) malloc (newpsize);	      \
96! 		if (!newp)						      \
97! 		  goto failed;						      \
98! 		newp->malloced = 1;					      \
99! 	      }								      \
100! 	    *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0');   \
101  	    newp->next = NULL;						      \
102  	    *lastp = newp;						      \
103  	    lastp = &newp->next
104***************
105*** 1085,1096 ****
106      {
107      case L_('*'):
108        if (FCT (p, string, string_end, no_leading_period, flags) == 0)
109! 	return 0;
110        /* FALLTHROUGH */
111  
112      case L_('+'):
113        do
114  	{
115  	  for (rs = string; rs <= string_end; ++rs)
116  	    /* First match the prefix with the current pattern with the
117  	       current pattern.  */
118--- 1101,1117 ----
119      {
120      case L_('*'):
121        if (FCT (p, string, string_end, no_leading_period, flags) == 0)
122! 	{
123! 	  retval = 0;
124! 	  goto done;
125! 	}
126        /* FALLTHROUGH */
127  
128      case L_('+'):
129        do
130  	{
131+ 	  struct patternlist *next;
132+ 
133  	  for (rs = string; rs <= string_end; ++rs)
134  	    /* First match the prefix with the current pattern with the
135  	       current pattern.  */
136***************
137*** 1112,1142 ****
138  				: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
139  				flags & FNM_FILE_NAME
140  				? flags : flags & ~FNM_PERIOD) == 0)))
141! 	      /* It worked.  Signal success.  */
142! 	      return 0;
143  	}
144!       while ((list = list->next) != NULL);
145  
146        /* None of the patterns lead to a match.  */
147        return FNM_NOMATCH;
148  
149      case L_('?'):
150        if (FCT (p, string, string_end, no_leading_period, flags) == 0)
151! 	return 0;
152        /* FALLTHROUGH */
153  
154      case L_('@'):
155        do
156! 	/* I cannot believe it but `strcat' is actually acceptable
157! 	   here.  Match the entire string with the prefix from the
158! 	   pattern list and the rest of the pattern following the
159! 	   pattern list.  */
160! 	if (FCT (STRCAT (list->str, p), string, string_end,
161! 		 no_leading_period,
162! 		 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
163! 	  /* It worked.  Signal success.  */
164! 	  return 0;
165!       while ((list = list->next) != NULL);
166  
167        /* None of the patterns lead to a match.  */
168        return FNM_NOMATCH;
169--- 1133,1186 ----
170  				: rs[-1] == '/' && NO_LEADING_PERIOD (flags),
171  				flags & FNM_FILE_NAME
172  				? flags : flags & ~FNM_PERIOD) == 0)))
173! 	      {
174! 		/* It worked.  Signal success.  */
175! 		retval = 0;
176! 		goto done;
177! 	      }
178! 
179! 	  next = list->next;
180! 	  if (list->malloced)
181! 	    free (list);
182! 	  list = next;
183  	}
184!       while (list != NULL);
185  
186        /* None of the patterns lead to a match.  */
187        return FNM_NOMATCH;
188  
189      case L_('?'):
190        if (FCT (p, string, string_end, no_leading_period, flags) == 0)
191! 	{
192! 	  retval = 0;
193! 	  goto done;
194! 	}
195        /* FALLTHROUGH */
196  
197      case L_('@'):
198        do
199! 	{
200! 	  struct patternlist *next;
201! 
202! 	  /* I cannot believe it but `strcat' is actually acceptable
203! 	     here.  Match the entire string with the prefix from the
204! 	     pattern list and the rest of the pattern following the
205! 	     pattern list.  */
206! 	  if (FCT (STRCAT (list->str, p), string, string_end,
207! 		   no_leading_period,
208! 		   flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)
209! 	    {
210! 	      /* It worked.  Signal success.  */
211! 	      retval = 0;
212! 	      goto done;
213! 	    }
214! 
215! 	  next = list->next;
216! 	  if (list->malloced)
217! 	    free (list);
218! 	  list = next;
219! 	}
220!       while (list != NULL);
221  
222        /* None of the patterns lead to a match.  */
223        return FNM_NOMATCH;
224***************
225*** 1159,1178 ****
226  		       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
227  		       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
228  		  == 0))
229! 	    /* This is successful.  */
230! 	    return 0;
231  	}
232  
233        /* None of the patterns together with the rest of the pattern
234  	 lead to a match.  */
235!       return FNM_NOMATCH;
236  
237      default:
238        assert (! "Invalid extended matching operator");
239        break;
240      }
241  
242!   return -1;
243  }
244  
245  
246--- 1203,1237 ----
247  		       : rs[-1] == '/' && NO_LEADING_PERIOD (flags),
248  		       flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD)
249  		  == 0))
250! 	    {
251! 	      /* This is successful.  */
252! 	      retval = 0;
253! 	      goto done;
254! 	    }
255  	}
256  
257        /* None of the patterns together with the rest of the pattern
258  	 lead to a match.  */
259!       retval = FNM_NOMATCH;
260!       goto done;
261  
262      default:
263        assert (! "Invalid extended matching operator");
264        break;
265      }
266  
267!  failed:
268!   retval = -1;
269!  done:
270!   while (list != NULL)
271!     {
272!       struct patternlist *next = list->next;
273! 
274!       if (list->malloced)
275! 	free (list);
276!       list = next;
277!     }
278!   return retval;
279  }
280  
281  
282