Skip to content

subprocess should quote comspec when forming its args string #101718

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
zooba opened this issue Feb 8, 2023 · 2 comments
Open

subprocess should quote comspec when forming its args string #101718

zooba opened this issue Feb 8, 2023 · 2 comments
Labels
stdlib Python modules in the Lib dir topic-subprocess Subprocess issues.

Comments

@zooba
Copy link
Member

zooba commented Feb 8, 2023

The value of args should quote comspec. Otherwise the shell process won't parse its command line correctly if comspec contains spaces.

Originally posted by @eryksun in #101712 (comment)

@amiremohamadi
Copy link
Contributor

could you provide an example to reproduce this scenario please? I think winapi handle it perfectly.

@eryksun
Copy link
Contributor

eryksun commented Feb 12, 2023

Regarding the API, previously with shell=True we didn't use lpApplicationName (i.e. the executable argument of subprocess.Popen). In this case the API has to parse the command out of the command line and search for the application name to use. For example, if the command line is r'C:\Program Files\JPSoft\TCCLE14x64\tcc.exe /c "dir"', then CreateProcessW() first looks for "C:\Program". It checks for the given name and also "C:\Program.exe". If that's not found, it consumes up to the next space character and looks for "C:\Program Files\JPSoft\TCCLE14x64\tcc.exe". If that's an existing file, it's used as the application name to execute.

In a related PR, subprocess.Popen has been modified to use lpApplicationName if the value of the "ComSpec" environment variable is an absolute path. In this case, the API doesn't have to search for the executable. Still the shell itself still has to parse its command line into command-line arguments, which may fail if the command isn't quoted. A shell is probably resilient to this, but that doesn't excuse the mistake in subprocess.Popen.

For an artificial example, let's run Python itself without quoting the executable path in the command line:

>>> os.getcwd()
'C:\\'
>>> sys.executable
'C:\\Program Files\\Python311\\python.exe'
>>> subprocess.call(fr'{sys.executable} -c "print(42)"', executable=sys.executable)
C:\Program: can't open file 'C:\\Files\\Python311\\python.exe': [Errno 2] No such file or directory
2

Python (rather, the C runtime library) parsed the command line as the argument list ['C:\\Program", "Files\\Python311\\python.exe", "-c", "print(42)"]. Let's fix this:

>>> subprocess.call(fr'"{sys.executable}" -c "print(42)"', executable=sys.executable)
42
0

@iritkatriel iritkatriel added the stdlib Python modules in the Lib dir label Nov 27, 2023
@vstinner vstinner added the topic-subprocess Subprocess issues. label Jul 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-subprocess Subprocess issues.
Projects
None yet
Development

No branches or pull requests

5 participants