summary refs log tree commit diff
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2016-03-12 10:09:31 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2016-03-21 15:46:59 -0700
commitef6f1eb1c5551acb7bb766eb76fab13e8a2e3dd3 (patch)
treeb4824f219ebe04bfc60e0112c541c09a7b38c44a
parentb81b275ab30b06867a6ab13f774e90f0955dad88 (diff)
downloadzsh-ef6f1eb1c5551acb7bb766eb76fab13e8a2e3dd3.tar.gz
zsh-ef6f1eb1c5551acb7bb766eb76fab13e8a2e3dd3.tar.xz
zsh-ef6f1eb1c5551acb7bb766eb76fab13e8a2e3dd3.zip
38142: signal re-entrancy, maybe
-rw-r--r--ChangeLog4
-rw-r--r--Src/pattern.c24
2 files changed, 23 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index d8f5cb50a..f4abbefaa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -49,6 +49,10 @@
 	* 38148: Completion/Unix/Command/_git: reflog: complete
 	references next to commands
 
+2016-03-12  Barton E. Schaefer  <schaefer@zsh.org>
+
+	* 38142: Src/pattern.c: signal re-entrancy, maybe
+
 2016-03-11  Daniel Shahaf  <d.s@daniel.shahaf.name>
 
 	* 38135: Src/Zle/complete.c: internal: bin_compadd: Add a
diff --git a/Src/pattern.c b/Src/pattern.c
index 72c7d97d5..fa9fefb79 100644
--- a/Src/pattern.c
+++ b/Src/pattern.c
@@ -537,9 +537,14 @@ patcompile(char *exp, int inflags, char **endexp)
     Upat pscan;
     char *lng, *strp = NULL;
     Patprog p;
+    int savpatflags, savpatglobflags;
 
     queue_signals();
 
+    /* In case called from a signal handler before queuing */
+    savpatflags = patflags;
+    savpatglobflags = patglobflags;
+
     startoff = sizeof(struct patprog);
     /* Ensure alignment of start of program string */
     startoff = (startoff + sizeof(union upat) - 1) & ~(sizeof(union upat) - 1);
@@ -603,6 +608,8 @@ patcompile(char *exp, int inflags, char **endexp)
 	    /* No, do normal compilation. */
 	    strp = NULL;
 	    if (patcompswitch(0, &flags) == 0) {
+		patflags = savpatflags;
+		patglobflags = savpatglobflags;
 		unqueue_signals();
 		return NULL;
 	    }
@@ -738,6 +745,8 @@ patcompile(char *exp, int inflags, char **endexp)
     if (endexp)
 	*endexp = patparse;
 
+    patflags = savpatflags;
+    patglobflags = savpatglobflags;
     unqueue_signals();
     return p;
 }
@@ -2259,6 +2268,9 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
     char *progstr = (char *)prog + prog->startoff;
     struct patstralloc patstralloc_struct;
 
+    /* In case called from a signal handler */
+    int savpatflags = patflags, savpatglobflags = patglobflags;
+
     if (nump) {
 	maxnpos = *nump;
 	*nump = 0;
@@ -2302,7 +2314,7 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	 * Either we are testing against a pure string,
 	 * or we can match anything at all.
 	 */
-	int ret, pstrlen;
+	int pstrlen;
 	char *pstr;
 	if (patstralloc->alloced)
 	{
@@ -2404,8 +2416,6 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 		}
 	    }
 	}
-
-	return ret;
     } else {
 	int q = queue_signal_level();
 
@@ -2441,6 +2451,8 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    }
 	}
 	if (!ret) {
+	    patflags = savpatflags;
+	    patglobflags = savpatglobflags;
 	    return 0;
 	}
 
@@ -2596,9 +2608,11 @@ pattryrefs(Patprog prog, char *string, int stringlen, int unmetalenin,
 	    ret = 0;
 
 	restore_queue_signals(q);
-
-	return ret;
     }
+
+    patflags = savpatflags;
+    patglobflags = savpatglobflags;
+    return ret;
 }
 
 /*