diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-06 11:27:32 +0200 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-09-06 11:27:32 +0200 |
commit | 77b32ccbf2a1a77911b486b673008a4cb82bb8b7 (patch) | |
tree | c68a1bef8013018843321d6807aa87ca432808b1 /shell/hush.c | |
parent | c49d2d97939d77be3d1f3bbbbf9db30a55771c15 (diff) | |
download | busybox-w32-77b32ccbf2a1a77911b486b673008a4cb82bb8b7.tar.gz busybox-w32-77b32ccbf2a1a77911b486b673008a4cb82bb8b7.tar.bz2 busybox-w32-77b32ccbf2a1a77911b486b673008a4cb82bb8b7.zip |
hush: fix backslash and terminator handling in <<[-]["]heredoc["]
function old new delta
parse_stream 2339 2395 +56
expand_pseudo_dquoted 104 118 +14
parse_stream_dquoted 296 300 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 74/0) Total: 74 bytes
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/shell/hush.c b/shell/hush.c index ef46372de..e8aef2d7e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -3162,17 +3162,20 @@ static int redirect_opt_num(o_string *o) | |||
3162 | static char *fetch_till_str(o_string *as_string, | 3162 | static char *fetch_till_str(o_string *as_string, |
3163 | struct in_str *input, | 3163 | struct in_str *input, |
3164 | const char *word, | 3164 | const char *word, |
3165 | int skip_tabs) | 3165 | int heredoc_flags) |
3166 | { | 3166 | { |
3167 | o_string heredoc = NULL_O_STRING; | 3167 | o_string heredoc = NULL_O_STRING; |
3168 | int past_EOL = 0; | 3168 | int past_EOL = 0; |
3169 | int prev = 0; /* not \ */ | ||
3169 | int ch; | 3170 | int ch; |
3170 | 3171 | ||
3171 | goto jump_in; | 3172 | goto jump_in; |
3172 | while (1) { | 3173 | while (1) { |
3173 | ch = i_getch(input); | 3174 | ch = i_getch(input); |
3174 | nommu_addchr(as_string, ch); | 3175 | nommu_addchr(as_string, ch); |
3175 | if (ch == '\n') { | 3176 | if (ch == '\n' |
3177 | && ((heredoc_flags & HEREDOC_QUOTED) || prev != '\\') | ||
3178 | ) { | ||
3176 | if (strcmp(heredoc.data + past_EOL, word) == 0) { | 3179 | if (strcmp(heredoc.data + past_EOL, word) == 0) { |
3177 | heredoc.data[past_EOL] = '\0'; | 3180 | heredoc.data[past_EOL] = '\0'; |
3178 | debug_printf_parse("parsed heredoc '%s'\n", heredoc.data); | 3181 | debug_printf_parse("parsed heredoc '%s'\n", heredoc.data); |
@@ -3185,7 +3188,7 @@ static char *fetch_till_str(o_string *as_string, | |||
3185 | do { | 3188 | do { |
3186 | ch = i_getch(input); | 3189 | ch = i_getch(input); |
3187 | nommu_addchr(as_string, ch); | 3190 | nommu_addchr(as_string, ch); |
3188 | } while (skip_tabs && ch == '\t'); | 3191 | } while ((heredoc_flags & HEREDOC_SKIPTABS) && ch == '\t'); |
3189 | } while (ch == '\n'); | 3192 | } while (ch == '\n'); |
3190 | } | 3193 | } |
3191 | if (ch == EOF) { | 3194 | if (ch == EOF) { |
@@ -3194,6 +3197,7 @@ static char *fetch_till_str(o_string *as_string, | |||
3194 | } | 3197 | } |
3195 | o_addchr(&heredoc, ch); | 3198 | o_addchr(&heredoc, ch); |
3196 | nommu_addchr(as_string, ch); | 3199 | nommu_addchr(as_string, ch); |
3200 | prev = ch; | ||
3197 | } | 3201 | } |
3198 | } | 3202 | } |
3199 | 3203 | ||
@@ -3223,7 +3227,7 @@ static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_ | |||
3223 | redir->rd_type = REDIRECT_HEREDOC2; | 3227 | redir->rd_type = REDIRECT_HEREDOC2; |
3224 | /* redir->rd_dup is (ab)used to indicate <<- */ | 3228 | /* redir->rd_dup is (ab)used to indicate <<- */ |
3225 | p = fetch_till_str(&ctx->as_string, input, | 3229 | p = fetch_till_str(&ctx->as_string, input, |
3226 | redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS); | 3230 | redir->rd_filename, redir->rd_dup); |
3227 | if (!p) { | 3231 | if (!p) { |
3228 | syntax_error("unexpected EOF in here document"); | 3232 | syntax_error("unexpected EOF in here document"); |
3229 | return 1; | 3233 | return 1; |
@@ -3778,8 +3782,9 @@ static int parse_stream_dquoted(o_string *as_string, | |||
3778 | * only when followed by one of the following characters: | 3782 | * only when followed by one of the following characters: |
3779 | * $, `, ", \, or <newline>. A double quote may be quoted | 3783 | * $, `, ", \, or <newline>. A double quote may be quoted |
3780 | * within double quotes by preceding it with a backslash." | 3784 | * within double quotes by preceding it with a backslash." |
3785 | * NB: in (unquoted) heredoc, above does not apply to ". | ||
3781 | */ | 3786 | */ |
3782 | if (strchr("$`\"\\\n", next) != NULL) { | 3787 | if (next == dquote_end || strchr("$`\\\n", next) != NULL) { |
3783 | ch = i_getch(input); | 3788 | ch = i_getch(input); |
3784 | if (ch != '\n') { | 3789 | if (ch != '\n') { |
3785 | o_addqchr(dest, ch); | 3790 | o_addqchr(dest, ch); |
@@ -4412,6 +4417,7 @@ static char *expand_pseudo_dquoted(const char *str) | |||
4412 | o_string dest = NULL_O_STRING; | 4417 | o_string dest = NULL_O_STRING; |
4413 | 4418 | ||
4414 | if (!strchr(str, '$') | 4419 | if (!strchr(str, '$') |
4420 | && !strchr(str, '\\') | ||
4415 | #if ENABLE_HUSH_TICK | 4421 | #if ENABLE_HUSH_TICK |
4416 | && !strchr(str, '`') | 4422 | && !strchr(str, '`') |
4417 | #endif | 4423 | #endif |