summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-14 12:03:24 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-14 12:03:24 +0200
commitcad5a79bd4e8ceef4a68f1551fd2b25122bcb1c8 (patch)
tree07a542ea9ee47b56f69122ed66dea7ed8e6c1925
parent4343ca9aa879cabc52ff82c0a46d3ba20d7fec5c (diff)
hush: explain "empty quoted str marker" trick
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/shell/hush.c b/shell/hush.c
index d65da3b98..002140b1a 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5656,15 +5656,20 @@ static struct pipe *parse_stream(char **pstring,
nommu_addchr(&ctx.as_string, ch);
if (ch == '\'') {
ctx.word.has_quoted_part = 1;
- next = i_getch(input);
- if (next == '\'' && !ctx.pending_redirect/*why?*/) {
+ ch = i_getch(input);
+ if (ch == '\'' && !ctx.pending_redirect/*why?*/) {
insert_empty_quoted_str_marker:
- nommu_addchr(&ctx.as_string, next);
+ nommu_addchr(&ctx.as_string, ch);
+//Just inserting nothing doesn't work: consider
+// CMD $EMPTYVAR
+// CMD ''
+//At execution time both will expand argv[1] to empty string
+//and thus the argument will "vanish".
+//But for second CMD, it should not vanish!
o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
continue; /* get next char */
}
- ch = next;
while (1) {
if (ch == EOF) {
syntax_error_unterm_ch('\'');
@@ -5789,6 +5794,7 @@ static struct pipe *parse_stream(char **pstring,
if ((ctx.is_assignment == MAYBE_ASSIGNMENT
|| ctx.is_assignment == WORD_IS_KEYWORD)
&& ch == '='
+ // && !ctx.word.has_quoted_part // unnecessary, "empty quoted str marker" trick handles this too
&& endofname(ctx.word.data)[0] == '='
) {
ctx.is_assignment = DEFINITELY_ASSIGNMENT;
@@ -5983,7 +5989,7 @@ static struct pipe *parse_stream(char **pstring,
case '"':
ctx.word.has_quoted_part = 1;
if (next == '"' && !ctx.pending_redirect) {
- i_getch(input); /* eat second " */
+ ch = i_getch(input); /* eat second " */
goto insert_empty_quoted_str_marker;
}
if (ctx.is_assignment == NOT_ASSIGNMENT)