ash: [PARSER] Removed noexpand/length check on eofmark
Upstream comment: Date: Sun, 11 Nov 2007 14:21:23 +0800 [PARSER] Removed noexpand/length check on eofmark On Tue, Oct 30, 2007 at 04:23:35AM +0000, Oleg Verych wrote: > > } 8<<"" > ====================== Actually this (the empty delim) only works with dash by accident. I've tried bash and pdksh and they both terminate on the first empty line which is what you would expect rather than EOF. The real Korn shell does something completely different. I've fixed this in dash to conform to bash/pdksh. > In [0] it's stated, that delimiter isn't evaluated (expanded), only > quoiting must be checked. That if() seems to be completely bogus. OK I agree. The reason it was there is because the parser would have already replaced the dollar sign by an internal representation. I've fixed it properly with this patch. Test case: cat <<- $a OK $a cat <<- "" OK echo OK Old result: dash: Syntax error: Illegal eof marker for << redirection OK echo OK New result: OK OK OK function old new delta parsefname 227 152 -75 readtoken1 2819 2651 -168 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-243) Total: -243 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
170f93ef1b
commit
a732898fdd
103
shell/ash.c
103
shell/ash.c
@ -9991,6 +9991,7 @@ static smallint checkkwd;
|
||||
#define CHKALIAS 0x1
|
||||
#define CHKKWD 0x2
|
||||
#define CHKNL 0x4
|
||||
#define CHKEOFMARK 0x8
|
||||
|
||||
/*
|
||||
* Push a string back onto the input at this current parsefile level.
|
||||
@ -10302,31 +10303,6 @@ pgetc_without_PEOA(void)
|
||||
# define pgetc_without_PEOA() pgetc()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read a line from the script.
|
||||
*/
|
||||
static char *
|
||||
pfgets(char *line, int len)
|
||||
{
|
||||
char *p = line;
|
||||
int nleft = len;
|
||||
int c;
|
||||
|
||||
while (--nleft > 0) {
|
||||
c = pgetc_without_PEOA();
|
||||
if (c == PEOF) {
|
||||
if (p == line)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
*p++ = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
*p = '\0';
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo a call to pgetc. Only two characters may be pushed back.
|
||||
* PEOF may be pushed back.
|
||||
@ -10960,8 +10936,6 @@ raise_error_unexpected_syntax(int token)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#define EOFMARKLEN 79
|
||||
|
||||
/* parsing is heavily cross-recursive, need these forward decls */
|
||||
static union node *andor(void);
|
||||
static union node *pipeline(void);
|
||||
@ -11141,43 +11115,22 @@ fixredir(union node *n, const char *text, int err)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the text contains nothing to expand (no dollar signs
|
||||
* or backquotes).
|
||||
*/
|
||||
static int
|
||||
noexpand(const char *text)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
while ((c = *text++) != '\0') {
|
||||
if (c == CTLQUOTEMARK)
|
||||
continue;
|
||||
if (c == CTLESC)
|
||||
text++;
|
||||
else if (SIT(c, BASESYNTAX) == CCTL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
parsefname(void)
|
||||
{
|
||||
union node *n = redirnode;
|
||||
|
||||
if (n->type == NHERE)
|
||||
checkkwd = CHKEOFMARK;
|
||||
if (readtoken() != TWORD)
|
||||
raise_error_unexpected_syntax(-1);
|
||||
if (n->type == NHERE) {
|
||||
struct heredoc *here = heredoc;
|
||||
struct heredoc *p;
|
||||
int i;
|
||||
|
||||
if (quoteflag == 0)
|
||||
n->type = NXHERE;
|
||||
TRACE(("Here document %d\n", n->type));
|
||||
if (!noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN)
|
||||
raise_error_syntax("illegal eof marker for << redirection");
|
||||
rmescapes(wordtext, 0);
|
||||
here->eofmark = wordtext;
|
||||
here->next = NULL;
|
||||
@ -11593,7 +11546,6 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
/* c parameter is an unsigned char or PEOF or PEOA */
|
||||
char *out;
|
||||
size_t len;
|
||||
char line[EOFMARKLEN + 1];
|
||||
struct nodelist *bqlist;
|
||||
smallint quotef;
|
||||
smallint dblquote;
|
||||
@ -11816,6 +11768,9 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
*/
|
||||
checkend: {
|
||||
if (eofmark) {
|
||||
int markloc;
|
||||
char *p;
|
||||
|
||||
#if ENABLE_ASH_ALIAS
|
||||
if (c == PEOA)
|
||||
c = pgetc_without_PEOA();
|
||||
@ -11825,27 +11780,42 @@ checkend: {
|
||||
c = pgetc_without_PEOA();
|
||||
}
|
||||
}
|
||||
if (c == *eofmark) {
|
||||
if (pfgets(line, sizeof(line)) != NULL) {
|
||||
char *p, *q;
|
||||
int cc;
|
||||
|
||||
p = line;
|
||||
for (q = eofmark + 1;; p++, q++) {
|
||||
cc = *p;
|
||||
if (cc == '\n')
|
||||
cc = 0;
|
||||
if (!*q || cc != *q)
|
||||
break;
|
||||
markloc = out - (char *)stackblock();
|
||||
for (p = eofmark; STPUTC(c, out), *p; p++) {
|
||||
if (c != *p)
|
||||
goto more_heredoc;
|
||||
|
||||
c = pgetc_without_PEOA();
|
||||
}
|
||||
if (cc == *q) {
|
||||
|
||||
if (c == '\n' || c == PEOF) {
|
||||
c = PEOF;
|
||||
nlnoprompt();
|
||||
g_parsefile->linno++;
|
||||
needprompt = doprompt;
|
||||
} else {
|
||||
pushstring(line, NULL);
|
||||
int len_here;
|
||||
|
||||
more_heredoc:
|
||||
p = (char *)stackblock() + markloc + 1;
|
||||
len_here = out - p;
|
||||
|
||||
if (len_here) {
|
||||
len_here -= (c >= PEOF);
|
||||
c = p[-1];
|
||||
|
||||
if (len_here) {
|
||||
char *str;
|
||||
|
||||
str = alloca(len_here + 1);
|
||||
*(char *)mempcpy(str, p, len_here) = '\0';
|
||||
|
||||
pushstring(str, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STADJUST((char *)stackblock() + markloc - out, out);
|
||||
}
|
||||
goto checkend_return;
|
||||
}
|
||||
@ -11939,7 +11909,8 @@ parsesub: {
|
||||
int typeloc;
|
||||
|
||||
c = pgetc_eatbnl();
|
||||
if (c > 255 /* PEOA or PEOF */
|
||||
if ((checkkwd & CHKEOFMARK)
|
||||
|| c > 255 /* PEOA or PEOF */
|
||||
|| (c != '(' && c != '{' && !is_name(c) && !is_special(c))
|
||||
) {
|
||||
#if BASH_DOLLAR_SQUOTE
|
||||
|
3
shell/ash_test/ash-heredoc/heredoc_empty.right
Normal file
3
shell/ash_test/ash-heredoc/heredoc_empty.right
Normal file
@ -0,0 +1,3 @@
|
||||
OK
|
||||
OK
|
||||
OK
|
8
shell/ash_test/ash-heredoc/heredoc_empty.tests
Executable file
8
shell/ash_test/ash-heredoc/heredoc_empty.tests
Executable file
@ -0,0 +1,8 @@
|
||||
unset a
|
||||
cat <<- $a
|
||||
OK
|
||||
$a
|
||||
cat <<- ""
|
||||
OK
|
||||
|
||||
echo OK
|
Loading…
Reference in New Issue
Block a user