summaryrefslogtreecommitdiff
path: root/Src/Zle
diff options
context:
space:
mode:
authorBarton E. Schaefer <schaefer@zsh.org>2017-01-29 08:30:14 -0800
committerBarton E. Schaefer <schaefer@zsh.org>2017-01-29 08:30:14 -0800
commite51c9c17af51e4055efb5a2cc36739d1d7ae457f (patch)
treeb77de131860f9f0d48ed0604d095a82c59665a1a /Src/Zle
parent0672c753596bd454e7456fe660eab1b8bf2879d1 (diff)
downloadzsh-e51c9c17af51e4055efb5a2cc36739d1d7ae457f.tar.gz
zsh-e51c9c17af51e4055efb5a2cc36739d1d7ae457f.zip
40453: signal handler safety for callers of patcompile(PAT_STATIC), which is not re-entrant.
Diffstat (limited to 'Src/Zle')
-rw-r--r--Src/Zle/compctl.c32
-rw-r--r--Src/Zle/complete.c10
-rw-r--r--Src/Zle/computil.c8
-rw-r--r--Src/Zle/zle_hist.c10
4 files changed, 49 insertions, 11 deletions
diff --git a/Src/Zle/compctl.c b/Src/Zle/compctl.c
index 52c6f1233..9e6ccb404 100644
--- a/Src/Zle/compctl.c
+++ b/Src/Zle/compctl.c
@@ -99,7 +99,7 @@ freecompctlp(HashNode hn)
}
/**/
-void
+static void
freecompctl(Compctl cc)
{
if (cc == &cc_default ||
@@ -142,7 +142,7 @@ freecompctl(Compctl cc)
}
/**/
-void
+static void
freecompcond(void *a)
{
Compcond cc = (Compcond) a;
@@ -186,7 +186,7 @@ freecompcond(void *a)
}
/**/
-int
+static int
compctlread(char *name, char **args, Options ops, char *reply)
{
char *buf, *bptr;
@@ -1564,6 +1564,8 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
Compctl cc = NULL;
int ret = 0;
+ queue_signals();
+
/* clear static flags */
cclist = 0;
showmask = 0;
@@ -1571,12 +1573,15 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
/* Parse all the arguments */
if (*argv) {
/* Let's see if this is a global matcher definition. */
- if ((ret = get_gmatcher(name, argv)))
+ if ((ret = get_gmatcher(name, argv))) {
+ unqueue_signals();
return ret - 1;
+ }
cc = (Compctl) zshcalloc(sizeof(*cc));
if (get_compctl(name, &argv, cc, 1, 0, 0)) {
freecompctl(cc);
+ unqueue_signals();
return 1;
}
@@ -1604,6 +1609,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
printcompctl((cclist & COMP_LIST) ? "" : "DEFAULT", &cc_default, 0, 0);
printcompctl((cclist & COMP_LIST) ? "" : "FIRST", &cc_first, 0, 0);
print_gmatcher((cclist & COMP_LIST));
+ unqueue_signals();
return ret;
}
@@ -1642,6 +1648,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
printcompctl("", &cc_first, 0, 0);
if (cclist & COMP_LISTMATCH)
print_gmatcher(COMP_LIST);
+ unqueue_signals();
return ret;
}
@@ -1656,6 +1663,7 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
compctl_process_cc(argv, cc);
}
+ unqueue_signals();
return ret;
}
@@ -1667,12 +1675,18 @@ bin_compctl(char *name, char **argv, UNUSED(Options ops), UNUSED(int func))
static int
bin_compcall(char *name, UNUSED(char **argv), Options ops, UNUSED(int func))
{
+ int ret;
+
if (incompfunc != 1) {
zwarnnam(name, "can only be called from completion function");
return 1;
}
- return makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
- (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
+
+ queue_signals();
+ ret = makecomplistctl((OPT_ISSET(ops,'T') ? 0 : CFN_FIRST) |
+ (OPT_ISSET(ops,'D') ? 0 : CFN_DEFAULT));
+ unqueue_signals();
+ return ret;
}
/*
@@ -1756,6 +1770,8 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
int onm = nmatches, odm = diffmatches, osi = movefd(0);
LinkNode n;
+ queue_signals();
+
/* We build a copy of the list of matchers to use to make sure that this
* works even if a shell function called from the completion code changes
* the global matchers. */
@@ -1883,6 +1899,8 @@ ccmakehookfn(UNUSED(Hookdef dummy), struct ccmakedat *dat)
}
redup(osi, 0);
dat->lst = 1;
+
+ unqueue_signals();
return 0;
}
@@ -2044,7 +2062,7 @@ maketildelist(void)
/* This does the check for compctl -x `n' and `N' patterns. */
/**/
-int
+static int
getcpat(char *str, int cpatindex, char *cpat, int class)
{
char *s, *t, *p;
diff --git a/Src/Zle/complete.c b/Src/Zle/complete.c
index 48fcd4751..49b338f29 100644
--- a/Src/Zle/complete.c
+++ b/Src/Zle/complete.c
@@ -896,6 +896,8 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
int i, l = arrlen(compwords), t = 0, b = 0, e = l - 1;
Patprog pp;
+ queue_signals(); /* Protect PAT_STATIC */
+
i = compcurrent - 1;
if (i < 0 || i >= l)
return 0;
@@ -930,6 +932,9 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
t = 0;
if (t && mod)
restrict_range(b, e);
+
+ unqueue_signals();
+
return t;
}
case CVT_PRENUM:
@@ -952,6 +957,8 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
{
Patprog pp;
+ queue_signals(); /* Protect PAT_STATIC */
+
if (!na)
return 0;
@@ -1036,6 +1043,9 @@ do_comp_vars(int test, int na, char *sa, int nb, char *sb, int mod)
if (mod)
ignore_suffix(ol - (p - compsuffix));
}
+
+ unqueue_signals();
+
return 1;
}
}
diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
index 5b9ceec1a..325da6ddb 100644
--- a/Src/Zle/computil.c
+++ b/Src/Zle/computil.c
@@ -3928,6 +3928,8 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
if (*q) {
char *qq, *qqq;
+ queue_signals();
+
if (c)
*c = '\0';
@@ -3999,6 +4001,8 @@ bin_comptry(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
}
if (c)
*c = ':';
+
+ unqueue_signals();
}
}
if (num) {
@@ -4708,6 +4712,8 @@ cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
if (!*p)
continue;
+ queue_signals(); /* Protect PAT_STATIC */
+
tokenize(f);
pprog = patcompile(f, PAT_STATIC, NULL);
untokenize(f);
@@ -4740,6 +4746,8 @@ cfp_add_sdirs(LinkList final, LinkList orig, char *skipped,
}
}
}
+
+ unqueue_signals();
}
}
}
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index 434735de9..581ca4979 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -1220,10 +1220,12 @@ doisearch(char **args, int dir, int pattern)
char *patbuf = ztrdup(sbuf);
char *patstring;
/*
- * Do not use static pattern buffer (PAT_STATIC) since we call zle hooks,
- * which might call other pattern functions. Use PAT_ZDUP instead.
- * Use PAT_NOANCH because we don't need the match
- * anchored to the end, even if it is at the start.
+ * Do not use static pattern buffer (PAT_STATIC) since we
+ * call zle hooks, which might call other pattern
+ * functions. Use PAT_ZDUP because we re-use the pattern
+ * in subsequent loops, so we can't pushheap/popheap.
+ * Use PAT_NOANCH because we don't need the match anchored
+ * to the end, even if it is at the start.
*/
int patflags = PAT_ZDUP|PAT_NOANCH;
if (sbuf[0] == '^') {