Skip to content

Commit

Permalink
Fix BUG_CASELIT: pattern matching as literal string in 'case'
Browse files Browse the repository at this point in the history
This fixes an undocumented 'case' pattern matching misbehaviour
(labelled BUG_CASELIT in modernish) that goes back to the original
Bourne shell, but wasn't discovered until 2018.

If a pattern doesn't match as a pattern, it's tried again as a
literal string. This breaks common validation use cases, such as:

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

src/cmd/ksh93/sh/xec.c:
- Remove trim_eq() function responsible for implementing the
  misbehaviour described above.

NEWS:
- Added. Document this bugfix.

Ref.:
- The problem: thread starting at
  https://www.mail-archive.com/[email protected]/msg02127.html
- The solution, thanks to George Koehler: comments/commits in
  att#476
- Modernish BUG_CASELIT bug test & documentation:
  modernish/modernish@b2024ae3

(cherry picked from commit 8d6c8ce69884767a160c1e20049e77bdd849c248
with some extra edits to NEWS to upate the info for this reboot)
  • Loading branch information
McDutchie committed Jun 11, 2020
1 parent c1c7a1b commit 6a49720
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 21 deletions.
25 changes: 25 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -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
22 changes: 1 addition & 21 deletions src/cmd/ksh93/sh/xec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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
*/
Expand Down

0 comments on commit 6a49720

Please sign in to comment.