From c7519144105bf319fd7ce437f9733b3cdc443ce7 Mon Sep 17 00:00:00 2001 From: pfofi <7479939+pfofi@users.noreply.github.com> Date: Fri, 10 May 2019 13:55:31 +0200 Subject: [PATCH 1/7] Fix URL resolution for Composer repositories Composer was unable canonicalize URLs in non-HTTP(S) Composer repositories. For example it was not possible to use a `providers-url` in a repository loaded via the `file://` scheme. See also: #8115 --- .../Repository/ComposerRepository.php | 6 +- .../Repository/ComposerRepositoryTest.php | 67 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 38b865103..1b03885fe 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -562,7 +562,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito protected function canonicalizeUrl($url) { if ('/' === $url[0]) { - return preg_replace('{(https?://[^/]+).*}i', '$1' . $url, $this->url); + if (preg_match('{[^:]+://[^/]*}', $this->url, $matches)) { + return $matches[0] . $url; + } + + return $this->url; } return $url; diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php index 3e29e8023..8e9216b35 100644 --- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php +++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php @@ -204,4 +204,71 @@ class ComposerRepositoryTest extends TestCase $repository->search('foo', RepositoryInterface::SEARCH_FULLTEXT, 'library') ); } + + /** + * @dataProvider canonicalizeUrlProvider + * + * @param string $expected + * @param string $url + * @param string $repositoryUrl + */ + public function testCanonicalizeUrl($expected, $url, $repositoryUrl) + { + $repository = new ComposerRepository( + array('url' => $repositoryUrl), + new NullIO(), + FactoryMock::createConfig() + ); + + $object = new \ReflectionObject($repository); + + $method = $object->getMethod('canonicalizeUrl'); + $method->setAccessible(true); + + // ComposerRepository::__construct ensures that the repository URL has a + // protocol, so reset it here in order to test all cases. + $property = $object->getProperty('url'); + $property->setAccessible(true); + $property->setValue($repository, $repositoryUrl); + + $this->assertSame($expected, $method->invoke($repository, $url)); + } + + public function canonicalizeUrlProvider() + { + return array( + array( + 'https://example.org/path/to/file', + '/path/to/file', + 'https://example.org', + ), + array( + 'https://example.org/canonic_url', + 'https://example.org/canonic_url', + 'https://should-not-see-me.test', + ), + array( + 'file:///path/to/repository/file', + '/path/to/repository/file', + 'file:///path/to/repository', + ), + array( + // Assert that the repository URL is returned unchanged if it is + // not a URL. + // (Backward compatibility test) + 'invalid_repo_url', + '/path/to/file', + 'invalid_repo_url', + ), + array( + // Assert that URLs can contain sequences resembling pattern + // references as understood by preg_replace() without messing up + // the result. + // (Regression test) + 'https://example.org/path/to/unusual_$0_filename', + '/path/to/unusual_$0_filename', + 'https://example.org', + ), + ); + } } From e7f02be9ffec80384df5d49e463d9f127d6957bc Mon Sep 17 00:00:00 2001 From: pfofi <7479939+pfofi@users.noreply.github.com> Date: Sat, 11 May 2019 16:27:39 +0200 Subject: [PATCH 2/7] Anchor pattern --- src/Composer/Repository/ComposerRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 1b03885fe..8fc40c812 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -562,7 +562,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito protected function canonicalizeUrl($url) { if ('/' === $url[0]) { - if (preg_match('{[^:]+://[^/]*}', $this->url, $matches)) { + if (preg_match('{^[^:]+://[^/]*}', $this->url, $matches)) { return $matches[0] . $url; } From faa7c5eea2de7e053f38c0726c01147531687361 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 19 May 2019 20:52:53 +0200 Subject: [PATCH 3/7] Allow overriding self-update target file with envvar COMPOSER_SELF_UPDATE_TARGET Useful if Composer is provided on a read-only filesystems, to allow self-update to work with a different destination --- src/Composer/Command/SelfUpdateCommand.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Composer/Command/SelfUpdateCommand.php b/src/Composer/Command/SelfUpdateCommand.php index 78b27460e..226aafeb5 100644 --- a/src/Composer/Command/SelfUpdateCommand.php +++ b/src/Composer/Command/SelfUpdateCommand.php @@ -351,6 +351,10 @@ TAGSPUBKEY @copy($localFilename, $backupTarget); } + if ($targetFilename = getenv('COMPOSER_SELF_UPDATE_TARGET')) { + $localFilename = realpath($targetFilename) ?: $targetFilename; + } + rename($newFilename, $localFilename); return null; From bd6b758a1be2ffd722690e27e83a0ab685a06d37 Mon Sep 17 00:00:00 2001 From: Rob Bast Date: Wed, 29 May 2019 08:45:05 +0200 Subject: [PATCH 4/7] fixes #8159 expand interface and add missing methods to aliaspackage --- src/Composer/Package/AliasPackage.php | 10 ++++++++ src/Composer/Package/PackageInterface.php | 28 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Composer/Package/AliasPackage.php b/src/Composer/Package/AliasPackage.php index 09ed4fb9b..89f197856 100644 --- a/src/Composer/Package/AliasPackage.php +++ b/src/Composer/Package/AliasPackage.php @@ -401,4 +401,14 @@ class AliasPackage extends BasePackage implements CompletePackageInterface { return parent::__toString().' (alias of '.$this->aliasOf->getVersion().')'; } + + public function setDistUrl($url) + { + return $this->aliasOf->setDistUrl($url); + } + + public function setDistType($type) + { + return $this->aliasOf->setDistType($type); + } } diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index 73d2ade41..cb16efa7e 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -358,4 +358,32 @@ interface PackageInterface * @return array */ public function getTransportOptions(); + + /** + * @param string $reference + * + * @return void + */ + public function setSourceReference($reference); + + /** + * @param string $url + * + * @return void + */ + public function setDistUrl($url); + + /** + * @param string $type + * + * @return void + */ + public function setDistType($type); + + /** + * @param string $reference + * + * @return void + */ + public function setDistReference($reference); } From 82825ccc74b977a86010dc78a80502e0dd5dc5dd Mon Sep 17 00:00:00 2001 From: pfofi <7479939+pfofi@users.noreply.github.com> Date: Fri, 7 Jun 2019 09:13:11 +0200 Subject: [PATCH 5/7] Use possessive quantifiers --- src/Composer/Repository/ComposerRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 8fc40c812..9d5b727cc 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -562,7 +562,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito protected function canonicalizeUrl($url) { if ('/' === $url[0]) { - if (preg_match('{^[^:]+://[^/]*}', $this->url, $matches)) { + if (preg_match('{^[^:]++://[^/]*+}', $this->url, $matches)) { return $matches[0] . $url; } From 088fb56c3d6f1264760d495d40edf7569ee83068 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 7 Jun 2019 16:27:40 +0200 Subject: [PATCH 6/7] Fix display of HHVM warning appearing when HHVM is not in use, fixes #8138 --- src/Composer/DependencyResolver/Problem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/DependencyResolver/Problem.php b/src/Composer/DependencyResolver/Problem.php index 073f64e2d..c7e529889 100644 --- a/src/Composer/DependencyResolver/Problem.php +++ b/src/Composer/DependencyResolver/Problem.php @@ -106,7 +106,7 @@ class Problem $msg = "\n - This package requires ".$job['packageName'].$this->constraintToText($job['constraint']).' but '; - if (defined('HHVM_VERSION') || count($available)) { + if (defined('HHVM_VERSION') || (count($available) && $job['packageName'] === 'hhvm')) { return $msg . 'your HHVM version does not satisfy that requirement.'; } From e7eecc6901698ea352bff11ccabe5a1b6a6122c6 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 7 Jun 2019 16:49:07 +0200 Subject: [PATCH 7/7] Add docs for COMPOSER_SELF_UPDATE_TARGET, refs #8151 --- doc/03-cli.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/03-cli.md b/doc/03-cli.md index 6460e9e1d..5fc527c49 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -917,6 +917,10 @@ if you use Composer as super user at all times like in docker containers. If set, the value is used as php's memory_limit. +### COMPOSER_SELF_UPDATE_TARGET + +If set, makes the self-update command write the new Composer phar file into that path instead of overwriting itself. Useful for updating Composer on read-only filesystem. + ### COMPOSER_MIRROR_PATH_REPOS If set to 1, this env changes the default path repository strategy to `mirror` instead