restore yyrecursive context in quitenv (LP#1069428)

This commit is contained in:
tg 2012-10-30 20:07:15 +00:00
parent fc27886680
commit faa0a78df3
4 changed files with 52 additions and 20 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.562 2012/10/22 20:19:10 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.563 2012/10/30 20:07:10 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas 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: 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 $ # $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -29,7 +29,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R40 2012/10/22 @(#)MIRBSD KSH R40 2012/10/30
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -38,7 +38,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R40 2012/10/22 @(#)LEGACY KSH R40 2012/10/30
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:

5
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.234 2012/10/30 20:07:00 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.235 2012/10/30 20:07:12 tg Exp $");
extern char **environ; extern char **environ;
@ -925,6 +925,7 @@ newenv(int type)
ep->loc = e->loc; ep->loc = e->loc;
ep->savefd = NULL; ep->savefd = NULL;
ep->temps = NULL; ep->temps = NULL;
ep->yyrecursive_statep = NULL;
ep->type = type; ep->type = type;
ep->flags = 0; ep->flags = 0;
/* jump buffer is invalid because flags == 0 */ /* jump buffer is invalid because flags == 0 */
@ -938,6 +939,8 @@ quitenv(struct shf *shf)
char *cp; char *cp;
int fd; int fd;
while (e->yyrecursive_statep)
yyrecursive_pop();
if (ep->oenv && ep->oenv->loc != ep->loc) if (ep->oenv && ep->oenv->loc != ep->loc)
popblock(); popblock();
if (ep->savefd != NULL) { if (ep->savefd != NULL) {

9
sh.h
View File

@ -157,9 +157,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.597 2012/10/22 20:19:16 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.598 2012/10/30 20:07:13 tg Exp $");
#endif #endif
#define MKSH_VERSION "R40 2012/10/22" #define MKSH_VERSION "R40 2012/10/30"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -646,6 +646,8 @@ enum sh_flag {
#define kshlongjmp siglongjmp #define kshlongjmp siglongjmp
#endif #endif
struct yyrecursive_state;
extern struct env { extern struct env {
ALLOC_ITEM alloc_INT; /* internal, do not touch */ ALLOC_ITEM alloc_INT; /* internal, do not touch */
Area area; /* temporary allocation area */ Area area; /* temporary allocation area */
@ -653,6 +655,8 @@ extern struct env {
struct block *loc; /* local variables and functions */ struct block *loc; /* local variables and functions */
short *savefd; /* original redirected fds */ short *savefd; /* original redirected fds */
struct temp *temps; /* temp files */ struct temp *temps; /* temp files */
/* saved parser recursion state */
struct yyrecursive_state *yyrecursive_statep;
kshjmp_buf jbuf; /* long jump back to env creator */ kshjmp_buf jbuf; /* long jump back to env creator */
uint8_t type; /* environment type - see below */ uint8_t type; /* environment type - see below */
uint8_t flags; /* EF_* */ uint8_t flags; /* EF_* */
@ -1929,6 +1933,7 @@ void initkeywords(void);
struct op *compile(Source *, bool); struct op *compile(Source *, bool);
bool parse_usec(const char *, struct timeval *); bool parse_usec(const char *, struct timeval *);
char *yyrecursive(int); char *yyrecursive(int);
void yyrecursive_pop(void);
/* tree.c */ /* tree.c */
void fptreef(struct shf *, int, const char *, ...); void fptreef(struct shf *, int, const char *, ...);
char *snptreef(char *, ssize_t, const char *, ...); char *snptreef(char *, ssize_t, const char *, ...);

52
syn.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.82 2012/10/22 20:19:18 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/syn.c,v 1.83 2012/10/30 20:07:15 tg Exp $");
extern int subshell_nesting_type; extern int subshell_nesting_type;
extern void yyskiputf8bom(void); extern void yyskiputf8bom(void);
@ -33,6 +33,15 @@ struct nesting_state {
int start_line; /* line nesting began on */ int start_line; /* line nesting began on */
}; };
struct yyrecursive_state {
struct yyrecursive_state *next;
struct ioword **old_herep;
int old_symbol;
int old_salias;
int old_nesting_type;
bool old_reject;
};
static void yyparse(void); static void yyparse(void);
static struct op *pipeline(int); static struct op *pipeline(int);
static struct op *andor(void); static struct op *andor(void);
@ -1122,9 +1131,7 @@ yyrecursive(int subtype MKSH_A_UNUSED)
{ {
struct op *t; struct op *t;
char *cp; char *cp;
bool old_reject; struct yyrecursive_state *ys;
int old_symbol, old_salias, old_nesting_type;
struct ioword **old_herep;
int stok, etok; int stok, etok;
#ifndef MKSH_DISABLE_EXPERIMENTAL #ifndef MKSH_DISABLE_EXPERIMENTAL
@ -1138,28 +1145,45 @@ yyrecursive(int subtype MKSH_A_UNUSED)
etok = ')'; etok = ')';
} }
ys = alloc(sizeof(struct yyrecursive_state), ATEMP);
/* tell the lexer to accept a closing parenthesis as EOD */ /* tell the lexer to accept a closing parenthesis as EOD */
old_nesting_type = subshell_nesting_type; ys->old_nesting_type = subshell_nesting_type;
subshell_nesting_type = etok; subshell_nesting_type = etok;
/* push reject state, parse recursively, pop reject state */ /* push reject state, parse recursively, pop reject state */
old_reject = reject; ys->old_reject = reject;
old_symbol = symbol; ys->old_symbol = symbol;
ACCEPT; ACCEPT;
old_herep = herep; ys->old_herep = herep;
old_salias = sALIAS; ys->old_salias = sALIAS;
sALIAS = 0; sALIAS = 0;
ys->next = e->yyrecursive_statep;
e->yyrecursive_statep = ys;
/* we use TPAREN as a helper container here */ /* we use TPAREN as a helper container here */
t = nested(TPAREN, stok, etok); t = nested(TPAREN, stok, etok);
sALIAS = old_salias; yyrecursive_pop();
herep = old_herep;
reject = old_reject;
symbol = old_symbol;
/* t->left because nested(TPAREN, ...) hides our goodies there */ /* t->left because nested(TPAREN, ...) hides our goodies there */
cp = snptreef(NULL, 0, "%T", t->left); cp = snptreef(NULL, 0, "%T", t->left);
tfree(t, ATEMP); tfree(t, ATEMP);
subshell_nesting_type = old_nesting_type;
return (cp); return (cp);
} }
void
yyrecursive_pop(void)
{
struct yyrecursive_state *ys = e->yyrecursive_statep;
e->yyrecursive_statep = ys->next;
sALIAS = ys->old_salias;
herep = ys->old_herep;
reject = ys->old_reject;
symbol = ys->old_symbol;
subshell_nesting_type = ys->old_nesting_type;
afree(ys, ATEMP);
}