diff --git a/phpstan/config.neon b/phpstan/config.neon index 2b26f4709..d3283e61b 100644 --- a/phpstan/config.neon +++ b/phpstan/config.neon @@ -1,14 +1,32 @@ parameters: + level: 1 autoload_files: - autoload.php - level: 0 excludes_analyse: - '../tests/Composer/Test/Fixtures/*' - '../tests/Composer/Test/Autoload/Fixtures/*' - '../tests/Composer/Test/Plugin/Fixtures/*' ignoreErrors: + # unused parameters + - '~^Constructor of class Composer\\Repository\\VcsRepository has an unused parameter \$dispatcher\.$~' + - '~^Constructor of class Composer\\Repository\\PearRepository has an unused parameter \$dispatcher\.$~' + - '~^Constructor of class Composer\\Util\\Http\\CurlDownloader has an unused parameter \$disableTls\.$~' + - '~^Constructor of class Composer\\Util\\Http\\CurlDownloader has an unused parameter \$options\.$~' + - '~^Constructor of class Composer\\Repository\\PearRepository has an unused parameter \$config\.$~' + # ion cube is not installed - '~^Function ioncube_loader_\w+ not found\.$~' + # rar is not installed + - '~^Call to static method open\(\) on an unknown class RarArchive\.$~' + # imagick is not installed + - '~^Instantiated class Imagick not found\.$~' + # windows specific constants + - + message: '~^Constant PHP_WINDOWS_VERSION_MAJOR not found\.$~' + path: '*/src/Composer/Downloader/PathDownloader.php' + - + message: '~^Constant PHP_WINDOWS_VERSION_MINOR not found\.$~' + path: '*/src/Composer/Downloader/PathDownloader.php' # variables from global scope - '~^Undefined variable: \$vendorDir$~' diff --git a/src/Composer/Command/DiagnoseCommand.php b/src/Composer/Command/DiagnoseCommand.php index b2b08e6f0..80e6f8423 100644 --- a/src/Composer/Command/DiagnoseCommand.php +++ b/src/Composer/Command/DiagnoseCommand.php @@ -634,6 +634,9 @@ EOT $text = PHP_EOL."The openssl extension is missing, which means that secure HTTPS transfers are impossible.".PHP_EOL; $text .= "If possible you should enable it or recompile php with --with-openssl"; break; + + default: + throw new \InvalidArgumentException(sprintf("DiagnoseCommand: Unknown error type \"%s\". Please report at https://github.com/composer/composer/issues/new.", $error)); } $out($text, 'error'); } @@ -698,6 +701,9 @@ EOT $text = "The Windows OneDrive folder is not supported on PHP versions below 7.2.23 and 7.3.10.".PHP_EOL; $text .= "Upgrade your PHP ({$current}) to use this location with Composer.".PHP_EOL; break; + + default: + throw new \InvalidArgumentException(sprintf("DiagnoseCommand: Unknown warning type \"%s\". Please report at https://github.com/composer/composer/issues/new.", $warning)); } $out($text, 'comment'); } diff --git a/src/Composer/DependencyResolver/DefaultPolicy.php b/src/Composer/DependencyResolver/DefaultPolicy.php index 859410752..3fdb4438b 100644 --- a/src/Composer/DependencyResolver/DefaultPolicy.php +++ b/src/Composer/DependencyResolver/DefaultPolicy.php @@ -47,9 +47,9 @@ class DefaultPolicy implements PolicyInterface public function selectPreferredPackages(Pool $pool, array $literals, $requiredPackage = null) { $packages = $this->groupLiteralsByName($pool, $literals); + $policy = $this; foreach ($packages as &$nameLiterals) { - $policy = $this; usort($nameLiterals, function ($a, $b) use ($policy, $pool, $requiredPackage) { return $policy->compareByPriority($pool, $pool->literalToPackage($a), $pool->literalToPackage($b), $requiredPackage, true); }); diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index bce1b7133..9e0e2d2bf 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -362,6 +362,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface $this->io = new NullIO; $this->io->loadConfiguration($this->config); $e = null; + $output = ''; try { $res = $this->download($package, $targetDir.'_compare', null, false); diff --git a/src/Composer/Json/JsonManipulator.php b/src/Composer/Json/JsonManipulator.php index e1ee43485..d7daa4e26 100644 --- a/src/Composer/Json/JsonManipulator.php +++ b/src/Composer/Json/JsonManipulator.php @@ -356,6 +356,10 @@ class JsonManipulator $childrenClean = $children; } + if (!isset($childrenClean)) { + throw new \InvalidArgumentException("JsonManipulator: \$childrenClean is not defined. Please report at https://github.com/composer/composer/issues/new."); + } + // no child data left, $name was the only key in $this->pregMatch('#^{ \s*? (?P\S+.*?)? (?P\s*) }$#sx', $childrenClean, $match); if (empty($match['content'])) { diff --git a/src/Composer/Package/Loader/JsonLoader.php b/src/Composer/Package/Loader/JsonLoader.php index a693e70c0..f8c6e8c88 100644 --- a/src/Composer/Package/Loader/JsonLoader.php +++ b/src/Composer/Package/Loader/JsonLoader.php @@ -38,6 +38,11 @@ class JsonLoader $config = JsonFile::parseJson(file_get_contents($json), $json); } elseif (is_string($json)) { $config = JsonFile::parseJson($json); + } else { + throw new \InvalidArgumentException(sprintf( + "JsonLoader: Unknown \$json parameter %s. Please report at https://github.com/composer/composer/issues/new.", + gettype($json) + )); } return $this->loader->load($config); diff --git a/src/Composer/Package/Package.php b/src/Composer/Package/Package.php index c633e1856..6fdba9b42 100644 --- a/src/Composer/Package/Package.php +++ b/src/Composer/Package/Package.php @@ -616,6 +616,8 @@ class Package extends BasePackage $mirrorUrl = ComposerMirror::processGitUrl($mirror['url'], $this->name, $url, $type); } elseif ($urlType === 'source' && $type === 'hg') { $mirrorUrl = ComposerMirror::processHgUrl($mirror['url'], $this->name, $url, $type); + } else { + continue; } if (!in_array($mirrorUrl, $urls)) { $func = $mirror['preferred'] ? 'array_unshift' : 'array_push'; diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index b6373dfb6..8ba4b8b8c 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -1078,6 +1078,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } } + if (!isset($data)) { + throw new \LogicException("ComposerRepository: Undefined \$data. Please report at https://github.com/composer/composer/issues/new."); + } + return $data; } diff --git a/src/Composer/Repository/Vcs/GitLabDriver.php b/src/Composer/Repository/Vcs/GitLabDriver.php index 6e98c838f..8f0ed6f0f 100644 --- a/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/src/Composer/Repository/Vcs/GitLabDriver.php @@ -366,13 +366,13 @@ class GitLabDriver extends VcsDriver protected function attemptCloneFallback() { - try { - if ($this->isPrivate === false) { - $url = $this->generatePublicUrl(); - } else { - $url = $this->generateSshUrl(); - } + if ($this->isPrivate === false) { + $url = $this->generatePublicUrl(); + } else { + $url = $this->generateSshUrl(); + } + try { // If this repository may be private and we // cannot ask for authentication credentials (because we // are not interactive) then we fallback to GitDriver. diff --git a/src/Composer/Util/AuthHelper.php b/src/Composer/Util/AuthHelper.php index 81eb49020..15a2a9e00 100644 --- a/src/Composer/Util/AuthHelper.php +++ b/src/Composer/Util/AuthHelper.php @@ -161,9 +161,10 @@ class AuthHelper if (!$this->io->isInteractive()) { if ($statusCode === 401) { $message = "The '" . $url . "' URL required authentication.\nYou must be using the interactive console to authenticate"; - } - if ($statusCode === 403) { + } elseif ($statusCode === 403) { $message = "The '" . $url . "' URL could not be accessed: " . $reason; + } else { + $message = "Unknown error code '" . $statusCode . "', reason: " . $reason; } throw new TransportException($message, $statusCode); diff --git a/src/Composer/Util/ConfigValidator.php b/src/Composer/Util/ConfigValidator.php index e1200fee1..98a6016f2 100644 --- a/src/Composer/Util/ConfigValidator.php +++ b/src/Composer/Util/ConfigValidator.php @@ -171,8 +171,8 @@ class ConfigValidator $warnings[] = "Defining autoload.psr-4 with an empty namespace prefix is a bad idea for performance"; } + $loader = new ValidatingArrayLoader(new ArrayLoader(), true, null, $arrayLoaderValidationFlags); try { - $loader = new ValidatingArrayLoader(new ArrayLoader(), true, null, $arrayLoaderValidationFlags); if (!isset($manifest['version'])) { $manifest['version'] = '1.0.0'; } diff --git a/src/Composer/Util/Git.php b/src/Composer/Util/Git.php index 91da871da..00e36830e 100644 --- a/src/Composer/Util/Git.php +++ b/src/Composer/Util/Git.php @@ -79,7 +79,7 @@ class Git return; } $messages[] = '- ' . $protoUrl . "\n" . preg_replace('#^#m', ' ', $this->process->getErrorOutput()); - if ($initialClone) { + if ($initialClone && isset($origCwd)) { $this->filesystem->removeDirectory($origCwd); } } @@ -238,7 +238,7 @@ class Git } } - if ($initialClone) { + if ($initialClone && isset($origCwd)) { $this->filesystem->removeDirectory($origCwd); } diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 6312deabc..c7077afbb 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -269,6 +269,7 @@ class RemoteFilesystem return true; }); + $http_response_header = array(); try { $result = $this->getRemoteContents($originUrl, $fileUrl, $ctx, $http_response_header); @@ -537,6 +538,8 @@ class RemoteFilesystem */ protected function getRemoteContents($originUrl, $fileUrl, $context, array &$responseHeaders = null) { + $result = false; + try { $e = null; $result = file_get_contents($fileUrl, false, $context); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 3c6c35de6..03d301164 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -319,7 +319,7 @@ class InstallerTest extends TestCase $output = str_replace("\r", '', $io->getOutput()); $this->assertEquals($expectResult, $result, $output . stream_get_contents($appOutput)); - if ($expectLock) { + if ($expectLock && isset($actualLock)) { unset($actualLock['hash']); unset($actualLock['content-hash']); unset($actualLock['_readme']); @@ -434,6 +434,7 @@ class InstallerTest extends TestCase ); $section = null; + $data = array(); foreach ($tokens as $i => $token) { if (null === $section && empty($token)) { continue; // skip leading blank