Alias expansion has a recursion check which tries to break the cycle if

encountered. However, when reading end of input, the source type is set
to SEOF while popping, whereas the recursion check code only checks for
an SALIAS type.

Fix: add a new SF_HASALIAS flag; change u.tblp from being valid if type
is SALIAS to being valid if SF_HASALIAS is set; set SF_HASALIAS for the
created SALIAS sources; set SF_HASALIAS and u.tblp when creating SALIAS
whose next is SEOF on the SEOF source as well.

Reported by Michael Hlavinka as Redhat Bug #474115
This commit is contained in:
tg 2008-12-02 12:39:38 +00:00
parent 177f707a9f
commit 4897682502
3 changed files with 17 additions and 8 deletions

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.246 2008/11/30 16:57:40 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.247 2008/12/02 12:39:36 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 $
@ -7,7 +7,7 @@
# http://www.research.att.com/~gsf/public/ifs.sh
expected-stdout:
@(#)MIRBSD KSH R36 2008/11/30
@(#)MIRBSD KSH R36 2008/12/02
description:
Check version of shell.
stdin:

14
lex.c
View File

@ -2,7 +2,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.76 2008/11/12 00:54:49 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.77 2008/12/02 12:39:37 tg Exp $");
/*
* states while lexing word
@ -903,16 +903,24 @@ yylex(int cf)
/* prefer functions over aliases */
ktdelete(p);
else {
Source *s;
Source *s = source;
for (s = source; s->type == SALIAS; s = s->next)
while (s->flags & SF_HASALIAS)
if (s->u.tblp == p)
return LWORD;
else
s = s->next;
/* push alias expansion */
s = pushs(SALIAS, source->areap);
s->start = s->str = p->val.s;
s->u.tblp = p;
s->flags |= SF_HASALIAS;
s->next = source;
if (source->type == SEOF) {
/* prevent infinite recursion at EOS */
source->u.tblp = p;
source->flags |= SF_HASALIAS;
}
source = s;
afree(yylval.cp, ATEMP);
goto Again;

7
sh.h
View File

@ -103,9 +103,9 @@
#define __SCCSID(x) __IDSTRING(sccsid,x)
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.262 2008/11/30 10:33:39 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.263 2008/12/02 12:39:38 tg Exp $");
#endif
#define MKSH_VERSION "R36 2008/11/30"
#define MKSH_VERSION "R36 2008/12/02"
#ifndef MKSH_INCLUDES_ONLY
@ -1147,7 +1147,7 @@ struct source {
union {
const char **strv; /* string [] */
struct shf *shf; /* shell file */
struct tbl *tblp; /* alias (SALIAS) */
struct tbl *tblp; /* alias (SF_HASALIAS) */
char *freeme; /* also for SREREAD */
} u;
int line; /* line number */
@ -1178,6 +1178,7 @@ struct source {
#define SF_ALIASEND BIT(2) /* faking space at end of alias */
#define SF_TTY BIT(3) /* type == SSTDIN & it is a tty */
#define SF_FIRST BIT(4) /* initial state (to ignore UTF-8 BOM) */
#define SF_HASALIAS BIT(5) /* u.tblp valid (SALIAS, SEOF) */
typedef union {
int i;