Visitar URL original
subprocess should quote `comspec` when forming its `args` string · Issue #101718 · python/cpython · GitHub
Skip to content

subprocess should quote comspec when forming its args string #101718

Description

@zooba

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)

Activity

  1. amiremohamadi commented on Feb 12, 2023

    @amiremohamadi
    Contributor

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

  2. eryksun commented on Feb 12, 2023

    @eryksun
    Contributor

    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
  3. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Nov 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-subprocessSubprocess issues.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions