diff --git a/NEWS b/NEWS index a4f4ea903..7fbdb0740 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,12 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2021-12-11: + +- Fixed two more crashing bugs that occurred if ksh received a signal (such + as SIGINT due to Ctrl+C) while the user is entering a multi-line command + substitution in an interactive shell. + 2021-12-09: - Increased the general robustness of discipline function handling, fixing diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile index a9ce33904..80f52e04e 100644 --- a/src/cmd/ksh93/Mamfile +++ b/src/cmd/ksh93/Mamfile @@ -924,6 +924,7 @@ make install prev include/edit.h implicit prev include/history.h implicit prev include/shnodes.h implicit + prev include/shlex.h implicit prev include/jobs.h implicit prev include/io.h implicit prev include/path.h implicit diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 662c96448..899107ad7 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -21,7 +21,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2021-12-09" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2021-12-11" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2021 Contributors to ksh " SH_RELEASE_FORK /* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */ diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c index b96e6b21a..92146f40d 100644 --- a/src/cmd/ksh93/sh/fault.c +++ b/src/cmd/ksh93/sh/fault.c @@ -68,9 +68,6 @@ void sh_fault(register int sig) register char *trap; register struct checkpt *pp = (struct checkpt*)shp->jmplist; int action=0; - /* reset lexer state on Ctrl+C */ - if(sh_isstate(SH_INTERACTIVE) && sig==SIGINT) - sh_lexopen(sh.lex_context, &sh, 0); /* reset handler */ if(!(sig&SH_TRAP)) signal(sig, sh_fault); @@ -437,6 +434,15 @@ void sh_chktrap(Shell_t* shp) cursig = sig; sh_trap(trap,0); cursig = -1; + /* If we're in a PS2 prompt, then we just parsed and executed a trap in the middle of parsing + * another command, so the lexer state is overwritten. Escape to avoid crashing the lexer. */ + if(sh.nextprompt == 2) + { + fcclose(); /* force lexer to abort partial command */ + sh.nextprompt = 1; /* next display prompt is PS1 */ + sh.lastsig = sig; /* make sh_exit() set $? to signal exit status */ + sh_exit(SH_EXITSIG); /* start a new command line */ + } } } } diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c index 363df597c..c8c7dbfe3 100644 --- a/src/cmd/ksh93/sh/io.c +++ b/src/cmd/ksh93/sh/io.c @@ -37,6 +37,7 @@ #include "path.h" #include "io.h" #include "jobs.h" +#include "shlex.h" #include "shnodes.h" #include "history.h" #include "edit.h" @@ -2154,6 +2155,7 @@ static int io_prompt(Shell_t *shp,Sfio_t *iop,register int flag) case 1: { register int c; + sh_lexopen(sh.lex_context, &sh, 0); /* reset lexer state */ #if defined(TIOCLBIC) && defined(LFLUSHO) if(!sh_isoption(SH_VI) && !sh_isoption(SH_EMACS) && !sh_isoption(SH_GMACS)) {