From bf125295df9da84c44989e33f9f84b4ed4f8ea56 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 25 Aug 2018 17:45:08 +0200 Subject: [PATCH] Fix escaping of URLs in Perforce and Subversion drivers --- src/Composer/Repository/Vcs/FossilDriver.php | 2 +- src/Composer/Repository/Vcs/HgDriver.php | 4 ++-- src/Composer/Repository/Vcs/SvnDriver.php | 4 ++-- src/Composer/Util/Bitbucket.php | 2 +- src/Composer/Util/Filesystem.php | 2 +- src/Composer/Util/GitHub.php | 2 +- src/Composer/Util/GitLab.php | 2 +- src/Composer/Util/Perforce.php | 18 +++++++------- src/Composer/Util/Svn.php | 2 +- tests/Composer/Test/Util/PerforceTest.php | 25 ++++++++++---------- 10 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/Composer/Repository/Vcs/FossilDriver.php b/src/Composer/Repository/Vcs/FossilDriver.php index 0b689e7bf..cc872474e 100644 --- a/src/Composer/Repository/Vcs/FossilDriver.php +++ b/src/Composer/Repository/Vcs/FossilDriver.php @@ -226,7 +226,7 @@ class FossilDriver extends VcsDriver return false; } - $process = new ProcessExecutor(); + $process = new ProcessExecutor($io); // check whether there is a fossil repo in that path if ($process->execute('fossil info', $output, $url) === 0) { return true; diff --git a/src/Composer/Repository/Vcs/HgDriver.php b/src/Composer/Repository/Vcs/HgDriver.php index 2db995e2e..45f13d5fe 100644 --- a/src/Composer/Repository/Vcs/HgDriver.php +++ b/src/Composer/Repository/Vcs/HgDriver.php @@ -211,7 +211,7 @@ class HgDriver extends VcsDriver return false; } - $process = new ProcessExecutor(); + $process = new ProcessExecutor($io); // check whether there is a hg repo in that path if ($process->execute('hg summary', $output, $url) === 0) { return true; @@ -222,7 +222,7 @@ class HgDriver extends VcsDriver return false; } - $processExecutor = new ProcessExecutor(); + $processExecutor = new ProcessExecutor($io); $exit = $processExecutor->execute(sprintf('hg identify %s', ProcessExecutor::escape($url)), $ignored); return $exit === 0; diff --git a/src/Composer/Repository/Vcs/SvnDriver.php b/src/Composer/Repository/Vcs/SvnDriver.php index 96434517a..d3e7ee175 100644 --- a/src/Composer/Repository/Vcs/SvnDriver.php +++ b/src/Composer/Repository/Vcs/SvnDriver.php @@ -307,10 +307,10 @@ class SvnDriver extends VcsDriver return false; } - $processExecutor = new ProcessExecutor(); + $processExecutor = new ProcessExecutor($io); $exit = $processExecutor->execute( - "svn info --non-interactive {$url}", + "svn info --non-interactive ".ProcessExecutor::escape('{'.$url.'}'), $ignoredOutput ); diff --git a/src/Composer/Util/Bitbucket.php b/src/Composer/Util/Bitbucket.php index 1c578576f..1fc286ac4 100644 --- a/src/Composer/Util/Bitbucket.php +++ b/src/Composer/Util/Bitbucket.php @@ -44,7 +44,7 @@ class Bitbucket { $this->io = $io; $this->config = $config; - $this->process = $process ?: new ProcessExecutor; + $this->process = $process ?: new ProcessExecutor($io); $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); $this->time = $time; } diff --git a/src/Composer/Util/Filesystem.php b/src/Composer/Util/Filesystem.php index 04df84ecd..a3af3b825 100644 --- a/src/Composer/Util/Filesystem.php +++ b/src/Composer/Util/Filesystem.php @@ -527,7 +527,7 @@ class Filesystem protected function getProcess() { - return new ProcessExecutor; + return $this->processExecutor; } /** diff --git a/src/Composer/Util/GitHub.php b/src/Composer/Util/GitHub.php index 2f5dbe5cd..1eca1a9bb 100644 --- a/src/Composer/Util/GitHub.php +++ b/src/Composer/Util/GitHub.php @@ -39,7 +39,7 @@ class GitHub { $this->io = $io; $this->config = $config; - $this->process = $process ?: new ProcessExecutor; + $this->process = $process ?: new ProcessExecutor($io); $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); } diff --git a/src/Composer/Util/GitLab.php b/src/Composer/Util/GitLab.php index fb809e2d4..475c5e7ee 100644 --- a/src/Composer/Util/GitLab.php +++ b/src/Composer/Util/GitLab.php @@ -40,7 +40,7 @@ class GitLab { $this->io = $io; $this->config = $config; - $this->process = $process ?: new ProcessExecutor(); + $this->process = $process ?: new ProcessExecutor($io); $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config); } diff --git a/src/Composer/Util/Perforce.php b/src/Composer/Util/Perforce.php index fbd73b2b5..cb5f2ee8c 100644 --- a/src/Composer/Util/Perforce.php +++ b/src/Composer/Util/Perforce.php @@ -58,7 +58,7 @@ class Perforce { $output = null; - return 0 === $processExecutor->execute('p4 -p ' . $url . ' info -s', $output); + return 0 === $processExecutor->execute('p4 -p ' . ProcessExecutor::escape($url) . ' info -s', $output); } public function initialize($repoConfig) @@ -105,7 +105,7 @@ class Perforce public function cleanupClientSpec() { $client = $this->getClient(); - $task = 'client -d ' . $client; + $task = 'client -d ' . ProcessExecutor::escape($client); $useP4Client = false; $command = $this->generateP4Command($task, $useP4Client); $this->executeCommand($command); @@ -383,7 +383,7 @@ class Perforce if ($this->windowsFlag) { $this->windowsLogin($password); } else { - $command = 'echo ' . $password . ' | ' . $this->generateP4Command(' login -a', false); + $command = 'echo ' . ProcessExecutor::escape($password) . ' | ' . $this->generateP4Command(' login -a', false); $exitCode = $this->executeCommand($command); $result = trim($this->commandResult); if ($exitCode) { @@ -408,7 +408,7 @@ class Perforce { $path = $this->getFilePath($file, $identifier); - $command = $this->generateP4Command(' print ' . $path); + $command = $this->generateP4Command(' print ' . ProcessExecutor::escape($path)); $this->executeCommand($command); $result = $this->commandResult; @@ -429,7 +429,7 @@ class Perforce } $path = substr($identifier, 0, $index) . '/' . $file . substr($identifier, $index); - $command = $this->generateP4Command(' files ' . $path, false); + $command = $this->generateP4Command(' files ' . ProcessExecutor::escape($path), false); $this->executeCommand($command); $result = $this->commandResult; $index2 = strpos($result, 'no such file(s).'); @@ -452,7 +452,7 @@ class Perforce if (!$this->isStream()) { $possibleBranches[$this->p4Branch] = $this->getStream(); } else { - $command = $this->generateP4Command('streams //' . $this->p4Depot . '/...'); + $command = $this->generateP4Command('streams '.ProcessExecutor::escape('//' . $this->p4Depot . '/...')); $this->executeCommand($command); $result = $this->commandResult; $resArray = explode(PHP_EOL, $result); @@ -464,7 +464,7 @@ class Perforce } } } - $command = $this->generateP4Command('changes '. $this->getStream() . '/...', false); + $command = $this->generateP4Command('changes '. ProcessExecutor::escape($this->getStream() . '/...'), false); $this->executeCommand($command); $result = $this->commandResult; $resArray = explode(PHP_EOL, $result); @@ -527,7 +527,7 @@ class Perforce return null; } $label = substr($reference, $index); - $command = $this->generateP4Command(' changes -m1 ' . $label); + $command = $this->generateP4Command(' changes -m1 ' . ProcessExecutor::escape($label)); $this->executeCommand($command); $changes = $this->commandResult; if (strpos($changes, 'Change') !== 0) { @@ -555,7 +555,7 @@ class Perforce } $index = strpos($fromReference, '@'); $main = substr($fromReference, 0, $index) . '/...'; - $command = $this->generateP4Command('filelog ' . $main . '@' . $fromChangeList. ',' . $toChangeList); + $command = $this->generateP4Command('filelog ' . ProcessExecutor::escape($main . '@' . $fromChangeList. ',' . $toChangeList)); $this->executeCommand($command); return $this->commandResult; diff --git a/src/Composer/Util/Svn.php b/src/Composer/Util/Svn.php index df31ccbbf..58114ac93 100644 --- a/src/Composer/Util/Svn.php +++ b/src/Composer/Util/Svn.php @@ -79,7 +79,7 @@ class Svn $this->url = $url; $this->io = $io; $this->config = $config; - $this->process = $process ?: new ProcessExecutor; + $this->process = $process ?: new ProcessExecutor($io); } public static function cleanEnv() diff --git a/tests/Composer/Test/Util/PerforceTest.php b/tests/Composer/Test/Util/PerforceTest.php index 7d27b013e..777dbb3aa 100644 --- a/tests/Composer/Test/Util/PerforceTest.php +++ b/tests/Composer/Test/Util/PerforceTest.php @@ -14,6 +14,7 @@ namespace Composer\Test\Util; use Composer\Util\Perforce; use PHPUnit\Framework\TestCase; +use Composer\Util\ProcessExecutor; /** * @author Matt Whittom @@ -344,7 +345,7 @@ class PerforceTest extends TestCase { $this->setPerforceToStream(); - $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port streams //depot/...'; + $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port streams '.ProcessExecutor::escape('//depot/...'); $this->processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -357,7 +358,7 @@ class PerforceTest extends TestCase } ) ); - $expectedCommand2 = 'p4 -u user -p port changes //depot/branch/...'; + $expectedCommand2 = 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/branch/...'); $expectedCallback = function ($command, &$output) { $output = 'Change 1234 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\''; @@ -374,7 +375,7 @@ class PerforceTest extends TestCase public function testGetBranchesWithoutStream() { - $expectedCommand = 'p4 -u user -p port changes //depot/...'; + $expectedCommand = 'p4 -u user -p port changes '.ProcessExecutor::escape('//depot/...'); $expectedCallback = function ($command, &$output) { $output = 'Change 5678 on 2014/03/19 by Clark.Stuth@Clark.Stuth_test_client \'test changelist\''; @@ -458,7 +459,7 @@ class PerforceTest extends TestCase public function testGetComposerInformationWithoutLabelWithoutStream() { - $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print //depot/composer.json'; + $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print '.ProcessExecutor::escape('//depot/composer.json'); $this->processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -484,7 +485,7 @@ class PerforceTest extends TestCase public function testGetComposerInformationWithLabelWithoutStream() { - $expectedCommand = 'p4 -u user -p port files //depot/composer.json@0.0.1'; + $expectedCommand = 'p4 -u user -p port files '.ProcessExecutor::escape('//depot/composer.json@0.0.1'); $this->processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -498,7 +499,7 @@ class PerforceTest extends TestCase ) ); - $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print //depot/composer.json@10001'; + $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot -p port print '.ProcessExecutor::escape('//depot/composer.json@10001'); $this->processExecutor->expects($this->at(1)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -527,7 +528,7 @@ class PerforceTest extends TestCase { $this->setPerforceToStream(); - $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print //depot/branch/composer.json'; + $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print '.ProcessExecutor::escape('//depot/branch/composer.json'); $this->processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -555,7 +556,7 @@ class PerforceTest extends TestCase public function testGetComposerInformationWithLabelWithStream() { $this->setPerforceToStream(); - $expectedCommand = 'p4 -u user -p port files //depot/branch/composer.json@0.0.1'; + $expectedCommand = 'p4 -u user -p port files '.ProcessExecutor::escape('//depot/branch/composer.json@0.0.1'); $this->processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -569,7 +570,7 @@ class PerforceTest extends TestCase ) ); - $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print //depot/branch/composer.json@10001'; + $expectedCommand = 'p4 -u user -c composer_perforce_TEST_depot_branch -p port print '.ProcessExecutor::escape('//depot/branch/composer.json@10001'); $this->processExecutor->expects($this->at(1)) ->method('execute') ->with($this->equalTo($expectedCommand)) @@ -621,7 +622,7 @@ class PerforceTest extends TestCase { $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); - $expectedCommand = 'p4 -p perforce.does.exist:port info -s'; + $expectedCommand = 'p4 -p '.ProcessExecutor::escape('perforce.does.exist:port').' info -s'; $processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand), $this->equalTo(null)) @@ -642,7 +643,7 @@ class PerforceTest extends TestCase { $processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock(); - $expectedCommand = 'p4 -p perforce.does.exist:port info -s'; + $expectedCommand = 'p4 -p '.ProcessExecutor::escape('perforce.does.exist:port').' info -s'; $processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedCommand), $this->equalTo(null)) @@ -712,7 +713,7 @@ class PerforceTest extends TestCase $this->perforce->setFilesystem($fs); $testClient = $this->perforce->getClient(); - $expectedCommand = 'p4 -u ' . self::TEST_P4USER . ' -p ' . self::TEST_PORT . ' client -d ' . $testClient; + $expectedCommand = 'p4 -u ' . self::TEST_P4USER . ' -p ' . self::TEST_PORT . ' client -d ' . ProcessExecutor::escape($testClient); $this->processExecutor->expects($this->once())->method('execute')->with($this->equalTo($expectedCommand)); $fs->expects($this->once())->method('remove')->with($this->perforce->getP4ClientSpec());