ensure that case end tokens are not mixed up (Closes: #220272)

XXX token/tpeek/musthave should rescan the last input lexems
XXX if the new cf passed doesn't match the last cf passed
This commit is contained in:
tg 2012-06-28 20:04:02 +00:00
parent 0c3aed77e0
commit d824683000
2 changed files with 46 additions and 5 deletions

27
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.545 2012/06/28 20:03:17 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.546 2012/06/28 20:04:01 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -10185,6 +10185,31 @@ expected-stdout:
b
x
---
name: case-braces
description:
Check that case end tokens are not mixed up (Debian #220272)
stdin:
i=0
for value in 'x' '}' 'esac'; do
print -n "$((++i))($value)bourne "
case $value in
}) echo brace ;;
*) echo no ;;
esac
print -n "$((++i))($value)korn "
case $value {
esac) echo esac ;;
*) echo no ;;
}
done
expected-stdout:
1(x)bourne no
2(x)korn no
3(})bourne brace
4(})korn no
5(esac)bourne no
6(esac)korn esac
---
name: stateptr-underflow
description:
This check overflows an Xrestpos stored in a short in R40

24
syn.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.75 2012/05/09 23:21:00 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.76 2012/06/28 20:04:02 tg Exp $");
extern short subshell_nesting_level;
extern void yyskiputf8bom(void);
@ -73,6 +73,9 @@ static int sALIAS = ALIAS; /* 0 in yyrecursive */
#define tpeek(cf) ((reject) ? (symbol) : (REJECT, symbol = yylex(cf)))
#define musthave(c,cf) do { if (token(cf) != (c)) syntaxerr(NULL); } while (/* CONSTCOND */ 0)
static const char Tcbrace[] = "}";
static const char Tesac[] = "esac";
static void
yyparse(void)
{
@ -602,7 +605,20 @@ casepart(int endtok)
if (token(CONTIN | KEYWORD) != '(')
REJECT;
do {
musthave(LWORD, 0);
switch (token(0)) {
case LWORD:
break;
case '}':
case ESAC:
if (symbol != endtok) {
strdupx(yylval.cp,
symbol == '}' ? Tcbrace : Tesac, ATEMP);
break;
}
/* FALLTHROUGH */
default:
syntaxerr(NULL);
}
XPput(ptns, yylval.cp);
} while (token(0) == '|');
REJECT;
@ -760,7 +776,7 @@ const struct tokeninfo {
{ "elif", ELIF, true },
{ "fi", FI, true },
{ "case", CASE, true },
{ "esac", ESAC, true },
{ Tesac, ESAC, true },
{ "for", FOR, true },
{ Tselect, SELECT, true },
{ "while", WHILE, true },
@ -771,7 +787,7 @@ const struct tokeninfo {
{ Tfunction, FUNCTION, true },
{ "time", TIME, true },
{ "{", '{', true },
{ "}", '}', true },
{ Tcbrace, '}', true },
{ "!", BANG, true },
{ "[[", DBRACKET, true },
/* Lexical tokens (0[EOF], LWORD and REDIR handled specially) */