]>
Commit | Line | Data |
---|---|---|
fbd86d4c A |
1 | --- glob.c.orig 2011-01-25 17:41:37.000000000 -0800 |
2 | +++ glob.c 2011-01-26 11:50:09.000000000 -0800 | |
3 | @@ -36,6 +36,8 @@ static char sccsid[] = "@(#)glob.c 8.3 ( | |
3d9156a7 | 4 | #include <sys/cdefs.h> |
fbd86d4c | 5 | __FBSDID("$FreeBSD: src/lib/libc/gen/glob.c,v 1.28 2010/05/12 17:44:00 gordon Exp $"); |
3d9156a7 A |
6 | |
7 | +#include "xlocale_private.h" | |
8 | + | |
9 | /* | |
10 | * glob(3) -- a superset of the one defined in POSIX 1003.2. | |
11 | * | |
fbd86d4c A |
12 | @@ -89,6 +91,19 @@ __FBSDID("$FreeBSD: src/lib/libc/gen/glo |
13 | ||
14 | #include "collate.h" | |
15 | ||
16 | +#define GLOB_LIMIT_STRING 65536 /* number of readdirs */ | |
17 | +#define GLOB_LIMIT_STAT 128 /* number of stat system calls */ | |
18 | +#define GLOB_LIMIT_READDIR 16384 /* total buffer size of path strings */ | |
19 | +#define GLOB_LIMIT_PATH 1024 /* number of path elements */ | |
20 | +#define GLOB_LIMIT_BRACE 128 /* Number of brace calls */ | |
21 | + | |
22 | +struct glob_limit { | |
23 | + size_t l_string; | |
24 | + size_t l_stat; | |
25 | + size_t l_readdir; | |
26 | + size_t l_brace; | |
27 | +}; | |
28 | + | |
29 | #define DOLLAR '$' | |
30 | #define DOT '.' | |
31 | #define EOS '\0' | |
32 | @@ -139,62 +154,64 @@ typedef char Char; | |
224c7076 | 33 | #define ismeta(c) (((c)&M_QUOTE) != 0) |
3d9156a7 | 34 | |
b5d655f7 A |
35 | |
36 | -static int compare(const void *, const void *); | |
fbd86d4c | 37 | -static int g_Ctoc(const Char *, char *, size_t); |
b5d655f7 A |
38 | -static int g_lstat(Char *, struct stat *, glob_t *); |
39 | -static DIR *g_opendir(Char *, glob_t *); | |
fbd86d4c | 40 | -static const Char *g_strchr(const Char *, wchar_t); |
b5d655f7 | 41 | +#define compare __gl_compare |
224c7076 | 42 | +#define g_Ctoc __gl_g_Ctoc |
b5d655f7 | 43 | +#define g_strchr __gl_g_strchr |
224c7076 | 44 | +#define globextend __gl_globextend |
b5d655f7 A |
45 | +#define globtilde __gl_globtilde |
46 | +#define match __gl_match | |
fbd86d4c A |
47 | +__private_extern__ int compare(const void *, const void *); |
48 | +__private_extern__ int g_Ctoc(const Char *, char *, size_t, locale_t); | |
49 | +__private_extern__ const Char *g_strchr(const Char *, wchar_t); | |
50 | +__private_extern__ int globextend(const Char *, glob_t *, struct glob_limit *, locale_t); | |
b5d655f7 A |
51 | +__private_extern__ const Char * |
52 | + globtilde(const Char *, Char *, size_t, glob_t *); | |
fbd86d4c | 53 | +__private_extern__ int match(Char *, Char *, Char *, locale_t); |
224c7076 | 54 | + |
b5d655f7 A |
55 | + |
56 | +static int g_lstat(Char *, struct stat *, glob_t *, locale_t); | |
3d9156a7 | 57 | +static DIR *g_opendir(Char *, glob_t *, locale_t); |
3d9156a7 A |
58 | #ifdef notdef |
59 | static Char *g_strcat(Char *, const Char *); | |
60 | #endif | |
61 | -static int g_stat(Char *, struct stat *, glob_t *); | |
fbd86d4c A |
62 | -static int glob0(const Char *, glob_t *, size_t *); |
63 | -static int glob1(Char *, glob_t *, size_t *); | |
64 | -static int glob2(Char *, Char *, Char *, Char *, glob_t *, size_t *); | |
65 | -static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, size_t *); | |
66 | -static int globextend(const Char *, glob_t *, size_t *); | |
b5d655f7 A |
67 | -static const Char * |
68 | - globtilde(const Char *, Char *, size_t, glob_t *); | |
fbd86d4c A |
69 | -static int globexp1(const Char *, glob_t *, size_t *); |
70 | -static int globexp2(const Char *, const Char *, glob_t *, int *, size_t *); | |
3d9156a7 | 71 | -static int match(Char *, Char *, Char *); |
b5d655f7 | 72 | +static int g_stat(Char *, struct stat *, glob_t *, locale_t); |
fbd86d4c A |
73 | +static int glob0(const Char *, glob_t *, struct glob_limit *, locale_t); |
74 | +static int glob1(Char *, glob_t *, struct glob_limit *, locale_t); | |
75 | +static int glob2(Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *, locale_t); | |
76 | +static int glob3(Char *, Char *, Char *, Char *, Char *, glob_t *, struct glob_limit *, locale_t); | |
77 | +static int globexp1(const Char *, glob_t *, struct glob_limit *, locale_t); | |
78 | +static int globexp2(const Char *, const Char *, glob_t *, int *, struct glob_limit *, locale_t); | |
3d9156a7 A |
79 | #ifdef DEBUG |
80 | static void qprintf(const char *, Char *); | |
81 | #endif | |
34e8f829 A |
82 | |
83 | -int | |
fbd86d4c | 84 | -glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) |
34e8f829 | 85 | +static int |
fbd86d4c | 86 | +__glob(const char *pattern, glob_t *pglob) |
34e8f829 | 87 | { |
fbd86d4c A |
88 | const char *patnext; |
89 | - size_t limit; | |
90 | + struct glob_limit limit = { 0, 0, 0, 0 }; | |
91 | Char *bufnext, *bufend, patbuf[MAXPATHLEN], prot; | |
3d9156a7 A |
92 | mbstate_t mbs; |
93 | wchar_t wc; | |
94 | size_t clen; | |
95 | + locale_t loc = __current_locale(); | |
96 | + int mb_cur_max = MB_CUR_MAX_L(loc); | |
97 | ||
fbd86d4c | 98 | patnext = pattern; |
34e8f829 A |
99 | - if (!(flags & GLOB_APPEND)) { |
100 | + if (!(pglob->gl_flags & GLOB_APPEND)) { | |
101 | pglob->gl_pathc = 0; | |
102 | pglob->gl_pathv = NULL; | |
103 | - if (!(flags & GLOB_DOOFFS)) | |
104 | + if (!(pglob->gl_flags & GLOB_DOOFFS)) | |
105 | pglob->gl_offs = 0; | |
106 | } | |
107 | - if (flags & GLOB_LIMIT) { | |
fbd86d4c A |
108 | - limit = pglob->gl_matchc; |
109 | - if (limit == 0) | |
110 | - limit = ARG_MAX; | |
111 | - } else | |
112 | - limit = 0; | |
34e8f829 A |
113 | - pglob->gl_flags = flags & ~GLOB_MAGCHAR; |
114 | - pglob->gl_errfunc = errfunc; | |
115 | pglob->gl_matchc = 0; | |
116 | ||
117 | bufnext = patbuf; | |
3d9156a7 | 118 | bufend = bufnext + MAXPATHLEN - 1; |
34e8f829 A |
119 | - if (flags & GLOB_NOESCAPE) { |
120 | + if (pglob->gl_flags & GLOB_NOESCAPE) { | |
3d9156a7 A |
121 | memset(&mbs, 0, sizeof(mbs)); |
122 | - while (bufend - bufnext >= MB_CUR_MAX) { | |
123 | - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); | |
124 | + while (bufend - bufnext >= mb_cur_max) { | |
fbd86d4c | 125 | + clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc); |
3d9156a7 A |
126 | if (clen == (size_t)-1 || clen == (size_t)-2) |
127 | return (GLOB_NOMATCH); | |
128 | else if (clen == 0) | |
fbd86d4c | 129 | @@ -205,7 +222,7 @@ glob(const char *pattern, int flags, int |
3d9156a7 A |
130 | } else { |
131 | /* Protect the quoted characters. */ | |
132 | memset(&mbs, 0, sizeof(mbs)); | |
133 | - while (bufend - bufnext >= MB_CUR_MAX) { | |
134 | + while (bufend - bufnext >= mb_cur_max) { | |
135 | if (*patnext == QUOTE) { | |
136 | if (*++patnext == EOS) { | |
137 | *bufnext++ = QUOTE | M_PROTECT; | |
fbd86d4c | 138 | @@ -214,7 +231,7 @@ glob(const char *pattern, int flags, int |
3d9156a7 A |
139 | prot = M_PROTECT; |
140 | } else | |
141 | prot = 0; | |
142 | - clen = mbrtowc(&wc, patnext, MB_LEN_MAX, &mbs); | |
fbd86d4c | 143 | + clen = mbrtowc_l(&wc, patnext, MB_LEN_MAX, &mbs, loc); |
3d9156a7 A |
144 | if (clen == (size_t)-1 || clen == (size_t)-2) |
145 | return (GLOB_NOMATCH); | |
146 | else if (clen == 0) | |
fbd86d4c | 147 | @@ -225,11 +242,34 @@ glob(const char *pattern, int flags, int |
34e8f829 | 148 | } |
3d9156a7 A |
149 | *bufnext = EOS; |
150 | ||
34e8f829 | 151 | - if (flags & GLOB_BRACE) |
3d9156a7 | 152 | - return globexp1(patbuf, pglob, &limit); |
34e8f829 | 153 | + if (pglob->gl_flags & GLOB_BRACE) |
3d9156a7 A |
154 | + return globexp1(patbuf, pglob, &limit, loc); |
155 | else | |
156 | - return glob0(patbuf, pglob, &limit); | |
157 | + return glob0(patbuf, pglob, &limit, loc); | |
34e8f829 A |
158 | +} |
159 | + | |
160 | +int | |
fbd86d4c | 161 | +glob(const char *pattern, int flags, int (*errfunc)(const char *, int), glob_t *pglob) |
34e8f829 A |
162 | +{ |
163 | +#ifdef __BLOCKS__ | |
164 | + pglob->gl_flags = flags & ~(GLOB_MAGCHAR | _GLOB_ERR_BLOCK); | |
165 | +#else /* !__BLOCKS__ */ | |
166 | + pglob->gl_flags = flags & ~GLOB_MAGCHAR; | |
167 | +#endif /* __BLOCKS__ */ | |
168 | + pglob->gl_errfunc = errfunc; | |
169 | + return __glob(pattern, pglob); | |
170 | +} | |
171 | + | |
172 | +#ifdef __BLOCKS__ | |
173 | +int | |
fbd86d4c | 174 | +glob_b(const char *pattern, int flags, int (^errblk)(const char *, int), glob_t *pglob) |
34e8f829 A |
175 | +{ |
176 | + pglob->gl_flags = flags & ~GLOB_MAGCHAR; | |
177 | + pglob->gl_flags |= _GLOB_ERR_BLOCK; | |
178 | + pglob->gl_errblk = errblk; | |
179 | + return __glob(pattern, pglob); | |
3d9156a7 | 180 | } |
34e8f829 | 181 | +#endif /* __BLOCKS__ */ |
3d9156a7 A |
182 | |
183 | /* | |
34e8f829 | 184 | * Expand recursively a glob {} pattern. When there is no more expansion |
fbd86d4c | 185 | @@ -237,20 +277,26 @@ glob(const char *pattern, int flags, int |
3d9156a7 A |
186 | * characters |
187 | */ | |
b5d655f7 | 188 | static int |
fbd86d4c A |
189 | -globexp1(const Char *pattern, glob_t *pglob, size_t *limit) |
190 | +globexp1(const Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
191 | { |
192 | const Char* ptr = pattern; | |
193 | int rv; | |
194 | ||
fbd86d4c A |
195 | + if ((pglob->gl_flags & GLOB_LIMIT) && |
196 | + limit->l_brace++ >= GLOB_LIMIT_BRACE) { | |
197 | + errno = 0; | |
198 | + return GLOB_NOSPACE; | |
199 | + } | |
200 | + | |
3d9156a7 A |
201 | /* Protect a single {}, for find(1), like csh */ |
202 | if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) | |
203 | - return glob0(pattern, pglob, limit); | |
204 | + return glob0(pattern, pglob, limit, loc); | |
205 | ||
fbd86d4c | 206 | while ((ptr = g_strchr(ptr, LBRACE)) != NULL) |
3d9156a7 A |
207 | - if (!globexp2(ptr, pattern, pglob, &rv, limit)) |
208 | + if (!globexp2(ptr, pattern, pglob, &rv, limit, loc)) | |
209 | return rv; | |
210 | ||
211 | - return glob0(pattern, pglob, limit); | |
212 | + return glob0(pattern, pglob, limit, loc); | |
213 | } | |
214 | ||
215 | ||
fbd86d4c | 216 | @@ -260,7 +306,7 @@ globexp1(const Char *pattern, glob_t *pg |
3d9156a7 A |
217 | * If it fails then it tries to glob the rest of the pattern and returns. |
218 | */ | |
219 | static int | |
fbd86d4c A |
220 | -globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, size_t *limit) |
221 | +globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
222 | { |
223 | int i; | |
224 | Char *lm, *ls; | |
fbd86d4c | 225 | @@ -297,7 +343,7 @@ globexp2(const Char *ptr, const Char *pa |
3d9156a7 A |
226 | |
227 | /* Non matching braces; just glob the pattern */ | |
228 | if (i != 0 || *pe == EOS) { | |
229 | - *rv = glob0(patbuf, pglob, limit); | |
230 | + *rv = glob0(patbuf, pglob, limit, loc); | |
231 | return 0; | |
232 | } | |
233 | ||
fbd86d4c | 234 | @@ -344,7 +390,7 @@ globexp2(const Char *ptr, const Char *pa |
3d9156a7 A |
235 | #ifdef DEBUG |
236 | qprintf("globexp2:", patbuf); | |
237 | #endif | |
238 | - *rv = globexp1(patbuf, pglob, limit); | |
239 | + *rv = globexp1(patbuf, pglob, limit, loc); | |
240 | ||
241 | /* move after the comma, to the next string */ | |
242 | pl = pm + 1; | |
fbd86d4c | 243 | @@ -360,10 +406,11 @@ globexp2(const Char *ptr, const Char *pa |
b5d655f7 A |
244 | |
245 | ||
246 | ||
247 | +#ifndef BUILDING_VARIANT | |
248 | /* | |
249 | * expand tilde from the passwd file. | |
250 | */ | |
251 | -static const Char * | |
252 | +__private_extern__ const Char * | |
fbd86d4c A |
253 | globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) |
254 | { | |
255 | struct passwd *pwd; | |
256 | @@ -421,6 +468,7 @@ globtilde(const Char *pattern, Char *pat | |
b5d655f7 A |
257 | |
258 | return patbuf; | |
259 | } | |
260 | +#endif /* BUILDING_VARIANT */ | |
261 | ||
262 | ||
263 | /* | |
fbd86d4c | 264 | @@ -430,7 +478,7 @@ globtilde(const Char *pattern, Char *pat |
3d9156a7 A |
265 | * if things went well, nonzero if errors occurred. |
266 | */ | |
b5d655f7 | 267 | static int |
fbd86d4c A |
268 | -glob0(const Char *pattern, glob_t *pglob, size_t *limit) |
269 | +glob0(const Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
270 | { |
271 | const Char *qpatnext; | |
fbd86d4c A |
272 | int err; |
273 | @@ -443,6 +491,10 @@ glob0(const Char *pattern, glob_t *pglob | |
224c7076 A |
274 | |
275 | /* We don't need to check for buffer overflow any more. */ | |
276 | while ((c = *qpatnext++) != EOS) { | |
277 | + if (c & M_PROTECT) { | |
278 | + *bufnext++ = CHAR(c); | |
279 | + continue; | |
280 | + } /* else */ | |
281 | switch (c) { | |
282 | case LBRACKET: | |
283 | c = *qpatnext; | |
fbd86d4c | 284 | @@ -493,7 +545,7 @@ glob0(const Char *pattern, glob_t *pglob |
3d9156a7 A |
285 | qprintf("glob0:", patbuf); |
286 | #endif | |
287 | ||
288 | - if ((err = glob1(patbuf, pglob, limit)) != 0) | |
289 | + if ((err = glob1(patbuf, pglob, limit, loc)) != 0) | |
290 | return(err); | |
291 | ||
292 | /* | |
fbd86d4c | 293 | @@ -506,7 +558,7 @@ glob0(const Char *pattern, glob_t *pglob |
3d9156a7 A |
294 | if (((pglob->gl_flags & GLOB_NOCHECK) || |
295 | ((pglob->gl_flags & GLOB_NOMAGIC) && | |
296 | !(pglob->gl_flags & GLOB_MAGCHAR)))) | |
297 | - return(globextend(pattern, pglob, limit)); | |
298 | + return(globextend(pattern, pglob, limit, loc)); | |
299 | else | |
300 | return(GLOB_NOMATCH); | |
301 | } | |
fbd86d4c | 302 | @@ -516,14 +568,16 @@ glob0(const Char *pattern, glob_t *pglob |
b5d655f7 A |
303 | return(0); |
304 | } | |
305 | ||
306 | -static int | |
307 | +#ifndef BUILDING_VARIANT | |
308 | +__private_extern__ int | |
fbd86d4c | 309 | compare(const void *p, const void *q) |
224c7076 A |
310 | { |
311 | - return(strcmp(*(char **)p, *(char **)q)); | |
312 | + return(strcoll(*(char **)p, *(char **)q)); | |
3d9156a7 | 313 | } |
b5d655f7 | 314 | +#endif /* BUILDING_VARIANT */ |
3d9156a7 A |
315 | |
316 | static int | |
fbd86d4c A |
317 | -glob1(Char *pattern, glob_t *pglob, size_t *limit) |
318 | +glob1(Char *pattern, glob_t *pglob, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
319 | { |
320 | Char pathbuf[MAXPATHLEN]; | |
321 | ||
fbd86d4c | 322 | @@ -531,7 +585,7 @@ glob1(Char *pattern, glob_t *pglob, size |
3d9156a7 A |
323 | if (*pattern == EOS) |
324 | return(0); | |
325 | return(glob2(pathbuf, pathbuf, pathbuf + MAXPATHLEN - 1, | |
326 | - pattern, pglob, limit)); | |
327 | + pattern, pglob, limit, loc)); | |
328 | } | |
329 | ||
330 | /* | |
fbd86d4c | 331 | @@ -541,7 +595,7 @@ glob1(Char *pattern, glob_t *pglob, size |
3d9156a7 | 332 | */ |
b5d655f7 | 333 | static int |
fbd86d4c A |
334 | glob2(Char *pathbuf, Char *pathend, Char *pathend_last, Char *pattern, |
335 | - glob_t *pglob, size_t *limit) | |
336 | + glob_t *pglob, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
337 | { |
338 | struct stat sb; | |
339 | Char *p, *q; | |
fbd86d4c | 340 | @@ -554,13 +608,20 @@ glob2(Char *pathbuf, Char *pathend, Char |
3d9156a7 A |
341 | for (anymeta = 0;;) { |
342 | if (*pattern == EOS) { /* End of pattern? */ | |
343 | *pathend = EOS; | |
344 | - if (g_lstat(pathbuf, &sb, pglob)) | |
345 | + if (g_lstat(pathbuf, &sb, pglob, loc)) | |
346 | return(0); | |
347 | ||
fbd86d4c A |
348 | + if ((pglob->gl_flags & GLOB_LIMIT) && |
349 | + limit->l_stat++ >= GLOB_LIMIT_STAT) { | |
350 | + errno = 0; | |
351 | + *pathend++ = SEP; | |
352 | + *pathend = EOS; | |
353 | + return GLOB_NOSPACE; | |
354 | + } | |
3d9156a7 A |
355 | if (((pglob->gl_flags & GLOB_MARK) && |
356 | pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) | |
357 | || (S_ISLNK(sb.st_mode) && | |
358 | - (g_stat(pathbuf, &sb, pglob) == 0) && | |
359 | + (g_stat(pathbuf, &sb, pglob, loc) == 0) && | |
360 | S_ISDIR(sb.st_mode)))) { | |
361 | if (pathend + 1 > pathend_last) | |
362 | return (GLOB_ABORTED); | |
fbd86d4c | 363 | @@ -568,7 +629,7 @@ glob2(Char *pathbuf, Char *pathend, Char |
3d9156a7 A |
364 | *pathend = EOS; |
365 | } | |
366 | ++pglob->gl_matchc; | |
367 | - return(globextend(pathbuf, pglob, limit)); | |
368 | + return(globextend(pathbuf, pglob, limit, loc)); | |
369 | } | |
370 | ||
371 | /* Find end of next segment, copy tentatively to pathend. */ | |
fbd86d4c | 372 | @@ -592,7 +653,7 @@ glob2(Char *pathbuf, Char *pathend, Char |
3d9156a7 A |
373 | } |
374 | } else /* Need expansion, recurse. */ | |
375 | return(glob3(pathbuf, pathend, pathend_last, pattern, p, | |
376 | - pglob, limit)); | |
377 | + pglob, limit, loc)); | |
378 | } | |
379 | /* NOTREACHED */ | |
380 | } | |
fbd86d4c | 381 | @@ -600,7 +661,7 @@ glob2(Char *pathbuf, Char *pathend, Char |
b5d655f7 | 382 | static int |
fbd86d4c A |
383 | glob3(Char *pathbuf, Char *pathend, Char *pathend_last, |
384 | Char *pattern, Char *restpattern, | |
385 | - glob_t *pglob, size_t *limit) | |
386 | + glob_t *pglob, struct glob_limit *limit, locale_t loc) | |
3d9156a7 A |
387 | { |
388 | struct dirent *dp; | |
389 | DIR *dirp; | |
fbd86d4c | 390 | @@ -620,15 +681,22 @@ glob3(Char *pathbuf, Char *pathend, Char |
3d9156a7 A |
391 | *pathend = EOS; |
392 | errno = 0; | |
393 | ||
394 | - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { | |
395 | + if ((dirp = g_opendir(pathbuf, pglob, loc)) == NULL) { | |
396 | /* TODO: don't call for ENOENT or ENOTDIR? */ | |
397 | if (pglob->gl_errfunc) { | |
398 | - if (g_Ctoc(pathbuf, buf, sizeof(buf))) | |
399 | + if (g_Ctoc(pathbuf, buf, sizeof(buf), loc)) | |
400 | return (GLOB_ABORTED); | |
224c7076 A |
401 | - if (pglob->gl_errfunc(buf, errno) || |
402 | - pglob->gl_flags & GLOB_ERR) | |
34e8f829 A |
403 | +#ifdef __BLOCKS__ |
404 | + if (pglob->gl_flags & _GLOB_ERR_BLOCK) { | |
405 | + if (pglob->gl_errblk(buf, errno)) | |
406 | + return (GLOB_ABORTED); | |
407 | + } else | |
408 | +#endif /* __BLOCKS__ */ | |
224c7076 A |
409 | + if (pglob->gl_errfunc(buf, errno)) |
410 | return (GLOB_ABORTED); | |
411 | } | |
412 | + if (pglob->gl_flags & GLOB_ERR) | |
413 | + return (GLOB_ABORTED); | |
414 | return(0); | |
415 | } | |
416 | ||
fbd86d4c A |
417 | @@ -646,6 +714,14 @@ glob3(Char *pathbuf, Char *pathend, Char |
418 | size_t clen; | |
419 | mbstate_t mbs; | |
420 | ||
421 | + if ((pglob->gl_flags & GLOB_LIMIT) && | |
422 | + limit->l_readdir++ >= GLOB_LIMIT_READDIR) { | |
423 | + errno = 0; | |
424 | + *pathend++ = SEP; | |
425 | + *pathend = EOS; | |
426 | + return GLOB_NOSPACE; | |
427 | + } | |
428 | + | |
429 | /* Initial DOT must be matched literally. */ | |
430 | if (dp->d_name[0] == DOT && *pattern != DOT) | |
431 | continue; | |
432 | @@ -653,7 +729,7 @@ glob3(Char *pathbuf, Char *pathend, Char | |
3d9156a7 | 433 | dc = pathend; |
fbd86d4c | 434 | sc = dp->d_name; |
3d9156a7 A |
435 | while (dc < pathend_last) { |
436 | - clen = mbrtowc(&wc, sc, MB_LEN_MAX, &mbs); | |
fbd86d4c | 437 | + clen = mbrtowc_l(&wc, sc, MB_LEN_MAX, &mbs, loc); |
3d9156a7 A |
438 | if (clen == (size_t)-1 || clen == (size_t)-2) { |
439 | wc = *sc; | |
440 | clen = 1; | |
fbd86d4c | 441 | @@ -663,12 +739,12 @@ glob3(Char *pathbuf, Char *pathend, Char |
3d9156a7 A |
442 | break; |
443 | sc += clen; | |
444 | } | |
445 | - if (!match(pathend, pattern, restpattern)) { | |
446 | + if (!match(pathend, pattern, restpattern, loc)) { | |
447 | *pathend = EOS; | |
448 | continue; | |
449 | } | |
450 | err = glob2(pathbuf, --dc, pathend_last, restpattern, | |
451 | - pglob, limit); | |
452 | + pglob, limit, loc); | |
453 | if (err) | |
454 | break; | |
455 | } | |
fbd86d4c | 456 | @@ -681,6 +757,7 @@ glob3(Char *pathbuf, Char *pathend, Char |
b5d655f7 A |
457 | } |
458 | ||
459 | ||
460 | +#ifndef BUILDING_VARIANT | |
461 | /* | |
462 | * Extend the gl_pathv member of a glob_t structure to accomodate a new item, | |
463 | * add the new item, and update gl_pathc. | |
fbd86d4c | 464 | @@ -695,20 +772,18 @@ glob3(Char *pathbuf, Char *pathend, Char |
224c7076 | 465 | * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and |
3d9156a7 A |
466 | * gl_pathv points to (gl_offs + gl_pathc + 1) items. |
467 | */ | |
224c7076 | 468 | -static int |
fbd86d4c | 469 | -globextend(const Char *path, glob_t *pglob, size_t *limit) |
224c7076 | 470 | +__private_extern__ int |
fbd86d4c | 471 | +globextend(const Char *path, glob_t *pglob, struct glob_limit *limit, locale_t loc) |
3d9156a7 A |
472 | { |
473 | char **pathv; | |
fbd86d4c A |
474 | size_t i, newsize, len; |
475 | char *copy; | |
476 | const Char *p; | |
477 | ||
478 | - if (*limit && pglob->gl_pathc > *limit) { | |
479 | - errno = 0; | |
480 | - return (GLOB_NOSPACE); | |
481 | - } | |
482 | - | |
483 | newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); | |
484 | + if ((pglob->gl_flags & GLOB_LIMIT) && | |
485 | + newsize > GLOB_LIMIT_PATH * sizeof(*pathv)) | |
486 | + goto nospace; | |
487 | pathv = pglob->gl_pathv ? | |
488 | realloc((char *)pglob->gl_pathv, newsize) : | |
489 | malloc(newsize); | |
490 | @@ -730,24 +805,33 @@ globextend(const Char *path, glob_t *pgl | |
3d9156a7 A |
491 | |
492 | for (p = path; *p++;) | |
493 | continue; | |
494 | - len = MB_CUR_MAX * (size_t)(p - path); /* XXX overallocation */ | |
495 | + len = MB_CUR_MAX_L(loc) * (size_t)(p - path); /* XXX overallocation */ | |
fbd86d4c | 496 | + limit->l_string += len; |
3d9156a7 A |
497 | if ((copy = malloc(len)) != NULL) { |
498 | - if (g_Ctoc(path, copy, len)) { | |
499 | + if (g_Ctoc(path, copy, len, loc)) { | |
500 | free(copy); | |
501 | return (GLOB_NOSPACE); | |
502 | } | |
fbd86d4c A |
503 | pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; |
504 | } | |
505 | pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; | |
506 | + | |
507 | + if ((pglob->gl_flags & GLOB_LIMIT) && | |
508 | + (newsize + limit->l_string) >= GLOB_LIMIT_STRING) | |
509 | + goto nospace; | |
510 | + | |
511 | return(copy == NULL ? GLOB_NOSPACE : 0); | |
512 | +nospace: | |
513 | + errno = 0; | |
514 | + return GLOB_NOSPACE; | |
515 | } | |
516 | ||
517 | /* | |
b5d655f7 | 518 | * pattern matching function for filenames. Each occurrence of the * |
3d9156a7 A |
519 | * pattern causes a recursion level. |
520 | */ | |
b5d655f7 | 521 | -static int |
fbd86d4c | 522 | -match(Char *name, Char *pat, Char *patend) |
b5d655f7 | 523 | +__private_extern__ int |
fbd86d4c | 524 | +match(Char *name, Char *pat, Char *patend, locale_t loc) |
3d9156a7 A |
525 | { |
526 | int ok, negate_range; | |
527 | Char c, k; | |
fbd86d4c | 528 | @@ -759,7 +843,7 @@ match(Char *name, Char *pat, Char *paten |
3d9156a7 A |
529 | if (pat == patend) |
530 | return(1); | |
531 | do | |
532 | - if (match(name, pat, patend)) | |
533 | + if (match(name, pat, patend, loc)) | |
534 | return(1); | |
535 | while (*name++ != EOS); | |
536 | return(0); | |
fbd86d4c | 537 | @@ -775,10 +859,10 @@ match(Char *name, Char *pat, Char *paten |
3d9156a7 A |
538 | ++pat; |
539 | while (((c = *pat++) & M_MASK) != M_END) | |
540 | if ((*pat & M_MASK) == M_RNG) { | |
541 | - if (__collate_load_error ? | |
542 | + if (loc->__collate_load_error ? | |
543 | CHAR(c) <= CHAR(k) && CHAR(k) <= CHAR(pat[1]) : | |
544 | - __collate_range_cmp(CHAR(c), CHAR(k)) <= 0 | |
545 | - && __collate_range_cmp(CHAR(k), CHAR(pat[1])) <= 0 | |
546 | + __collate_range_cmp(CHAR(c), CHAR(k), loc) <= 0 | |
547 | + && __collate_range_cmp(CHAR(k), CHAR(pat[1]), loc) <= 0 | |
548 | ) | |
549 | ok = 1; | |
550 | pat += 2; | |
fbd86d4c | 551 | @@ -812,16 +896,17 @@ globfree(glob_t *pglob) |
b5d655f7 A |
552 | pglob->gl_pathv = NULL; |
553 | } | |
3d9156a7 | 554 | } |
b5d655f7 | 555 | +#endif /* !BUILDING_VARIANT */ |
3d9156a7 A |
556 | |
557 | static DIR * | |
fbd86d4c A |
558 | -g_opendir(Char *str, glob_t *pglob) |
559 | +g_opendir(Char *str, glob_t *pglob, locale_t loc) | |
3d9156a7 A |
560 | { |
561 | char buf[MAXPATHLEN]; | |
562 | ||
563 | if (!*str) | |
564 | strcpy(buf, "."); | |
565 | else { | |
566 | - if (g_Ctoc(str, buf, sizeof(buf))) | |
567 | + if (g_Ctoc(str, buf, sizeof(buf), loc)) | |
568 | return (NULL); | |
569 | } | |
570 | ||
fbd86d4c | 571 | @@ -832,11 +917,11 @@ g_opendir(Char *str, glob_t *pglob) |
3d9156a7 A |
572 | } |
573 | ||
574 | static int | |
fbd86d4c A |
575 | -g_lstat(Char *fn, struct stat *sb, glob_t *pglob) |
576 | +g_lstat(Char *fn, struct stat *sb, glob_t *pglob, locale_t loc) | |
3d9156a7 A |
577 | { |
578 | char buf[MAXPATHLEN]; | |
579 | ||
580 | - if (g_Ctoc(fn, buf, sizeof(buf))) { | |
581 | + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { | |
582 | errno = ENAMETOOLONG; | |
583 | return (-1); | |
584 | } | |
fbd86d4c | 585 | @@ -846,11 +931,11 @@ g_lstat(Char *fn, struct stat *sb, glob_ |
3d9156a7 A |
586 | } |
587 | ||
588 | static int | |
fbd86d4c A |
589 | -g_stat(Char *fn, struct stat *sb, glob_t *pglob) |
590 | +g_stat(Char *fn, struct stat *sb, glob_t *pglob, locale_t loc) | |
3d9156a7 A |
591 | { |
592 | char buf[MAXPATHLEN]; | |
593 | ||
594 | - if (g_Ctoc(fn, buf, sizeof(buf))) { | |
595 | + if (g_Ctoc(fn, buf, sizeof(buf), loc)) { | |
596 | errno = ENAMETOOLONG; | |
597 | return (-1); | |
598 | } | |
fbd86d4c | 599 | @@ -859,7 +944,8 @@ g_stat(Char *fn, struct stat *sb, glob_t |
224c7076 | 600 | return(stat(buf, sb)); |
3d9156a7 A |
601 | } |
602 | ||
fbd86d4c | 603 | -static const Char * |
224c7076 | 604 | +#ifndef BUILDING_VARIANT |
fbd86d4c A |
605 | +__private_extern__ const Char * |
606 | g_strchr(const Char *str, wchar_t ch) | |
607 | { | |
608 | ||
609 | @@ -870,15 +956,16 @@ g_strchr(const Char *str, wchar_t ch) | |
224c7076 A |
610 | return (NULL); |
611 | } | |
612 | ||
613 | -static int | |
fbd86d4c | 614 | -g_Ctoc(const Char *str, char *buf, size_t len) |
224c7076 | 615 | +__private_extern__ int |
fbd86d4c | 616 | +g_Ctoc(const Char *str, char *buf, size_t len, locale_t loc) |
3d9156a7 A |
617 | { |
618 | mbstate_t mbs; | |
619 | size_t clen; | |
620 | + int mb_cur_max = MB_CUR_MAX_L(loc); | |
621 | ||
622 | memset(&mbs, 0, sizeof(mbs)); | |
623 | - while (len >= MB_CUR_MAX) { | |
624 | - clen = wcrtomb(buf, *str, &mbs); | |
625 | + while (len >= mb_cur_max) { | |
626 | + clen = wcrtomb_l(buf, *str, &mbs, loc); | |
627 | if (clen == (size_t)-1) | |
628 | return (1); | |
629 | if (*str == L'\0') | |
fbd86d4c | 630 | @@ -908,3 +995,4 @@ qprintf(const char *str, Char *s) |
224c7076 A |
631 | (void)printf("\n"); |
632 | } | |
633 | #endif | |
634 | +#endif /* !BUILDING_VARIANT */ |