diff options
author | Barton E. Schaefer <schaefer@zsh.org> | 2016-03-20 10:30:58 -0700 |
---|---|---|
committer | Barton E. Schaefer <schaefer@zsh.org> | 2016-03-21 15:46:59 -0700 |
commit | 21202e7b95b2b34446fbac34df67205b3889eed2 (patch) | |
tree | 7b6925c7af6d5b0aa5e91356839edd7ed4d981e0 | |
parent | 09e991a20a0b27080e978607d6c8f4d14a166803 (diff) | |
download | zsh-21202e7b95b2b34446fbac34df67205b3889eed2.tar.gz zsh-21202e7b95b2b34446fbac34df67205b3889eed2.tar.xz zsh-21202e7b95b2b34446fbac34df67205b3889eed2.zip |
38191: additional re-entrancy checks in reexpandprompt()
Do not free global pointers until after promptexpand() in case they are referenced from signal handlers, and check for window size changes during promptexpand().
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 35 |
2 files changed, 34 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index d2f3ecc87..a763ba2d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,13 @@ 2016-03-20 Barton E. Schaefer <schaefer@zsh.org> + * 38191: Src/Zle/zle_main.c: in reexpandprompt(), do not free global + pointers until after promptexpand() in case they are referenced from + signal handlers, and do additional re-entrancy checks in case of + window size changes during promptexpand(). + +2016-03-20 Barton E. Schaefer <schaefer@zsh.org> + * 38188: Src/pattern.c: signal re-entrancy, maybe 2016-03-19 Mikael Magnusson <mikachu@gmail.com> diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 6e2bfded8..104e5d6c5 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1856,6 +1856,7 @@ void reexpandprompt(void) { static int reexpanding; + static int looping; if (!reexpanding++) { /* @@ -1866,15 +1867,33 @@ reexpandprompt(void) int local_lastval = lastval; lastval = pre_zle_status; - free(lpromptbuf); - lpromptbuf = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL, - &pmpt_attr); - rpmpt_attr = pmpt_attr; - free(rpromptbuf); - rpromptbuf = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL, - &rpmpt_attr); + do { + /* A new SIGWINCH may arrive while in promptexpand(), causing + * looping to increment. This only happens when a command + * substitution is used in a PROMPT_SUBST prompt, but + * nevertheless keep trying until we see no more changes. + */ + char *new_lprompt, *new_rprompt; + looping = reexpanding; + + new_lprompt = promptexpand(raw_lp ? *raw_lp : NULL, 1, NULL, NULL, + &pmpt_attr); + free(lpromptbuf); + lpromptbuf = new_lprompt; + + if (looping != reexpanding) + continue; + + rpmpt_attr = pmpt_attr; + new_rprompt = promptexpand(raw_rp ? *raw_rp : NULL, 1, NULL, NULL, + &rpmpt_attr); + free(rpromptbuf); + rpromptbuf = new_rprompt; + } while (looping != reexpanding); + lastval = local_lastval; - } + } else + looping = reexpanding; reexpanding--; } |