Skip to content

Commit

Permalink
Merge branch '2.3' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Seldaek committed May 25, 2022
2 parents b2006fb + 5b067a1 commit d971f2e
Show file tree
Hide file tree
Showing 25 changed files with 127 additions and 46 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Expand Up @@ -71,6 +71,15 @@
* Fixed symlink creation in linux VM guest filesystems to be recognized by Windows (#10592)
* Performance improvement in pool optimization step (#10585)

### [2.2.13] 2022-05-25

* Fixed invalid credentials loop when setting up GitLab token (#10748)
* Fixed PHP 8.2 deprecations (#10766)
* Fixed lock file changes being output even when the lock file creation is disabled
* Fixed race condition when multiple requests asking for auth on the same hostname fired concurrently (#10763)
* Fixed quoting of commas on Windows (#10775)
* Fixed issue installing path repos with a disabled symlink function (#10786)

### [2.2.12] 2022-04-13

* Security: Fixed command injection vulnerability in HgDriver/GitDriver (GHSA-x7cr-6qr6-2hh6 / CVE-2022-24828)
Expand Down Expand Up @@ -1508,6 +1517,7 @@
[2.3.0]: https://github.com/composer/composer/compare/2.3.0-RC2...2.3.0
[2.3.0-RC2]: https://github.com/composer/composer/compare/2.3.0-RC1...2.3.0-RC2
[2.3.0-RC1]: https://github.com/composer/composer/compare/2.2.9...2.3.0-RC1
[2.2.13]: https://github.com/composer/composer/compare/2.2.12...2.2.13
[2.2.12]: https://github.com/composer/composer/compare/2.2.11...2.2.12
[2.2.11]: https://github.com/composer/composer/compare/2.2.10...2.2.11
[2.2.10]: https://github.com/composer/composer/compare/2.2.9...2.2.10
Expand Down
36 changes: 18 additions & 18 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion phpstan/baseline.neon
Expand Up @@ -2167,7 +2167,7 @@ parameters:

-
message: "#^Call to function in_array\\(\\) with arguments 20, array\\{0\\: 10\\|20, 1\\?\\: 20\\} and true will always evaluate to true\\.$#"
count: 1
count: 2
path: ../src/Composer/Downloader/PathDownloader.php

-
Expand Down
2 changes: 1 addition & 1 deletion res/composer-schema.json
Expand Up @@ -6,7 +6,7 @@
"name": {
"type": "string",
"description": "Package name, including 'vendor-name/' prefix.",
"pattern": "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$"
"pattern": "^[a-z0-9]([_.-]?[a-z0-9]++)*+/[a-z0-9](([_.]|-{1,2})?[a-z0-9]++)*+$"
},
"description": {
"type": "string",
Expand Down
2 changes: 1 addition & 1 deletion src/Composer/Command/ArchiveCommand.php
Expand Up @@ -159,7 +159,7 @@ protected function selectPackage(IOInterface $io, string $packageName, ?string $
$localRepo = $composer->getRepositoryManager()->getLocalRepository();
$repo = new CompositeRepository(array_merge(array($localRepo), $composer->getRepositoryManager()->getRepositories()));
} else {
$defaultRepos = RepositoryFactory::defaultRepos($this->getIO());
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
$io->writeError('No composer.json found in the current directory, searching packages from ' . implode(', ', array_keys($defaultRepos)));
$repo = new CompositeRepository($defaultRepos);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Composer/Command/BaseDependencyCommand.php
Expand Up @@ -18,6 +18,7 @@
use Composer\Package\RootPackage;
use Composer\Repository\InstalledArrayRepository;
use Composer\Repository\CompositeRepository;
use Composer\Repository\RepositoryInterface;
use Composer\Repository\RootPackageRepository;
use Composer\Repository\InstalledRepository;
use Composer\Repository\PlatformRepository;
Expand Down Expand Up @@ -80,7 +81,7 @@ protected function doExecute(InputInterface $input, OutputInterface $output, boo
// If the version we ask for is not installed then we need to locate it in remote repos and add it.
// This is needed for why-not to resolve conflicts from an uninstalled version against installed packages.
if (!$installedRepo->findPackage($needle, $textConstraint)) {
$defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO()));
$defaultRepos = new CompositeRepository(RepositoryFactory::defaultRepos($this->getIO(), $composer->getConfig(), $composer->getRepositoryManager()));
if ($match = $defaultRepos->findPackage($needle, $textConstraint)) {
$installedRepo->addRepository(new InstalledArrayRepository(array(clone $match)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Composer/Command/HomeCommand.php
Expand Up @@ -170,6 +170,6 @@ private function initializeRepos(): array
);
}

return RepositoryFactory::defaultRepos($this->getIO());
return RepositoryFactory::defaultReposWithDefaultManager($this->getIO());
}
}
7 changes: 5 additions & 2 deletions src/Composer/Command/InitCommand.php
Expand Up @@ -225,6 +225,9 @@ protected function interact(InputInterface $input, OutputInterface $output)
$repositories = $input->getOption('repository');
if (count($repositories) > 0) {
$config = Factory::createConfig($io);
$io->loadConfiguration($config);
$repoManager = RepositoryFactory::manager($io, $config);

$repos = array(new PlatformRepository);
$createDefaultPackagistRepo = true;
foreach ($repositories as $repo) {
Expand All @@ -236,14 +239,14 @@ protected function interact(InputInterface $input, OutputInterface $output)
$createDefaultPackagistRepo = false;
continue;
}
$repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig);
$repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig, $repoManager);
}

if ($createDefaultPackagistRepo) {
$repos[] = RepositoryFactory::createRepo($io, $config, array(
'type' => 'composer',
'url' => 'https://repo.packagist.org',
));
), $repoManager);
}

$this->repos = new CompositeRepository($repos);
Expand Down
2 changes: 1 addition & 1 deletion src/Composer/Command/PackageDiscoveryTrait.php
Expand Up @@ -47,7 +47,7 @@ protected function getRepos(): CompositeRepository
if (null === $this->repos) {
$this->repos = new CompositeRepository(array_merge(
array(new PlatformRepository),
RepositoryFactory::defaultRepos($this->getIO())
RepositoryFactory::defaultReposWithDefaultManager($this->getIO())
));
}

Expand Down
4 changes: 2 additions & 2 deletions src/Composer/Command/ShowCommand.php
Expand Up @@ -194,7 +194,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$repos = new CompositeRepository($composer->getRepositoryManager()->getRepositories());
$installedRepo->addRepository($composer->getRepositoryManager()->getLocalRepository());
} else {
$defaultRepos = RepositoryFactory::defaultRepos($io);
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
$repos = new CompositeRepository($defaultRepos);
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
}
Expand All @@ -209,7 +209,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
$repos = new CompositeRepository(array_merge(array(new FilterRepository($installedRepo, array('canonical' => false))), $composer->getRepositoryManager()->getRepositories()));
} elseif ($input->getOption('all')) {
$defaultRepos = RepositoryFactory::defaultRepos($io);
$defaultRepos = RepositoryFactory::defaultReposWithDefaultManager($io);
$io->writeError('No composer.json found in the current directory, showing available packages from ' . implode(', ', array_keys($defaultRepos)));
$installedRepo = new InstalledRepository(array($platformRepo));
$repos = new CompositeRepository(array_merge(array($installedRepo), $defaultRepos));
Expand Down
3 changes: 2 additions & 1 deletion src/Composer/Console/Application.php
Expand Up @@ -135,7 +135,8 @@ public function doRun(InputInterface $input, OutputInterface $output): int
$this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins');
$this->disableScriptsByDefault = $input->hasParameterOption('--no-scripts');

if (Platform::getEnv('COMPOSER_NO_INTERACTION') || !Platform::isTty(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'))) {
$stdin = defined('STDIN') ? STDIN : fopen('php://stdin', 'r');
if (Platform::getEnv('COMPOSER_NO_INTERACTION') || $stdin === false || !Platform::isTty($stdin)) {
$input->setInteractive(false);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Composer/DependencyResolver/RuleSetIterator.php
Expand Up @@ -75,7 +75,7 @@ public function next(): void
}

$this->currentType = $this->types[$this->currentTypeOffset];
} while (isset($this->types[$this->currentTypeOffset]) && !\count($this->rules[$this->currentType]));
} while (0 === \count($this->rules[$this->currentType]));
}
}

Expand All @@ -95,7 +95,7 @@ public function rewind(): void
}

$this->currentType = $this->types[$this->currentTypeOffset];
} while (isset($this->types[$this->currentTypeOffset]) && !\count($this->rules[$this->currentType]));
} while (0 === \count($this->rules[$this->currentType]));
}

public function valid(): bool
Expand Down
9 changes: 9 additions & 0 deletions src/Composer/Downloader/PathDownloader.php
Expand Up @@ -280,6 +280,15 @@ private function computeAllowedStrategies(array $transportOptions): array
$allowedStrategies = array(self::STRATEGY_MIRROR);
}

// Check we can use symlink() otherwise
if (!Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !function_exists('symlink')) {
if (!in_array(self::STRATEGY_MIRROR, $allowedStrategies, true)) {
throw new \RuntimeException('Your PHP has the symlink() function disabled which does not allow Composer to use symlinks and this path repository has symlink:true in its options so copying is not allowed');
}
$currentStrategy = self::STRATEGY_MIRROR;
$allowedStrategies = array(self::STRATEGY_MIRROR);
}

return array($currentStrategy, $allowedStrategies);
}

Expand Down
1 change: 0 additions & 1 deletion src/Composer/Package/BasePackage.php
Expand Up @@ -53,7 +53,6 @@ abstract class BasePackage implements PackageInterface
* READ-ONLY: The package id, public for fast access in dependency solver
* @var int
* @internal
* @readonly
*/
public $id;
/** @var string */
Expand Down
2 changes: 1 addition & 1 deletion src/Composer/Package/Loader/ValidatingArrayLoader.php
Expand Up @@ -456,7 +456,7 @@ public static function hasPackageNamingError(string $name, bool $isLink = false)
return null;
}

if (!Preg::isMatch('{^[a-z0-9](?:[_.-]?[a-z0-9]+)*/[a-z0-9](?:(?:[_.]?|-{0,2})[a-z0-9]+)*$}iD', $name)) {
if (!Preg::isMatch('{^[a-z0-9](?:[_.-]?[a-z0-9]++)*+/[a-z0-9](?:(?:[_.]|-{1,2})?[a-z0-9]++)*+$}iD', $name)) {
return $name.' is invalid, it should have a vendor name, a forward slash, and a package name. The vendor and package name can be words separated by -, . or _. The complete name should match "^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$".';
}

Expand Down
37 changes: 31 additions & 6 deletions src/Composer/Repository/RepositoryFactory.php
Expand Up @@ -80,7 +80,8 @@ public static function fromString(IOInterface $io, Config $config, string $repos
public static function createRepo(IOInterface $io, Config $config, array $repoConfig, RepositoryManager $rm = null): RepositoryInterface
{
if (!$rm) {
$rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config));
@trigger_error('Not passing a repository manager when calling createRepo is deprecated since Composer 2.3.6', E_USER_DEPRECATED);
$rm = static::manager($io, $config);
}
$repos = self::createRepos($rm, array($repoConfig));

Expand All @@ -95,14 +96,18 @@ public static function createRepo(IOInterface $io, Config $config, array $repoCo
*/
public static function defaultRepos(IOInterface $io = null, Config $config = null, RepositoryManager $rm = null): array
{
if (!$config) {
if (null === $rm) {
@trigger_error('Not passing a repository manager when calling defaultRepos is deprecated since Composer 2.3.6, use defaultReposWithDefaultManager() instead if you cannot get a manager.', E_USER_DEPRECATED);
}

if (null === $config) {
$config = Factory::createConfig($io);
}
if ($io) {
if (null !== $io) {
$io->loadConfiguration($config);
}
if (!$rm) {
if (!$io) {
if (null === $rm) {
if (null === $io) {
throw new \InvalidArgumentException('This function requires either an IOInterface or a RepositoryManager');
}
$rm = static::manager($io, $config, Factory::createHttpDownloader($io, $config));
Expand All @@ -118,8 +123,16 @@ public static function defaultRepos(IOInterface $io = null, Config $config = nul
* @param HttpDownloader $httpDownloader
* @return RepositoryManager
*/
public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null): RepositoryManager
public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader = null, EventDispatcher $eventDispatcher = null, ProcessExecutor $process = null): RepositoryManager
{
if ($httpDownloader === null) {
$httpDownloader = Factory::createHttpDownloader($io, $config);
}
if ($process === null) {
$process = new ProcessExecutor($io);
$process->enableAsync();
}

$rm = new RepositoryManager($io, $config, $httpDownloader, $eventDispatcher, $process);
$rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
$rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
Expand All @@ -140,6 +153,18 @@ public static function manager(IOInterface $io, Config $config, HttpDownloader $
return $rm;
}

/**
* @return RepositoryInterface[]
*/
public static function defaultReposWithDefaultManager(IOInterface $io): array
{
$manager = RepositoryFactory::manager($io, $config = Factory::createConfig($io));
$io->loadConfiguration($config);

return RepositoryFactory::defaultRepos($io, $config, $manager);
}


/**
* @param array<int|string, mixed> $repoConfigs
*
Expand Down
7 changes: 7 additions & 0 deletions src/Composer/Repository/Vcs/GitHubDriver.php
Expand Up @@ -295,6 +295,13 @@ public function getFileContent(string $file, string $identifier): ?string

$resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier);
$resource = $this->getContents($resource)->decodeJson();

// The GitHub contents API only returns files up to 1MB as base64 encoded files
// larger files either need be fetched with a raw accept header or by using the git blob endpoint
if ((!isset($resource['content']) || $resource['content'] === '') && $resource['encoding'] === 'none' && isset($resource['git_url'])) {
$resource = $this->getContents($resource['git_url'])->decodeJson();
}

if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) {
throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier);
}
Expand Down

0 comments on commit d971f2e

Please sign in to comment.