*** lib/fnmatch_loop.c.bak 2006-07-11 13:54:17.000000000 +0200 --- lib/fnmatch_loop.c 2006-07-30 21:03:04.000000000 +0200 *************** *** 1003,1022 **** struct patternlist { struct patternlist *next; CHAR str[1]; } *list = NULL; struct patternlist **lastp = &list; size_t pattern_len = STRLEN (pattern); const CHAR *p; const CHAR *rs; enum { ALLOCA_LIMIT = 8000 }; /* Parse the pattern. Store the individual parts in the list. */ level = 0; for (startp = p = pattern + 1; ; ++p) if (*p == L_('\0')) /* This is an invalid pattern. */ ! return -1; else if (*p == L_('[')) { /* Handle brackets special. */ --- 1003,1028 ---- struct patternlist { struct patternlist *next; + int malloced; CHAR str[1]; } *list = NULL; struct patternlist **lastp = &list; size_t pattern_len = STRLEN (pattern); const CHAR *p; const CHAR *rs; + #if HAVE_ALLOCA || defined _LIBC enum { ALLOCA_LIMIT = 8000 }; + #else + enum { ALLOCA_LIMIT = 0 }; + #endif + int retval; /* Parse the pattern. Store the individual parts in the list. */ level = 0; for (startp = p = pattern + 1; ; ++p) if (*p == L_('\0')) /* This is an invalid pattern. */ ! goto failed; else if (*p == L_('[')) { /* Handle brackets special. */ *************** *** 1034,1040 **** while (*p != L_(']')) if (*p++ == L_('\0')) /* This is no valid pattern. */ ! return -1; } else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') || *p == L_('!')) && p[1] == L_('(')) --- 1040,1046 ---- while (*p != L_(']')) if (*p++ == L_('\0')) /* This is no valid pattern. */ ! goto failed; } else if ((*p == L_('?') || *p == L_('*') || *p == L_('+') || *p == L_('@') || *p == L_('!')) && p[1] == L_('(')) *************** *** 1057,1067 **** plensize = plen * sizeof (CHAR); \ newpsize = offsetof (struct patternlist, str) + plensize; \ if ((size_t) -1 / sizeof (CHAR) < plen \ ! || newpsize < offsetof (struct patternlist, str) \ ! || ALLOCA_LIMIT <= newpsize) \ ! return -1; \ ! newp = (struct patternlist *) alloca (newpsize); \ ! *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ newp->next = NULL; \ *lastp = newp; \ lastp = &newp->next --- 1063,1083 ---- plensize = plen * sizeof (CHAR); \ newpsize = offsetof (struct patternlist, str) + plensize; \ if ((size_t) -1 / sizeof (CHAR) < plen \ ! || newpsize < offsetof (struct patternlist, str)) \ ! goto failed; \ ! if (newpsize < ALLOCA_LIMIT) \ ! { \ ! newp = (struct patternlist *) alloca (newpsize); \ ! newp->malloced = 0; \ ! } \ ! else \ ! { \ ! newp = (struct patternlist *) malloc (newpsize); \ ! if (!newp) \ ! goto failed; \ ! newp->malloced = 1; \ ! } \ ! *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L_('\0'); \ newp->next = NULL; \ *lastp = newp; \ lastp = &newp->next *************** *** 1085,1096 **** { case L_('*'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) ! return 0; /* FALLTHROUGH */ case L_('+'): do { for (rs = string; rs <= string_end; ++rs) /* First match the prefix with the current pattern with the current pattern. */ --- 1101,1117 ---- { case L_('*'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) ! { ! retval = 0; ! goto done; ! } /* FALLTHROUGH */ case L_('+'): do { + struct patternlist *next; + for (rs = string; rs <= string_end; ++rs) /* First match the prefix with the current pattern with the current pattern. */ *************** *** 1112,1142 **** : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0))) ! /* It worked. Signal success. */ ! return 0; } ! while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ return FNM_NOMATCH; case L_('?'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) ! return 0; /* FALLTHROUGH */ case L_('@'): do ! /* I cannot believe it but `strcat' is actually acceptable ! here. Match the entire string with the prefix from the ! pattern list and the rest of the pattern following the ! pattern list. */ ! if (FCT (STRCAT (list->str, p), string, string_end, ! no_leading_period, ! flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) ! /* It worked. Signal success. */ ! return 0; ! while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ return FNM_NOMATCH; --- 1133,1186 ---- : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0))) ! { ! /* It worked. Signal success. */ ! retval = 0; ! goto done; ! } ! ! next = list->next; ! if (list->malloced) ! free (list); ! list = next; } ! while (list != NULL); /* None of the patterns lead to a match. */ return FNM_NOMATCH; case L_('?'): if (FCT (p, string, string_end, no_leading_period, flags) == 0) ! { ! retval = 0; ! goto done; ! } /* FALLTHROUGH */ case L_('@'): do ! { ! struct patternlist *next; ! ! /* I cannot believe it but `strcat' is actually acceptable ! here. Match the entire string with the prefix from the ! pattern list and the rest of the pattern following the ! pattern list. */ ! if (FCT (STRCAT (list->str, p), string, string_end, ! no_leading_period, ! flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0) ! { ! /* It worked. Signal success. */ ! retval = 0; ! goto done; ! } ! ! next = list->next; ! if (list->malloced) ! free (list); ! list = next; ! } ! while (list != NULL); /* None of the patterns lead to a match. */ return FNM_NOMATCH; *************** *** 1159,1178 **** : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)) ! /* This is successful. */ ! return 0; } /* None of the patterns together with the rest of the pattern lead to a match. */ ! return FNM_NOMATCH; default: assert (! "Invalid extended matching operator"); break; } ! return -1; } --- 1203,1237 ---- : rs[-1] == '/' && NO_LEADING_PERIOD (flags), flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD) == 0)) ! { ! /* This is successful. */ ! retval = 0; ! goto done; ! } } /* None of the patterns together with the rest of the pattern lead to a match. */ ! retval = FNM_NOMATCH; ! goto done; default: assert (! "Invalid extended matching operator"); break; } ! failed: ! retval = -1; ! done: ! while (list != NULL) ! { ! struct patternlist *next = list->next; ! ! if (list->malloced) ! free (list); ! list = next; ! } ! return retval; }