From f58f44a2f9c2e9b8fc9ea2ca910bd070d1f8bd48 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 26 Aug 2005 05:58:54 +0000 Subject: [PATCH] * 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 . (__libc_use_alloca) [!defined _LIBC]: New macro. * lib/regexec.c (build_trtable): Remove "#ifdef _LIBC", since the code now works outside glibc. --- config/ChangeLog | 2 +- config/srclist.txt | 5 ++++- lib/ChangeLog | 13 +++++++++++++ lib/regex.c | 24 ------------------------ lib/regex_internal.h | 15 +++++++++++++++ lib/regexec.c | 28 +++++++++++++++++++++++----- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/config/ChangeLog b/config/ChangeLog index 0a7e37930..0c8cb68b9 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,6 +1,6 @@ 2005-08-25 Paul Eggert - * srclist.txt: Add glibc bug 1241. + * srclist.txt: Add glibc bugs 1241, 1245. 2005-08-24 Paul Eggert diff --git a/config/srclist.txt b/config/srclist.txt index 8cf6e7806..c6ddaf8a9 100644 --- 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/stdlib/getsubopt.c lib gpl #$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 @@ $LIBCSRC/stdlib/getsubopt.c lib gpl # 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 @@ $LIBCSRC/stdlib/getsubopt.c lib gpl # 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 diff --git a/lib/ChangeLog b/lib/ChangeLog index 527a593b8..9a97443ea 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,16 @@ +2005-08-25 Paul Eggert + + * 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 . + (__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 * getpass.c: Add WIN32 implementation. Conditionalize use of diff --git a/lib/regex.c b/lib/regex.c index 0877dba26..1bfdd6b9c 100644 --- 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 -# else -# ifdef __hpux - void *alloca (); -# else -# if !defined __OS2__ && !defined WIN32 - char *alloca (); -# else -# include /* 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) diff --git a/lib/regex_internal.h b/lib/regex_internal.h index eaf4e67a7..edb5f8f59 100644 --- a/lib/regex_internal.h +++ b/lib/regex_internal.h @@ -431,6 +431,21 @@ static unsigned char re_string_fetch_byte_case (re_string_t *pstr) #define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) #define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) +#include + +#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))) diff --git a/lib/regexec.c b/lib/regexec.c index 9c738fc14..827b676df 100644 --- a/lib/regexec.c +++ b/lib/regexec.c @@ -1354,6 +1354,7 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, 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 @@ build_trtable (re_dfa_t *dfa, re_dfastate_t *state) 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 @@ build_trtable (re_dfa_t *dfa, re_dfastate_t *state) 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 *)); -- 2.11.0