2003-12-29  Jakub Jelinek  <jakub@redhat.com>

	* 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.
This commit is contained in:
Ulrich Drepper 2003-12-29 17:59:41 +00:00
parent a96c63edd2
commit 447777715a
6 changed files with 133 additions and 28 deletions

View File

@ -1,3 +1,20 @@
2003-12-29 Jakub Jelinek <jakub@redhat.com>
* 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 <drepper@redhat.com> 2003-12-28 Ulrich Drepper <drepper@redhat.com>
* posix/regcomp.c (mark_opt_subexp_iter): Declare IDX as int. * posix/regcomp.c (mark_opt_subexp_iter): Declare IDX as int.

View File

@ -22,6 +22,7 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
# include <dl-sysdep.h>
# include <pt-machine.h> # include <pt-machine.h>
# include <stddef.h> # include <stddef.h>
@ -80,11 +81,18 @@ typedef struct
# define GET_DTV(tcbp) \ # define GET_DTV(tcbp) \
(((tcbhead_t *) (tcbp))->dtv) (((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 /* Code to initially initialize the thread pointer. This might need
special attention since 'errno' is not yet available and if the special attention since 'errno' is not yet available and if the
operation can cause a failure 'errno' must not be touched. */ operation can cause a failure 'errno' must not be touched. */
# define TLS_INIT_TP(tcbp, secondcall) \ # 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. */ /* Return the address of the dtv for the current thread. */
# define THREAD_DTV() \ # define THREAD_DTV() \

View File

@ -1,7 +1,27 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 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 <errno.h> #include <errno.h>
#include <error.h> #include <error.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
volatile int count; volatile int count;

View File

@ -453,8 +453,7 @@ re_copy_regs (regs, pmatch, nregs, regs_allocated)
/* Have the register data arrays been allocated? */ /* Have the register data arrays been allocated? */
if (regs_allocated == REGS_UNALLOCATED) if (regs_allocated == REGS_UNALLOCATED)
{ /* No. So allocate them with malloc. We allocate the arrays { /* No. So allocate them with malloc. */
for the start and end in one block. */
regs->start = re_malloc (regoff_t, need_regs); regs->start = re_malloc (regoff_t, need_regs);
regs->end = 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)) 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. */ leave it alone. */
if (BE (need_regs > regs->num_regs, 0)) if (BE (need_regs > regs->num_regs, 0))
{ {
regs->start = re_realloc (regs->start, regoff_t, need_regs); regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
regs->end = re_realloc (regs->end, regoff_t, need_regs); regoff_t *new_end = re_realloc (regs->end, regoff_t, need_regs);
if (BE (regs->start == NULL, 0) || BE (regs->end == NULL, 0)) if (BE (new_start == NULL, 0) || BE (new_end == NULL, 0))
return REGS_UNALLOCATED; return REGS_UNALLOCATED;
regs->start = new_start;
regs->end = new_end;
regs->num_regs = need_regs; 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]; int ndest, dest_nodes[2];
err = re_node_set_insert (eps_via_nodes, node); err = re_node_set_insert (eps_via_nodes, node);
if (BE (err < 0, 0)) if (BE (err < 0, 0))
return -1; return -2;
/* Pick up valid destinations. */ /* Pick up valid destinations. */
for (ndest = 0, i = 0; i < dfa->edests[node].nelem; ++i) 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*)*". */ /* In order to avoid infinite loop like "(a*)*". */
if (re_node_set_contains (eps_via_nodes, dest_nodes[0])) if (re_node_set_contains (eps_via_nodes, dest_nodes[0]))
return dest_nodes[1]; return dest_nodes[1];
if (fs != NULL) if (fs != NULL
push_fail_stack (fs, *pidx, dest_nodes, nregs, regs, eps_via_nodes); && push_fail_stack (fs, *pidx, dest_nodes, nregs, regs,
eps_via_nodes))
return -2;
return dest_nodes[0]; return dest_nodes[0];
} }
else else
@ -1220,11 +1223,11 @@ push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes)
if (fs->num == fs->alloc) if (fs->num == fs->alloc)
{ {
struct re_fail_stack_ent_t *new_array; struct re_fail_stack_ent_t *new_array;
fs->alloc *= 2;
new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
* fs->alloc)); * fs->alloc * 2));
if (new_array == NULL) if (new_array == NULL)
return REG_ESPACE; return REG_ESPACE;
fs->alloc *= 2;
fs->stack = new_array; fs->stack = new_array;
} }
fs->stack[num].idx = str_idx; fs->stack[num].idx = str_idx;
@ -1246,7 +1249,7 @@ pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)
{ {
int num = --fs->num; int num = --fs->num;
assert (num >= 0); assert (num >= 0);
*pidx = fs->stack[num].idx; *pidx = fs->stack[num].idx;
memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
re_node_set_free (eps_via_nodes); re_node_set_free (eps_via_nodes);
re_free (fs->stack[num].regs); 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 (BE (cur_node < 0, 0))
{ {
if (cur_node == -2) if (BE (cur_node == -2, 0))
return REG_ESPACE; {
re_node_set_free (&eps_via_nodes);
free_fail_stack_return (fs);
return REG_ESPACE;
}
if (fs) if (fs)
cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
&eps_via_nodes); &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); re_node_set_free (&union_set);
return err; 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); re_node_set_free (&union_set);
if (BE (err < 0, 0)) return REG_ESPACE;
{
re_node_set_free (&union_set);
return REG_ESPACE;
}
} }
mctx->state_log[next_idx] = re_acquire_state (&err, dfa, mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
&union_set); &union_set);

View File

@ -38,7 +38,7 @@ routines := signal raise killpg \
allocrtsig sigtimedwait sigwaitinfo sigqueue \ allocrtsig sigtimedwait sigwaitinfo sigqueue \
sighold sigrelse sigignore sigset 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 distribute := sigsetops.h testrtsig.h sigset-cvt-mask.h

62
signal/tst-raise.c Normal file
View File

@ -0,0 +1,62 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 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 <errno.h>
#include <error.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
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);
}