From b7dde4e747f3a50b2f1b10aa3778ad43b44a70b4 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Wed, 21 Apr 2021 19:28:46 +0100 Subject: [PATCH] Fix ksh exit on syntax error in profile (re: cb67a01b, ceb77b13) Johnothan King writes: > There are two regressions related to how ksh handles syntax > errors in the .kshrc file. If ~/.kshrc or the file pointed to by > $ENV have a syntax error, ksh exits during startup. Additionally, > the error message printed is incorrect: > > $ cat /tmp/synerror > (( > echo foo > > # ksh93u+m > $ ENV=/tmp/synerror arch/*/bin/ksh -ic 'echo ${.sh.version}' > /tmp/synerror: syntax error: `/t/tmp/synerror' unmatched > > # ksh93u+ > $ ENV=/tmp/synerror ksh93u -ic 'echo ${.sh.version}' > /tmp/synerror: syntax error: `(' unmatched > Version AJM 93u+ 2012-08-01 > > The regression that causes the incorrect error message was > introduced by commit cb67a01. The other bug that causes ksh to > exit on startup was introduced by commit ceb77b1. src/cmd/ksh93/sh/lex.c: fmttoken(): - Call stakfreeze(0) to terminate a possible unterminated previous stack item before writing the token string onto the stack. This fixes the bug with garbage in a syntax error message. src/cmd/ksh93/sh/main.c: exfile(): - Revert Red Hat's ksh-20140801-diskfull.patch applied in ceb77b13. This fixes the bug with interactive ksh exiting on syntax error in a profile script. Testing by @JohnoKing showed the patch is no longer necessary to fix a login crash on disk full, as commit 970069a6 (which applied Red Hat patches ksh-20120801-macro.patch and ksh-20120801-fd2lost.patch) also fixes that crash. src/cmd/ksh93/README: - Fix typos. (re: fdc08b23) Co-authored-by: Johnothan King Resolves: https://github.com/ksh93/ksh/issues/281 --- NEWS | 5 +++++ src/cmd/ksh93/README | 4 ++-- src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh/lex.c | 1 + src/cmd/ksh93/sh/main.c | 4 ++-- src/cmd/ksh93/tests/pty.sh | 14 ++++++++++++++ 6 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 9868bedc7571..77f69e4ce486 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,11 @@ For full details, see the git log at: https://github.com/ksh93/ksh Any uppercase BUG_* names are modernish shell bug IDs. +2021-04-21: + +- Fixed a bug introduced on 2020-09-28 that caused an interactive ksh to exit + if a profile script (such as ~/.kshrc) contains a syntax error. + 2021-04-20: - Fixed three problems with the /opt/ast/bin/getconf built-in command: diff --git a/src/cmd/ksh93/README b/src/cmd/ksh93/README index eb4eaddaf9c7..051c5d3da2bd 100644 --- a/src/cmd/ksh93/README +++ b/src/cmd/ksh93/README @@ -44,7 +44,7 @@ The options have the following defaults and meanings: built-ins. The value must include double quotes. CRNL off treated as in shell grammar. DEVFD Use the more secure /dev/fd mechanism instead of FIFOs for - proces substitutions. On by default on OSs with /dev/fd. + process substitutions. On by default on OSs with /dev/fd. DYNAMIC on Dynamic loading of builtins. (Requires dlopen() interface.) ECHOPRINT off Make echo equivalent to print. EDPREDICT on Enables predictive editing. As you type a line beginning @@ -84,7 +84,7 @@ The options have the following defaults and meanings: value will require the -p flag to run suid/sgid scripts. RAWONLY on Turn on if the vi line mode doesn't work right unless you do a set -o viraw. - REGRESS off Enable the __regress__ built-in command and instrumented + REGRESS off Enable the __regress__ built-in command and instrumented intercepts for testing. REMOTE off Set --rc (read profile scripts) even if ksh was invoked with standard input on a socket, i.e. as a remote shell. diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index f7ff7143eed9..b9725ca5cf78 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -20,7 +20,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-alpha" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2021-04-20" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2021-04-21" /* 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/lex.c b/src/cmd/ksh93/sh/lex.c index d6f6a4b2a055..bdb575818281 100644 --- a/src/cmd/ksh93/sh/lex.c +++ b/src/cmd/ksh93/sh/lex.c @@ -2060,6 +2060,7 @@ static char *fmttoken(Lex_t *lp, register int sym) return((char*)sh_translate(e_endoffile)); if(sym==NL) return((char*)sh_translate(e_newline)); + stakfreeze(0); stakputc(sym); if(sym&SYMREP) stakputc(sym); diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 86ca971f391c..0ff17205a838 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -424,7 +424,7 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno) sfsync(shp->outpool); shp->st.execbrk = shp->st.breakcnt = 0; /* check for return from profile or env file */ - if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT || jmpval==SH_JMPERREXIT)) + if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT)) { sh_setstate(states); goto done; @@ -603,7 +603,7 @@ static void exfile(register Shell_t *shp, register Sfio_t *iop,register int fno) } if(jmpval == SH_JMPSCRIPT) siglongjmp(*shp->jmplist,jmpval); - else if(jmpval == SH_JMPEXIT || jmpval == SH_JMPERREXIT) + else if(jmpval == SH_JMPEXIT) sh_done(shp,0); if(fno>0) sh_close(fno); diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh index 0426300864bd..6ee7cfaa3f51 100755 --- a/src/cmd/ksh93/tests/pty.sh +++ b/src/cmd/ksh93/tests/pty.sh @@ -797,5 +797,19 @@ w cd emacste\t123abc r ^:test-1: cd emacstest/123abc\r\n$ ! +# err_exit # +echo '((' >$tmp/synerror +ENV=$tmp/synerror tst $LINENO <<"!" +L syntax error in profile causes exit on startup +# https://github.com/ksh93/ksh/issues/281 + +d 15 +r /synerror: syntax error: `\(' unmatched\r\n$ +p :test-1: +w echo ok +r ^:test-1: echo ok\r\n$ +r ^ok\r\n$ +! + # ====== exit $((Errors<125?Errors:125))