From 3eb12efae5b588eb03e3f14787cc510198e8d0f8 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 16 Feb 2022 08:37:36 +0000 Subject: [PATCH] VcsRepositories: handle initialize with invalid repository URL (#10525) --- .../Repository/Vcs/GitBitbucketDriver.php | 5 +- src/Composer/Repository/Vcs/GitHubDriver.php | 5 +- src/Composer/Repository/Vcs/GitLabDriver.php | 2 +- .../Repository/Vcs/GitBitbucketDriverTest.php | 8 ++++ .../Test/Repository/Vcs/GitHubDriverTest.php | 48 ++++++++++++++++++- 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/Composer/Repository/Vcs/GitBitbucketDriver.php b/src/Composer/Repository/Vcs/GitBitbucketDriver.php index 6942048995bc..dd4033991985 100644 --- a/src/Composer/Repository/Vcs/GitBitbucketDriver.php +++ b/src/Composer/Repository/Vcs/GitBitbucketDriver.php @@ -61,7 +61,10 @@ class GitBitbucketDriver extends VcsDriver */ public function initialize() { - Preg::match('#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i', $this->url, $match); + if (!Preg::isMatch('#^https?://bitbucket\.org/([^/]+)/([^/]+?)(\.git|/?)?$#i', $this->url, $match)) { + throw new \InvalidArgumentException(sprintf('The Bitbucket repository URL %s is invalid. It must be the HTTPS URL of a Bitbucket repository.', $this->url)); + } + $this->owner = $match[1]; $this->repository = $match[2]; $this->originUrl = 'bitbucket.org'; diff --git a/src/Composer/Repository/Vcs/GitHubDriver.php b/src/Composer/Repository/Vcs/GitHubDriver.php index e95492a66c0b..33d7e8cd37ce 100644 --- a/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/src/Composer/Repository/Vcs/GitHubDriver.php @@ -59,7 +59,10 @@ class GitHubDriver extends VcsDriver */ public function initialize() { - Preg::match('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/(.+?)(?:\.git|/)?$#', $this->url, $match); + if (!Preg::isMatch('#^(?:(?:https?|git)://([^/]+)/|git@([^:]+):/?)([^/]+)/(.+?)(?:\.git|/)?$#', $this->url, $match)) { + throw new \InvalidArgumentException(sprintf('The GitHub repository URL %s is invalid.', $this->url)); + } + $this->owner = $match[3]; $this->repository = $match[4]; $this->originUrl = strtolower(!empty($match[1]) ? $match[1] : $match[2]); diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 3c45b4e737a1..2e7d36cc2762 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -94,7 +94,7 @@ class GitLabDriver extends VcsDriver public function initialize() { if (!Preg::isMatch(self::URL_REGEX, $this->url, $match)) { - throw new \InvalidArgumentException('The URL provided is invalid. It must be the HTTP URL of a GitLab project.'); + throw new \InvalidArgumentException(sprintf('The GitLab repository URL %s is invalid. It must be the HTTP URL of a GitLab project.', $this->url)); } $guessedDomain = !empty($match['domain']) ? $match['domain'] : $match['domain2']; diff --git a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php index e685b9dfd181..b8fd2d2a521f 100644 --- a/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php @@ -218,6 +218,14 @@ public function testGetParams($driver) ); } + public function testInitializeInvalidRepositoryUrl() + { + $this->setExpectedException('\InvalidArgumentException'); + + $driver = $this->getDriver(array('url' => 'https://bitbucket.org/acme')); + $driver->initialize(); + } + public function testSupports() { $this->assertTrue( diff --git a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php index d48a8fd1c344..fcffb583bfce 100644 --- a/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php +++ b/tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php @@ -14,11 +14,11 @@ use Composer\Downloader\TransportException; use Composer\Repository\Vcs\GitHubDriver; +use Composer\Test\Mock\ProcessExecutorMock; use Composer\Test\TestCase; use Composer\Util\Filesystem; -use Composer\Util\Http\Response; -use Composer\Test\Mock\ProcessExecutorMock; use Composer\Config; +use Composer\Util\Http\Response; use Composer\Util\ProcessExecutor; class GitHubDriverTest extends TestCase @@ -341,6 +341,50 @@ public function testPrivateRepositoryNoInteraction() $process->assertComplete($this); } + /** + * @return void + */ + public function initializeInvalidReoUrl() + { + $this->setExpectedException('\InvalidArgumentException'); + + $repoConfig = array( + 'url' => 'https://github.com/acme', + ); + + $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); + $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader') + ->setConstructorArgs(array($io, $this->config)) + ->getMock(); + + $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $httpDownloader, new ProcessExecutorMock); + $gitHubDriver->initialize(); + } + + /** + * @dataProvider supportsProvider + * @param bool $expected + * @param string $repoUrl + */ + public function testSupports($expected, $repoUrl) + { + $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(); + + $this->assertSame($expected, GitHubDriver::supports($io, $this->config, $repoUrl)); + } + + /** + * @return list + */ + public function supportsProvider() + { + return array( + array(false, 'https://github.com/acme'), + array(true, 'https://github.com/acme/repository'), + array(true, 'git@github.com:acme/repository.git'), + ); + } + /** * @param string|object $object * @param string $attribute