python / cpython

The Python programming language
https://www.python.org
Other
63.14k stars 30.23k forks source link

windows installer quiet installation targetdir escapes "quote"-symbol #89236

Open 1ce60f14-740b-4dd9-acd9-6604a5da9bb4 opened 3 years ago

1ce60f14-740b-4dd9-acd9-6604a5da9bb4 commented 3 years ago
BPO 45073
Nosy @pfmoore, @tjguk, @zware, @eryksun, @zooba

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['3.8', 'type-bug', 'expert-installation', 'OS-windows'] title = 'windows installer quiet installation targetdir escapes "quote"-symbol' updated_at = user = 'https://bugs.python.org/DMI-1407' ``` bugs.python.org fields: ```python activity = actor = 'eryksun' assignee = 'none' closed = False closed_date = None closer = None components = ['Installation', 'Windows'] creation = creator = 'DMI-1407' dependencies = [] files = [] hgrepos = [] issue_num = 45073 keywords = [] message_count = 2.0 messages = ['400809', '400811'] nosy_count = 6.0 nosy_names = ['paul.moore', 'tim.golden', 'zach.ware', 'eryksun', 'steve.dower', 'DMI-1407'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue45073' versions = ['Python 3.8'] ```

1ce60f14-740b-4dd9-acd9-6604a5da9bb4 commented 3 years ago

If the windows installer (Python 3.8.9 64bit exe) is run in quiet mode and the TargetDir option is used, then the last quote (") symbol gets escaped if the path ends with an backslash (\).

Example: /quiet TargetDir="D:\pyt hon\" AssociateFiles=0 Result: TargetDir=hon\" AssociateFiles=0 this raises the error that the path contains a invalid character... (the quote ofc)

Example: /quiet TargetDir="D:\pyt hon" AssociateFiles=0 Result: installs correctly

so in general "D:\pyt hon" indicates a file thats named "pyt hon" where "D:\pyt hon\" indicates a folder. whatever "D:\pyt hon\" should be valid and i dont understand why the first backslash does not escape the p and leads to "D:pyt hon" ...

its really annoying, pls do at least write a notice into the docs that the installer behaves like this. :/

eryksun commented 3 years ago

A literal backlash has to be escaped by doubling it if it precedes a double quote, else it escapes the double quote character. This is how typical command-line argument parsing handles backslash in Windows [1]:

* 2n backslashes followed by a quotation mark produce n backslashes
  followed by begin/end quote. This does not become part of the
  parsed argument, but toggles the "in quotes" mode.
* (2n) + 1 backslashes followed by a quotation mark again produce n
  backslashes followed by a quotation mark literal ("). This does
  not toggle the "in quotes" mode.
* n backslashes not followed by a quotation mark simply produce n
  backslashes.

For example:

    import ctypes
    shell32 = ctypes.WinDLL('shell32', use_last_error=True)
    shell32.CommandLineToArgvW.restype = ctypes.POINTER(ctypes.c_wchar_p)
    n = ctypes.c_int()

Escape the trailing backslash as a literal backslash:

    >>> cmd = r'/quiet TargetDir="D:\pyt hon\\" AssociateFiles=0'
    >>> args = shell32.CommandLineToArgvW(cmd, ctypes.byref(n))
    >>> args[:n.value]
    ['/quiet', 'TargetDir=D:\\pyt hon\\', 'AssociateFiles=0']

Escape the double quote as a literal double quote:

    >>> cmd = r'/quiet TargetDir="D:\pyt hon\" AssociateFiles=0'
    >>> args = shell32.CommandLineToArgvW(cmd, ctypes.byref(n))
    >>> args[:n.value]
    ['/quiet', 'TargetDir=D:\\pyt hon" AssociateFiles=0']

[1] https://docs.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw