Skip to content

Commit 289a242

Browse files
committed
review
1 parent 1c35906 commit 289a242

2 files changed

Lines changed: 23 additions & 18 deletions

File tree

src/filemanager/command.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
Slava Zanko <slavazanko@gmail.com>, 2013
1212
Andrew Borodin <aborodin@vmail.ru>, 2011-2022
1313
14+
Updated by:
15+
Marek Libra <libra.marek@gmail.com>, 2026
16+
1417
This file is part of the Midnight Commander.
1518
1619
The Midnight Commander is free software: you can redistribute it
@@ -217,6 +220,9 @@ command_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *d
217220
* - Command substitution: $( or ` (including inside double quotes,
218221
* where the shell still expands them)
219222
*
223+
* Note: plain parameter expansion ($VAR, ${VAR}) is intentionally excluded
224+
* because the internal cd handler expands environment variables itself.
225+
*
220226
* Motivation: the internal cd handler cannot expand command substitutions
221227
* nor execute compound commands. When any of these constructs are present,
222228
* the entire command line must be passed to the shell.
@@ -247,22 +253,22 @@ command_has_unquoted_metacharacters (const char *cmd)
247253
continue;
248254
}
249255

250-
if (in_double_quote)
256+
if (*p == '\\' && p[1] != '\0')
251257
{
252-
if (*p == '\\' && p[1] != '\0')
253-
p++;
254-
else if (*p == '"')
255-
in_double_quote = FALSE;
256-
else if (*p == '`')
257-
return TRUE;
258-
else if (*p == '$' && p[1] == '(')
259-
return TRUE;
258+
p++;
260259
continue;
261260
}
262261

263-
if (*p == '\\' && p[1] != '\0')
262+
if (*p == '`')
263+
return TRUE;
264+
265+
if (*p == '$' && p[1] == '(')
266+
return TRUE;
267+
268+
if (in_double_quote)
264269
{
265-
p++;
270+
if (*p == '"')
271+
in_double_quote = FALSE;
266272
continue;
267273
}
268274

@@ -276,16 +282,10 @@ command_has_unquoted_metacharacters (const char *cmd)
276282
{
277283
in_double_quote = TRUE;
278284
continue;
279-
}
285+
}
280286

281287
if (*p == ';' || *p == '|' || *p == '&')
282288
return TRUE;
283-
284-
if (*p == '`')
285-
return TRUE;
286-
287-
if (*p == '$' && p[1] == '(')
288-
return TRUE;
289289
}
290290

291291
return FALSE;

tests/src/filemanager/has_unquoted_metacharacters.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ static const struct test_metacharacters_ds
9191
/* escaped metacharacter plus a real separator */
9292
{ "cd foo\\;bar; make", TRUE },
9393

94+
/* double-backslash before semicolon: \\; at runtime - first \ escapes second, ; is real */
95+
{ "cd foo\\\\;ls", TRUE },
96+
/* triple-backslash before semicolon: \\\; at runtime - \\ + \; (escaped semicolon) */
97+
{ "cd foo\\\\\\;ls", FALSE },
98+
9499
/* command substitution $(...) - internal cd cannot expand */
95100
{ "cd $(echo /tmp)", TRUE },
96101
{ "cd $(pwd)", TRUE },

0 commit comments

Comments
 (0)