*** lib/fnmatch_loop.c.bak	2009-12-10 20:38:55.000000000 +0100
--- lib/fnmatch_loop.c	2009-12-11 11:55:04.000000000 +0100
***************
*** 1021,1040 ****
    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.  */
--- 1021,1046 ----
    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.  */
***************
*** 1052,1058 ****
          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_('('))
--- 1058,1064 ----
          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_('('))
***************
*** 1075,1085 ****
              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
--- 1081,1101 ----
              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
***************
*** 1103,1114 ****
      {
      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.  */
--- 1119,1135 ----
      {
      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.  */
***************
*** 1130,1160 ****
                                  : 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;
--- 1151,1204 ----
                                  : 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;
***************
*** 1177,1196 ****
                         : 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;
  }
  
  
--- 1221,1255 ----
                         : 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;
  }
  
  
