### Merge request
This fixes a vulnerability by incorrect parsing of command line arguments.
The way how a triple quote chars (or double quote chars inside a quoted string) will be currently parsed in `CommandLineToArgvW` of wine is wrong, therefore opens an attack vector (using artificially created command line validated with different rules matching default parsing mechanism of Windows), so could be even considered as a vulnerability.
## Proposed changes
`CommandLineToArgvW` will parse command line arguments correct and more similar to Windows.
Here is the diff illustrating wrong behavior: ```diff ## # test is an alias for ## # python.exe -c "from sys import argv; del argv[0]; print(str(len(argv)) + ' | ' + ' | '.join(argv))" - # Wine + # Windows (and fixed variant) ## double in quoted string:
test "abc""def" ghi" xxx
- 2 | abc"def ghi | xxx + 2 | abc"def | ghi xxx
test "abc"""def" ghi" xxx
- 3 | abc"def | ghi" xxx + 2 | abc"def ghi | xxx ## triple in unquoted string:
test abc"""def" ghi" xxx
- 2 | abc"def ghi | xxx + 2 | abc"def | ghi xxx
test abc""""def" ghi" xxx
- 2 | abc"def | ghi xxx + 2 | abc"def ghi | xxx ``` As a consequence: - the arguments can be parsed incorrectly (compared to default behavior of Windows parser) in the way that parts of quoted arguments may become unquoted and vice versa, as well as swim between different args; - an attacker may create artificial command line that pass validation rules of nominal condition of Windows, but vulnerable here (inject, data steal, etc), because the arguments would deviate between validation and execution phase - special tokens like pipe `|`, ampersand `&` or redirecting tokens like `>` that normally included in quoted string (and validated as a string) could abrupt get different meaning and used for piping, redirecting etc, that beside the injection possibility opens still worse attacking vector that can even cause RCE or used to create persistent exploits.
<details><summary>Here is the nominal condition how arguments will be parsed in Windows...</summary>
cmd line|arg1|arg2 ---|---|--- abc" "def|abc def| abc\" \"def|abc"|"def "abc\" \"def"|abc" "def| "abc"" ""def"|abc" "def| abc"" ""def|abc|def abc""" """def|abc" "def| abc\""" \"""def|abc"|"def abc\\""" \\"""def|abc\" \"def "abc"""def" ghi"</sup>|abc"def ghi| "abc"""def" ghi<br><sup>* missing close qoute at end</sup>|abc"def ghi| "abc""def" ghi|abc"def|ghi "abc\"""def" ghi|abc""def|ghi "abc\\"""def" ghi"|abc\"def ghi| "abc\\\"""def" ghi|abc\""def|ghi "abc\\\\"""def" ghi"|abc\\"def ghi| </details>
For PoC one could use any lang like tcl, python, etc, or even a self-written executable getting the argc/argv from main.<br/> The above diff and nominal condition was generated using this python script on Windows box: ```python from sys import argv; del argv[0]; print(str(len(argv)) + ' | ' + ' | '.join(argv)) ``` ## References
[Related PR](https://github.com/reactos/reactos/pull/5186) with fix for ReactOS.