changeset 6125:4af02335816a

* config/srclist.txt: Add glibc bug 1245. * lib/regexec.c (set_regs): Don't alloca with an unbounded size. alloca modernization/simplification for regex. * lib/regex.c: Remove portability cruft for alloca. This no longer needs to be at the start of the file, and can be moved into regex_internal.h and simplified. * lib/regex_internal.h: Include <alloca.h>. (__libc_use_alloca) [!defined _LIBC]: New macro. * lib/regexec.c (build_trtable): Remove "#ifdef _LIBC", since the code now works outside glibc.
author Paul Eggert <eggert@cs.ucla.edu>
date Fri, 26 Aug 2005 05:58:54 +0000
parents 2e48e4301246
children 3690c96b6da9
files config/ChangeLog config/srclist.txt lib/ChangeLog lib/regex.c lib/regex_internal.h lib/regexec.c
diffstat 6 files changed, 56 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,6 +1,6 @@
 2005-08-25  Paul Eggert  <eggert@cs.ucla.edu>
 
-	* srclist.txt: Add glibc bug 1241.
+	* srclist.txt: Add glibc bugs 1241, 1245.
 
 2005-08-24  Paul Eggert  <eggert@cs.ucla.edu>
 
--- a/config/srclist.txt
+++ b/config/srclist.txt
@@ -1,4 +1,4 @@
-# $Id: srclist.txt,v 1.86 2005-08-25 20:39:57 eggert Exp $
+# $Id: srclist.txt,v 1.87 2005-08-26 05:58:54 eggert Exp $
 # Files for which we are not the source.  See ./srclistvars.sh for the
 # variable definitions.
 
@@ -105,6 +105,7 @@
 #$LIBCSRC/posix/regcomp.c		lib gpl
 #
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1238
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1245
 #$LIBCSRC/posix/regex.c			lib gpl
 #
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1201
@@ -128,6 +129,7 @@
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1221
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1237
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1241
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1245
 #$LIBCSRC/posix/regex_internal.h		lib gpl
 #
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1216
@@ -137,6 +139,7 @@
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1231
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1237
 # http://sources.redhat.com/bugzilla/show_bug.cgi?id=1241
+# http://sources.redhat.com/bugzilla/show_bug.cgi?id=1245
 #$LIBCSRC/posix/regexec.c		lib gpl
 #
 # c89 changes $LIBCSRC/string/strdup.c		lib gpl
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -1,3 +1,16 @@
+2005-08-25  Paul Eggert  <eggert@cs.ucla.edu>
+
+	* regexec.c (set_regs): Don't alloca with an unbounded size.
+
+	alloca modernization/simplification for regex.
+	* regex.c: Remove portability cruft for alloca.  This no longer
+	needs to be at the start of the file, and can be moved into
+	regex_internal.h and simplified.
+	* regex_internal.h: Include <alloca.h>.
+	(__libc_use_alloca) [!defined _LIBC]: New macro.
+	* regexec.c (build_trtable): Remove "#ifdef _LIBC", since the code
+	now works outside glibc.
+
 2005-08-24  Simon Josefsson  <jas@extundo.com>
 
 	* getpass.c: Add WIN32 implementation.  Conditionalize use of
--- a/lib/regex.c
+++ b/lib/regex.c
@@ -21,30 +21,6 @@
 #include "config.h"
 #endif
 
-#ifdef _AIX
-#pragma alloca
-#else
-# ifndef allocax           /* predefined by HP cc +Olibcalls */
-#  ifdef __GNUC__
-#   define alloca(size) __builtin_alloca (size)
-#  else
-#   if HAVE_ALLOCA_H
-#    include <alloca.h>
-#   else
-#    ifdef __hpux
-        void *alloca ();
-#    else
-#     if !defined __OS2__ && !defined WIN32
-        char *alloca ();
-#     else
-#      include <malloc.h>       /* OS/2 defines alloca in here */
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-#endif
-
 #ifdef _LIBC
 /* We have to keep the namespace clean.  */
 # define regfree(preg) __regfree (preg)
--- a/lib/regex_internal.h
+++ b/lib/regex_internal.h
@@ -431,6 +431,21 @@
 #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
 #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
 
+#include <alloca.h>
+
+#ifndef __LIBC
+# if HAVE_ALLOCA
+/* The OS usually guarantees only one guard page at the bottom of the stack,
+   and a page size can be as small as 4096 bytes.  So we cannot safely
+   allocate anything larger than 4096 bytes.  Also care for the possibility
+   of a few compiler-allocated temporary stack slots.  */
+#  define __libc_use_alloca(n) ((n) < 4032)
+# else
+/* alloca is implemented with malloc, so just use malloc.  */
+#  define __libc_use_alloca(n) 0
+# endif
+#endif
+
 #define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
 #define re_calloc(t,n) ((t *) calloc (n, sizeof (t)))
 #define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
--- a/lib/regexec.c
+++ b/lib/regexec.c
@@ -1354,6 +1354,7 @@
   struct re_fail_stack_t *fs;
   struct re_fail_stack_t fs_body = { 0, 2, NULL };
   regmatch_t *prev_idx_match;
+  int prev_idx_match_malloced = 0;
 
 #ifdef DEBUG
   assert (nmatch > 1);
@@ -1372,7 +1373,18 @@
   cur_node = dfa->init_node;
   re_node_set_init_empty (&eps_via_nodes);
 
-  prev_idx_match = (regmatch_t *) alloca (sizeof (regmatch_t) * nmatch);
+  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
+    prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
+  else
+    {
+      prev_idx_match = re_malloc (regmatch_t, nmatch);
+      if (prev_idx_match == NULL)
+	{
+	  free_fail_stack_return (fs);
+	  return REG_ESPACE;
+	}
+      prev_idx_match_malloced = 1;
+    }
   memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
 
   for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
@@ -1390,6 +1402,8 @@
 	      if (reg_idx == nmatch)
 		{
 		  re_node_set_free (&eps_via_nodes);
+		  if (prev_idx_match_malloced)
+		    re_free (prev_idx_match);
 		  return free_fail_stack_return (fs);
 		}
 	      cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
@@ -1398,6 +1412,8 @@
 	  else
 	    {
 	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
 	      return REG_NOERROR;
 	    }
 	}
@@ -1411,6 +1427,8 @@
 	  if (BE (cur_node == -2, 0))
 	    {
 	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
 	      free_fail_stack_return (fs);
 	      return REG_ESPACE;
 	    }
@@ -1420,11 +1438,15 @@
 	  else
 	    {
 	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
 	      return REG_NOMATCH;
 	    }
 	}
     }
   re_node_set_free (&eps_via_nodes);
+  if (prev_idx_match_malloced)
+    re_free (prev_idx_match);
   return free_fail_stack_return (fs);
 }
 
@@ -3235,12 +3257,10 @@
      from `state'.  `dests_node[i]' represents the nodes which i-th
      destination state contains, and `dests_ch[i]' represents the
      characters which i-th destination state accepts.  */
-#ifdef _LIBC
   if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))
     dests_node = (re_node_set *)
       alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
   else
-#endif
     {
       dests_node = (re_node_set *)
 	malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
@@ -3273,13 +3293,11 @@
   if (BE (err != REG_NOERROR, 0))
     goto out_free;
 
-#ifdef _LIBC
   if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
 			 + ndests * 3 * sizeof (re_dfastate_t *)))
     dest_states = (re_dfastate_t **)
       alloca (ndests * 3 * sizeof (re_dfastate_t *));
   else
-#endif
     {
       dest_states = (re_dfastate_t **)
 	malloc (ndests * 3 * sizeof (re_dfastate_t *));