Escapes cmd.exe Special Characters#5030
Escapes cmd.exe Special Characters#5030myurasov-nv wants to merge 2 commits intoisaac-sim:developfrom
Conversation
Greptile SummaryThis PR fixes a Windows-specific bug where
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["run_command(cmd, ...)"] --> B{"cmd is list/tuple<br>AND is_windows()?"}
B -- No --> F["subprocess.run(cmd, ...)"]
B -- Yes --> C["_escape_for_cmd_exe(cmd)"]
C --> D{"cmd[0] ends with<br>.bat or .cmd?"}
D -- No --> E["Return list(cmd) unchanged"]
D -- Yes --> G["Quote args with metacharacters<br>or whitespace"]
G --> H["Return joined string<br>(bypasses list2cmdline)"]
E --> F
H --> F
Last reviewed commit: 711410c |
| for arg in cmd: | ||
| s = str(arg) | ||
| if any(c in s for c in _CMD_METACHARACTERS) or " " in s or "\t" in s: | ||
| parts.append(f'"{s}"') |
There was a problem hiding this comment.
Arguments with embedded double quotes will produce malformed quoting
If an argument already contains a " character (e.g., a path like C:\some"dir\file), wrapping it in f'"{s}"' produces "C:\some"dir\file" which cmd.exe will parse incorrectly. While this is unlikely with current callers (pip package specs, flags, paths), it would be safer to escape any existing double quotes before wrapping:
| for arg in cmd: | |
| s = str(arg) | |
| if any(c in s for c in _CMD_METACHARACTERS) or " " in s or "\t" in s: | |
| parts.append(f'"{s}"') | |
| if any(c in s for c in _CMD_METACHARACTERS) or " " in s or "\t" in s: | |
| parts.append(f'"{s.replace(chr(34), chr(34)+chr(34))}"') |
In cmd.exe, "" inside a double-quoted string represents a literal ". This is a minor defensive hardening — current callers don't pass arguments with embedded quotes, but future callers might.
When
subprocess.run()receives a list whose first element is a.batfile, Python invokescmd.exe /c "..."under the hood.subprocess.list2cmdlineexecuted down the line does not escapecmd.exespecial characters (<,>,|,&,^), so they are interpreted as shell operators, which breaks commands that utilize IsacSim'spython.batas interpreter ("C:\Users\Misha\IsaacLab\_isaac_sim\python.bat -m pip install setuptools<82.0.0"etc).run_command()now detects.bat/.cmdexecutables on Windows and converts the command list to a pre-quoted string, bypassinglist2cmdline.Type of change
Checklist
pre-commitchecks with./isaaclab.sh --formatconfig/extension.tomlfileCONTRIBUTORS.mdor my name already exists there