summaryrefslogtreecommitdiff
path: root/Src/signals.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2004-03-25 10:07:12 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2004-03-25 10:07:12 +0000
commit83b0fd36740bd78d6058be58115ff688796a922a (patch)
tree38c3265238a2d0c8d87998d4442f981c78a4f31f /Src/signals.c
parent8de7436fc07454e2f5307c00ad99ee19d0baf853 (diff)
downloadzsh-83b0fd36740bd78d6058be58115ff688796a922a.tar.gz
zsh-83b0fd36740bd78d6058be58115ff688796a922a.zip
19682: Don't run ZERR, DEBUG or EXIT traps inside other traps.
Diffstat (limited to 'Src/signals.c')
-rw-r--r--Src/signals.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/Src/signals.c b/Src/signals.c
index affb5379b..dbecdf20c 100644
--- a/Src/signals.c
+++ b/Src/signals.c
@@ -932,7 +932,10 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
int trapret = 0;
int obreaks = breaks;
int isfunc;
-
+
+ /* Are we already executing a trap? */
+ static int intrap;
+
/* if signal is being ignored or the trap function *
* is NULL, then return *
* *
@@ -946,6 +949,24 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
if ((*sigtr & ZSIG_IGNORED) || !sigfn || errflag)
return;
+ /*
+ * Never execute special (synchronous) traps inside other traps.
+ * This can cause unexpected code execution when more than one
+ * of these is set.
+ *
+ * The down side is that it's harder to debug traps. I don't think
+ * that's a big issue.
+ */
+ if (intrap) {
+ switch (sig) {
+ case SIGEXIT:
+ case SIGDEBUG:
+ case SIGZERR:
+ return;
+ }
+ }
+
+ intrap++;
*sigtr |= ZSIG_IGNORED;
lexsave();
@@ -1023,6 +1044,7 @@ dotrapargs(int sig, int *sigtr, void *sigfn)
if (*sigtr != ZSIG_IGNORED)
*sigtr &= ~ZSIG_IGNORED;
+ intrap--;
}
/* Standard call to execute a trap for a given signal. */