From 447777715a7d19266686b09f4eb1e71238d9568a Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 29 Dec 2003 17:59:41 +0000 Subject: [PATCH] Update. 2003-12-29 Jakub Jelinek * posix/regexec.c (re_copy_regs): Revert comment change. Avoid memory leak if realloc fails. (proceed_next_node): Return -2 if re_node_set_insert fails. Return -2 if push_fail_stack fails. (push_fail_stack): Change fs->alloc only after successful realloc. (pop_fail_stack): Formatting. (set_regs): If proceed_next_node returns -2, free eps_via_nodes and fs. (check_arrival_add_next_nodes): Merge identical statements from if branches. * signal/Makefile (tests): Add tst-raise. * signal/tst-raise.c: New test. --- ChangeLog | 17 +++++++++ linuxthreads/sysdeps/ia64/tls.h | 10 +++++- nptl/tst-raise1.c | 20 +++++++++++ posix/regexec.c | 50 +++++++++++++------------- signal/Makefile | 2 +- signal/tst-raise.c | 62 +++++++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 28 deletions(-) create mode 100644 signal/tst-raise.c diff --git a/ChangeLog b/ChangeLog index bfa5d7aea1..aa3b4cbbdc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2003-12-29 Jakub Jelinek + + * posix/regexec.c (re_copy_regs): Revert comment change. + Avoid memory leak if realloc fails. + (proceed_next_node): Return -2 if re_node_set_insert fails. + Return -2 if push_fail_stack fails. + (push_fail_stack): Change fs->alloc only after successful + realloc. + (pop_fail_stack): Formatting. + (set_regs): If proceed_next_node returns -2, free eps_via_nodes + and fs. + (check_arrival_add_next_nodes): Merge identical statements + from if branches. + + * signal/Makefile (tests): Add tst-raise. + * signal/tst-raise.c: New test. + 2003-12-28 Ulrich Drepper * posix/regcomp.c (mark_opt_subexp_iter): Declare IDX as int. diff --git a/linuxthreads/sysdeps/ia64/tls.h b/linuxthreads/sysdeps/ia64/tls.h index db810d1872..49ca977c1c 100644 --- a/linuxthreads/sysdeps/ia64/tls.h +++ b/linuxthreads/sysdeps/ia64/tls.h @@ -22,6 +22,7 @@ #ifndef __ASSEMBLER__ +# include # include # include @@ -80,11 +81,18 @@ typedef struct # define GET_DTV(tcbp) \ (((tcbhead_t *) (tcbp))->dtv) +#if defined NEED_DL_SYSINFO +# define INIT_SYSINFO \ + (((tcbhead_t *)__thread_self)->private = GL(dl_sysinfo)) +#else +# define INIT_SYSINFO 0 +#endif + /* Code to initially initialize the thread pointer. This might need special attention since 'errno' is not yet available and if the operation can cause a failure 'errno' must not be touched. */ # define TLS_INIT_TP(tcbp, secondcall) \ - (__thread_self = (__typeof (__thread_self)) (tcbp), NULL) + (__thread_self = (__typeof (__thread_self)) (tcbp), INIT_SYSINFO, NULL) /* Return the address of the dtv for the current thread. */ # define THREAD_DTV() \ diff --git a/nptl/tst-raise1.c b/nptl/tst-raise1.c index 9c291e6c1f..5ea9886a47 100644 --- a/nptl/tst-raise1.c +++ b/nptl/tst-raise1.c @@ -1,7 +1,27 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + #include #include #include #include +#include volatile int count; diff --git a/posix/regexec.c b/posix/regexec.c index 9d1af80c0d..afaf1bb7b7 100644 --- a/posix/regexec.c +++ b/posix/regexec.c @@ -453,8 +453,7 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated) /* Have the register data arrays been allocated? */ if (regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. We allocate the arrays - for the start and end in one block. */ + { /* No. So allocate them with malloc. */ regs->start = re_malloc (regoff_t, need_regs); regs->end = re_malloc (regoff_t, need_regs); if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0)) @@ -467,10 +466,12 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated) leave it alone. */ if (BE (need_regs > regs->num_regs, 0)) { - regs->start = re_realloc (regs->start, regoff_t, need_regs); - regs->end = re_realloc (regs->end, regoff_t, need_regs); - if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0)) + regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); + regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs); + if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0)) return REGS_UNALLOCATED; + regs->start = new_start; + regs->end = new_end; regs->num_regs = need_regs; } } @@ -1133,7 +1134,7 @@ proceed_next_node (preg, nregs, regs, mctx, pidx, node, eps_via_nodes, fs) int ndest, dest_nodes[2]; err = re_node_set_insert (eps_via_nodes, node); if (BE (err < 0, 0)) - return -1; + return -2; /* Pick up valid destinations. */ for (ndest = 0, i = 0; i < dfa->edests[node].nelem; ++i) { @@ -1149,8 +1150,10 @@ proceed_next_node (preg, nregs, regs, mctx, pidx, node, eps_via_nodes, fs) /* In order to avoid infinite loop like "(a*)*". */ if (re_node_set_contains (eps_via_nodes, dest_nodes[0])) return dest_nodes[1]; - if (fs != NULL) - push_fail_stack (fs, *pidx, dest_nodes, nregs, regs, eps_via_nodes); + if (fs != NULL + && push_fail_stack (fs, *pidx, dest_nodes, nregs, regs, + eps_via_nodes)) + return -2; return dest_nodes[0]; } else @@ -1220,11 +1223,11 @@ push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes) if (fs->num == fs->alloc) { struct re_fail_stack_ent_t *new_array; - fs->alloc *= 2; new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) - * fs->alloc)); + * fs->alloc * 2)); if (new_array == NULL) return REG_ESPACE; + fs->alloc *= 2; fs->stack = new_array; } fs->stack[num].idx = str_idx; @@ -1246,7 +1249,7 @@ pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes) { int num = --fs->num; assert (num >= 0); - *pidx = fs->stack[num].idx; + *pidx = fs->stack[num].idx; memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); re_node_set_free (eps_via_nodes); re_free (fs->stack[num].regs); @@ -1328,8 +1331,12 @@ set_regs (preg, mctx, nmatch, pmatch, fl_backtrack) if (BE (cur_node < 0, 0)) { - if (cur_node == -2) - return REG_ESPACE; + if (BE (cur_node == -2, 0)) + { + re_node_set_free (&eps_via_nodes); + free_fail_stack_return (fs); + return REG_ESPACE; + } if (fs) cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, &eps_via_nodes); @@ -2911,21 +2918,12 @@ check_arrival_add_next_nodes (preg, dfa, mctx, str_idx, cur_nodes, next_nodes) re_node_set_free (&union_set); return err; } - err = re_node_set_insert (&union_set, next_node); - if (BE (err < 0, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } } - else + err = re_node_set_insert (&union_set, next_node); + if (BE (err < 0, 0)) { - err = re_node_set_insert (&union_set, next_node); - if (BE (err < 0, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } + re_node_set_free (&union_set); + return REG_ESPACE; } mctx->state_log[next_idx] = re_acquire_state (&err, dfa, &union_set); diff --git a/signal/Makefile b/signal/Makefile index b616d62599..b5c18fef04 100644 --- a/signal/Makefile +++ b/signal/Makefile @@ -38,7 +38,7 @@ routines := signal raise killpg \ allocrtsig sigtimedwait sigwaitinfo sigqueue \ sighold sigrelse sigignore sigset -tests := tst-signal tst-sigset tst-sigsimple +tests := tst-signal tst-sigset tst-sigsimple tst-raise distribute := sigsetops.h testrtsig.h sigset-cvt-mask.h diff --git a/signal/tst-raise.c b/signal/tst-raise.c new file mode 100644 index 0000000000..5ea9886a47 --- /dev/null +++ b/signal/tst-raise.c @@ -0,0 +1,62 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2003. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include + +volatile int count; + +void +sh (int sig) +{ + ++count; +} + +int +main (void) +{ + struct sigaction sa; + sa.sa_handler = sh; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction (SIGUSR1, &sa, NULL) < 0) + { + printf ("sigaction failed: %m\n"); + exit (1); + } + if (raise (SIGUSR1) < 0) + { + printf ("first raise failed: %m\n"); + exit (1); + } + if (raise (SIGUSR1) < 0) + { + printf ("second raise failed: %m\n"); + exit (1); + } + if (count != 2) + { + printf ("signal handler not called 2 times\n"); + exit (1); + } + exit (0); +}