hush: safe indention level by continueing a loop
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
36893bf29a
commit
8c3cc9621f
162
common/hush.c
162
common/hush.c
|
@ -1284,95 +1284,97 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
|
|||
ch >= ' ' ? ch : '.', ch, m,
|
||||
dest->quote, ctx->stack == NULL ? '*' : '.');
|
||||
|
||||
if (m==0 || ((m==1 || m==2) && dest->quote)) {
|
||||
if (m == 0 || ((m == 1 || m == 2) && dest->quote)) {
|
||||
b_addqchr(dest, ch, dest->quote);
|
||||
} else {
|
||||
if (m==2) { /* unquoted IFS */
|
||||
if (done_word(dest, ctx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m == 2) { /* unquoted IFS */
|
||||
if (done_word(dest, ctx)) {
|
||||
return 1;
|
||||
}
|
||||
/* If we aren't performing a substitution, treat a newline as a
|
||||
* command separator. */
|
||||
if (end_trigger != '\0' && ch=='\n')
|
||||
done_pipe(ctx,PIPE_SEQ);
|
||||
}
|
||||
if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) {
|
||||
debug("leaving parse_stream (triggered)\n");
|
||||
return 0;
|
||||
}
|
||||
if (m != 2) {
|
||||
switch (ch) {
|
||||
case '#':
|
||||
if (dest->length == 0 && !dest->quote) {
|
||||
while (ch = b_peek(input), ch != EOF && ch!='\n') {
|
||||
b_getch(input);
|
||||
}
|
||||
} else {
|
||||
b_addqchr(dest, ch, dest->quote);
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
if (next == EOF) {
|
||||
syntax();
|
||||
return 1;
|
||||
}
|
||||
/* If we aren't performing a substitution, treat a newline as a
|
||||
* command separator. */
|
||||
if (end_trigger != '\0' && ch=='\n')
|
||||
done_pipe(ctx,PIPE_SEQ);
|
||||
}
|
||||
if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) {
|
||||
debug("leaving parse_stream (triggered)\n");
|
||||
return 0;
|
||||
}
|
||||
if (m!=2) {
|
||||
switch (ch) {
|
||||
case '#':
|
||||
if (dest->length == 0 && !dest->quote) {
|
||||
while(ch=b_peek(input),ch!=EOF && ch!='\n') {
|
||||
b_getch(input);
|
||||
}
|
||||
} else {
|
||||
b_addqchr(dest, ch, dest->quote);
|
||||
}
|
||||
break;
|
||||
case '\\':
|
||||
if (next == EOF) {
|
||||
syntax();
|
||||
b_addqchr(dest, '\\', dest->quote);
|
||||
b_addqchr(dest, b_getch(input), dest->quote);
|
||||
break;
|
||||
case '$':
|
||||
if (handle_dollar(dest, ctx, input)!=0)
|
||||
return 1;
|
||||
break;
|
||||
case '\'':
|
||||
dest->nonnull = 1;
|
||||
while (ch = b_getch(input), ch!=EOF && ch != '\'') {
|
||||
if (input->__promptme == 0)
|
||||
return 1;
|
||||
}
|
||||
b_addqchr(dest, '\\', dest->quote);
|
||||
b_addqchr(dest, b_getch(input), dest->quote);
|
||||
break;
|
||||
case '$':
|
||||
if (handle_dollar(dest, ctx, input)!=0)
|
||||
return 1;
|
||||
break;
|
||||
case '\'':
|
||||
dest->nonnull = 1;
|
||||
while(ch=b_getch(input),ch!=EOF && ch!='\'') {
|
||||
if(input->__promptme == 0)
|
||||
return 1;
|
||||
b_addchr(dest,ch);
|
||||
}
|
||||
if (ch==EOF) {
|
||||
syntax();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
dest->nonnull = 1;
|
||||
dest->quote = !dest->quote;
|
||||
break;
|
||||
case ';':
|
||||
done_word(dest, ctx);
|
||||
done_pipe(ctx,PIPE_SEQ);
|
||||
break;
|
||||
case '&':
|
||||
done_word(dest, ctx);
|
||||
if (next=='&') {
|
||||
b_getch(input);
|
||||
done_pipe(ctx,PIPE_AND);
|
||||
} else {
|
||||
syntax_err();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
done_word(dest, ctx);
|
||||
if (next=='|') {
|
||||
b_getch(input);
|
||||
done_pipe(ctx,PIPE_OR);
|
||||
} else {
|
||||
/* we could pick up a file descriptor choice here
|
||||
* with redirect_opt_num(), but bash doesn't do it.
|
||||
* "echo foo 2| cat" yields "foo 2". */
|
||||
syntax_err();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
syntax(); /* this is really an internal logic error */
|
||||
b_addchr(dest,ch);
|
||||
}
|
||||
if (ch == EOF) {
|
||||
syntax();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case '"':
|
||||
dest->nonnull = 1;
|
||||
dest->quote = !dest->quote;
|
||||
break;
|
||||
case ';':
|
||||
done_word(dest, ctx);
|
||||
done_pipe(ctx, PIPE_SEQ);
|
||||
break;
|
||||
case '&':
|
||||
done_word(dest, ctx);
|
||||
if (next == '&') {
|
||||
b_getch(input);
|
||||
done_pipe(ctx, PIPE_AND);
|
||||
} else {
|
||||
syntax_err();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case '|':
|
||||
done_word(dest, ctx);
|
||||
if (next == '|') {
|
||||
b_getch(input);
|
||||
done_pipe(ctx, PIPE_OR);
|
||||
} else {
|
||||
/* we could pick up a file descriptor choice here
|
||||
* with redirect_opt_num(), but bash doesn't do it.
|
||||
* "echo foo 2| cat" yields "foo 2". */
|
||||
syntax_err();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
syntax(); /* this is really an internal logic error */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* complain if quote? No, maybe we just finished a command substitution
|
||||
* that was quoted. Example:
|
||||
* $ echo "`cat foo` plus more"
|
||||
|
|
Loading…
Reference in New Issue