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:
parent
0c3aed77e0
commit
d824683000
27
check.t
27
check.t
@ -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
24
syn.c
@ -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) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user