diff --git a/src/Composer/Command/HomeCommand.php b/src/Composer/Command/HomeCommand.php index 8e43f39a4..1a228b871 100644 --- a/src/Composer/Command/HomeCommand.php +++ b/src/Composer/Command/HomeCommand.php @@ -129,7 +129,7 @@ EOT $process = new ProcessExecutor($this->getIO()); if (Platform::isWindows()) { - return $process->execute('start "web" explorer "' . $url . '"', $output); + return $process->execute('start "web" explorer ' . $url, $output); } $linux = $process->execute('which xdg-open', $output); diff --git a/src/Composer/Util/ProcessExecutor.php b/src/Composer/Util/ProcessExecutor.php index 70ea40b77..668905821 100644 --- a/src/Composer/Util/ProcessExecutor.php +++ b/src/Composer/Util/ProcessExecutor.php @@ -455,7 +455,7 @@ class ProcessExecutor } /** - * Copy of ProcessUtils::escapeArgument() that is deprecated in Symfony 3.3 and removed in Symfony 4. + * Copy of Symfony's Process::escapeArgument() which is private * * @param string $argument * @@ -463,40 +463,21 @@ class ProcessExecutor */ private static function escapeArgument($argument) { - //Fix for PHP bug #43784 escapeshellarg removes % from given string - //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows - //@see https://bugs.php.net/bug.php?id=43784 - //@see https://bugs.php.net/bug.php?id=49446 - if ('\\' === DIRECTORY_SEPARATOR) { - if ((string) $argument === '') { - return escapeshellarg($argument); - } - - $escapedArgument = ''; - $quote = false; - foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) { - if ('"' === $part) { - $escapedArgument .= '\\"'; - } elseif (self::isSurroundedBy($part, '%')) { - // Avoid environment variable expansion - $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%'; - } else { - // escape trailing backslash - if ('\\' === substr($part, -1)) { - $part .= '\\'; - } - $quote = true; - $escapedArgument .= $part; - } - } - if ($quote) { - $escapedArgument = '"'.$escapedArgument.'"'; - } - - return $escapedArgument; + if ('' === $argument || null === $argument) { + return '""'; } + if ('\\' !== \DIRECTORY_SEPARATOR) { + return "'".str_replace("'", "'\\''", $argument)."'"; + } + if (str_contains($argument, "\0")) { + $argument = str_replace("\0", '?', $argument); + } + if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) { + return $argument; + } + $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument); - return "'".str_replace("'", "'\\''", $argument)."'"; + return '"'.str_replace(['"', '^', '%', '!', "\n"], ['""', '"^^"', '"^%"', '"^!"', '!LF!'], $argument).'"'; } /**