Description
Symfony version(s) affected
5.4+
Description
On windows, some commands like rmdir are built-in commands inside cmd.exe, and not a rmdir.exe process.. And it seems cmd.exe has trouble parsing flags when they are escaped via the env var thing of #21474 (cc @nicolas-grekas).
How to reproduce
<?php
include 'vendor/autoload.php';
mkdir('test/foo/bar', 0777, true);
$p = new Symfony\Component\Process\Process(['rmdir', '/S', '/Q', 'test']);
$p->run();
var_dump($p->getOutput(), $p->getErrorOutput(), $p->getExitCode());
$p = Symfony\Component\Process\Process::fromShellCommandline('rmdir /S /Q test');
$p->run();
var_dump($p->getOutput(), $p->getErrorOutput(), $p->getExitCode());
$p = new Symfony\Component\Process\Process(['ipconfig']);
$p->run();
var_dump($p->getOutput());
$p = new Symfony\Component\Process\Process(['ipconfig', '/all']);
$p->run();
var_dump($p->getOutput()); // correctly shows more info than without /all flag, so this works
Running the above outputs this for the first command using symfony escaping:
string(0) ""
string(117) "The system cannot find the file specified.
The system cannot find the file specified.
The directory is not empty.
"
int(145)
You can see there are 3 errors, because it takes /S, /Q and test as 3 arguments and not two option flags and one argument. So it doesn't find "/S" which indeed is no valid path, same for "/Q", then it finds test but cannot delete it as it is not empty and it requires /S for that to work, but it didn't detect it as an option.
string(0) ""
string(0) ""
int(0)
This second version using a string command works fine.
The ipconfig test works fine in both ways, so I am unsure if the problem is dependent on which command runs, or if it's just cmd.exe built-ins, or what the root cause is.
Possible Solution
I'd say maybe we don't need to escape strings that are just /[a-zA-Z0-9]+
, as that seems safe.
Additional Context
Found via composer/composer#12180