diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..1280b3977 --- /dev/null +++ b/NEWS @@ -0,0 +1,25 @@ +This documents significant changes in the 93u+m branch of AT&T ksh93. +For full details, see the git log at: + https://github.com/modernish/ksh + +Any uppercase BUG_* names are modernish shell bug IDs. + +2020-05-13: + +- Fix BUG_CASELIT: an undocumented 'case' pattern matching misbehaviour that + goes back to the original Bourne shell, but wasn't discovered until 2018. + If a pattern doesn't match as a pattern, it was tried again as a literal + string. This broke common validation use cases, e.g.: + n='[0-9]' + case $n in + ( [0-9] ) echo "$n is a number" ;; + esac + would output "[0-9] is a number" as the literal string fallback matches the + pattern. As this misbehaviour was never documented anywhere (not for Bourne, + ksh88, or ksh93), and it was never replicated in other shells (not even in + ksh88 clones pdksh and mksh), it is unlikely any scripts rely on it. + Of course, a literal string fallback, should it be needed, is trivial to + implement correctly without this breakage: + case $n in + ( [0-9] | "[0-9]") echo "$n is a number or the number pattern" ;; + esac diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index c370477ad..9718266c0 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -65,7 +65,6 @@ #endif /* SHOPT_SPAWN */ static void sh_funct(Shell_t *,Namval_t*, int, char*[], struct argnod*,int); -static int trim_eq(const char*, const char*); static void coproc_init(Shell_t*, int pipes[]); static void *timeout; @@ -2556,8 +2555,7 @@ int sh_exec(register const Shnode_t *t, int flags) s = rex->argval; type = (rex->argflag&ARG_RAW); if((type && strcmp(r,s)==0) || - (!type && (strmatch(r,s) - || trim_eq(r,s)))) + (!type && strmatch(r,s))) { do sh_exec(t->reg.regcom,(t->reg.regflag?(flags&sh_state(SH_ERREXIT)):flags)); while(t->reg.regflag && @@ -2983,24 +2981,6 @@ int sh_run(int argn, char *argv[]) return(argn); } -/* - * test for equality with second argument trimmed - * returns 1 if r == trim(s) otherwise 0 - */ - -static int trim_eq(register const char *r,register const char *s) -{ - register char c; - while(c = *s++) - { - if(c=='\\') - c = *s++; - if(c && c != *r++) - return(0); - } - return(*r==0); -} - /* * print out the command line if set -x is on */