fix reentry of here documents (LP#1030581)

This commit is contained in:
tg 2012-07-30 19:58:05 +00:00
parent 9156b9eee4
commit 8e51bb7a23
2 changed files with 60 additions and 26 deletions

26
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.551 2012/07/20 23:22:07 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.552 2012/07/30 19:58:03 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 $
@ -2268,7 +2268,13 @@ stdin:
=c $x \x40=
EOF
}
typeset -f foo
fnd=$(typeset -f foo)
print -r -- "$fnd"
function foo {
echo blub
}
foo
eval "$fnd"
foo
# rather nonsensical, but…
vd=<<<"=d $x \x40="
@ -2278,11 +2284,12 @@ stdin:
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
expected-stdout:
function foo {
vc= <<-EOF
vc=<<-EOF
=c $x \x40=
EOF
}
blub
| va={=a u \x40=
} vb={=b $x \x40=
} vc={=c u \x40=
@ -2310,20 +2317,27 @@ stdin:
=d $x \x40=
}
typeset -f foo
fnd=$(typeset -f foo)
print -r -- "$fnd"
function foo {
echo blub
}
foo
eval "$fnd"
foo
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
expected-stdout:
function foo {
vc= <<-
vc=<<-
=c $x \x40=
<<
vd= <<-""
vd=<<-""
=d $x \x40=
}
blub
| va={=a u \x40=
} vb={=b $x \x40=
} vc={=c u \x40=

30
tree.c
View File

@ -23,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.61 2012/06/28 20:17:39 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/tree.c,v 1.62 2012/07/30 19:58:05 tg Exp $");
#define INDENT 8
@ -53,6 +53,25 @@ ptree(struct op *t, int indent, struct shf *shf)
return;
switch (t->type) {
case TCOM:
prevent_semicolon = false;
/*
* special-case 'var=<<EOF' (rough; see
* exec.c:execute() for full code)
*/
if (
/* we have zero arguments, i.e. no programme to run */
t->args[0] == NULL &&
/* we have exactly one variable assignment */
t->vars[0] != NULL && t->vars[1] == NULL &&
/* we have exactly one I/O redirection */
t->ioact != NULL && t->ioact[0] != NULL &&
t->ioact[1] == NULL &&
/* of type "here document" (or "here string") */
(t->ioact[0]->flag & IOTYPE) == IOHERE) {
fptreef(shf, indent, "%S", t->vars[0]);
break;
}
if (t->vars) {
w = (const char **)t->vars;
while (*w)
@ -65,7 +84,6 @@ ptree(struct op *t, int indent, struct shf *shf)
fptreef(shf, indent, "%S ", *w++);
} else
shf_puts("#no-args# ", shf);
prevent_semicolon = false;
break;
case TEXEC:
t = t->left;
@ -216,8 +234,10 @@ ptree(struct op *t, int indent, struct shf *shf)
* often leads to an extra blank line, but it's not
* worth worrying about)
*/
if (need_nl)
if (need_nl) {
shf_putc('\n', shf);
prevent_semicolon = true;
}
}
}
@ -258,8 +278,8 @@ pioact(struct shf *shf, int indent, struct ioword *iop)
/* name/delim are NULL when printing syntax errors */
if (type == IOHERE) {
if (iop->delim)
fptreef(shf, indent, "%S ", iop->delim);
else
wdvarput(shf, iop->delim, 0, WDS_TPUTS);
if (iop->flag & IOHERESTR)
shf_putc(' ', shf);
} else if (iop->name)
fptreef(shf, indent, (iop->flag & IONAMEXP) ? "%s " : "%S ",