diff --git a/NEWS b/NEWS index 24d4b67f6..0c2cdc32a 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-03-05: + +- Unbalanced quotes and backticks now correctly produce a syntax error + in -c scripts, 'eval', and backtick-style command substitutions. + 2021-03-04: - Fixed an arbitrary command execution vulnerability that occurred when diff --git a/src/cmd/ksh93/COMPATIBILITY b/src/cmd/ksh93/COMPATIBILITY index e70aa2c83..7c7585c9e 100644 --- a/src/cmd/ksh93/COMPATIBILITY +++ b/src/cmd/ksh93/COMPATIBILITY @@ -89,6 +89,9 @@ For more details, see the NEWS file and for complete details, see the git log. 15. 'command -x' now always runs an external command, bypassing built-ins. +16. Unbalanced quotes and backticks now correctly produce a syntax error + in -c scripts, 'eval', and backtick-style command substitutions. + ____________________________________________________________________________ KSH-93 VS. KSH-88 diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 80397a48a..6c5932688 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-03-04" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2021-03-05" /* 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 0fc46c4d6..1b7cee923 100644 --- a/src/cmd/ksh93/sh/lex.c +++ b/src/cmd/ksh93/sh/lex.c @@ -92,7 +92,6 @@ struct lexdata char nested_tilde; char *docend; char noarg; - char balance; char warn; char message; char arith; @@ -277,7 +276,7 @@ Lex_t *sh_lexopen(Lex_t *lp, Shell_t *sp, int mode) lp->lexd.warn=1; if(!mode) { - lp->lexd.noarg = lp->lexd.level= lp->lexd.dolparen = lp->lexd.balance = 0; + lp->lexd.noarg = lp->lexd.level= lp->lexd.dolparen = 0; lp->lexd.nocopy = lp->lexd.docword = lp->lexd.nest = lp->lexd.paren = 0; lp->lexd.lex_state = lp->lexd.lastc=0; lp->lexd.docend = 0; @@ -326,7 +325,6 @@ int sh_lex(Lex_t* lp) Stk_t *stkp = shp->stk; int inlevel=lp->lexd.level, assignment=0, ingrave=0; int epatchar=0; - Sfio_t *sp; #if SHOPT_MULTIBYTE LEN=1; #endif /* SHOPT_MULTIBYTE */ @@ -397,7 +395,6 @@ int sh_lex(Lex_t* lp) fcseek(-LEN); goto breakloop; case S_EOF: - sp = fcfile(); if((n=lexfill(lp)) > 0) { fcseek(-1); @@ -446,16 +443,11 @@ int sh_lex(Lex_t* lp) c = LBRACE; break; case '"': case '`': case '\'': - lp->lexd.balance = c; break; } - if(sp && !(sfset(sp,0,0)&SF_STRING)) - { - lp->lasttok = c; - lp->token = EOFSYM; - sh_syntax(lp); - } - lp->lexd.balance = c; + lp->lasttok = c; + lp->token = EOFSYM; + sh_syntax(lp); } goto breakloop; case S_COM: @@ -1299,13 +1291,9 @@ int sh_lex(Lex_t* lp) } breakloop: if(lp->lexd.nocopy) - { - lp->lexd.balance = 0; return(0); - } if(lp->lexd.dolparen) { - lp->lexd.balance = 0; if(lp->lexd.docword) nested_here(lp); lp->lexd.message = (wordflags&ARG_MESSAGE); @@ -1318,12 +1306,6 @@ breakloop: lp->arg = (struct argnod*)stkseek(stkp,ARGVAL); if(n>0) sfwrite(stkp,state,n); - /* add balancing character if necessary */ - if(lp->lexd.balance) - { - sfputc(stkp,lp->lexd.balance); - lp->lexd.balance = 0; - } sfputc(stkp,0); stkseek(stkp,stktell(stkp)-1); state = stkptr(stkp,ARGVAL);