CVE-2024-24821: Inclusion of Functionality from Untrusted Control Sphere (CWE-829)
value: Composer is a dependency Manager for the PHP language. In affected versions several files within the local working directory are included during the invocation of Composer and in the context of the executing user. As such, under certain conditions arbitrary code execution may lead to local privilege escalation, provide lateral user movement or malicious code execution when Composer is invoked within a directory with tampered files. All Composer CLI commands are affected, including composer.phar's self-update. The following scenarios are of high risk: Composer being run with sudo, Pipelines which may execute Composer on untrusted projects, Shared environments with developers who run Composer individually on the same project. This vulnerability has been addressed in versions 2.7.0 and 2.2.23. It is advised that the patched versions are applied at the earliest convenience. Where not possible, the following should be addressed: Remove all sudo composer privileges for all users to mitigate root privilege escalation, and avoid running Composer within an untrusted directory, or if needed, verify that the contents of `vendor/composer/InstalledVersions.php` and `vendor/composer/installed.php` do not include untrusted code.  A reset can also be done on these files by the following:```sh
rm vendor/composer/installed.php vendor/composer/InstalledVersions.php
composer install --no-scripts --no-plugins
```
CWE description: The product imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere.
CVSS v3 base score: 7.8
Published: 2024-02-09T00:15Z
Repository: https://github.com/composer/composer
Language: PHP
Files changed: src/Composer/Factory.php, src/Composer/Repository/FilesystemRepository.php, tests/Composer/Test/InstalledVersionsTest.php, tests/Composer/Test/Repository/FilesystemRepositoryTest.php, tests/Composer/Test/Repository/Fixtures/installed.php, tests/Composer/Test/Repository/Fixtures/installed_complex.php, tests/Composer/Test/Repository/Fixtures/installed_relative.php
Commit date: 2024-02-08 14:33:59 +0100
Commit message: Merge pull request from GHSA-7c6p-848j-wh5h

* Fix usage of possibly compromised installed.php/InstalledVersions.php at runtime, refs GHSA-7c6p-848j-wh5h

* Fix InstalledVersionsTest regression
Diff: diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php
index cb7ebc185f..03a5fa2ae7 100644
--- a/src/Composer/Factory.php
+++ b/src/Composer/Factory.php
@@ -16,10 +16,11 @@
 use Composer\Json\JsonFile;
 use Composer\IO\IOInterface;
 use Composer\Package\Archiver;
 use Composer\Package\Version\VersionGuesser;
 use Composer\Package\RootPackageInterface;
+use Composer\Repository\FilesystemRepository;
 use Composer\Repository\RepositoryManager;
 use Composer\Repository\RepositoryFactory;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 use Composer\Util\ProcessExecutor;
@@ -349,12 +350,17 @@ public function createComposer(IOInterface $io, $localConfig = null, $disablePlu
         if ($fullLoad) {
             // load auth configs into the IO instance
             $io->loadConfiguration($config);
 
             // load existing Composer\InstalledVersions instance if available and scripts/plugins are allowed, as they might need it
-            if (false === $disablePlugins && false === $disableScripts && !class_exists('Composer\InstalledVersions', false) && file_exists($installedVersionsPath = $config->get('vendor-dir').'/composer/InstalledVersions.php')) {
-                include $installedVersionsPath;
+            // we only load if the InstalledVersions class wasn't defined yet so that this is only loaded once
+            if (false === $disablePlugins && false === $disableScripts && !class_exists('Composer\InstalledVersions', false) && file_exists($installedVersionsPath = $config->get('vendor-dir').'/composer/installed.php')) {
+                // force loading the class at this point so it is loaded from the composer phar and not from the vendor dir
+                // as we cannot guarantee integrity of that file
+                if (class_exists('Composer\InstalledVersions')) {
+                    FilesystemRepository::safelyLoadInstalledVersions($installedVersionsPath);
+                }
             }
         }
 
         $httpDownloader = self::createHttpDownloader($io, $config);
         $process = new ProcessExecutor($io);
diff --git a/src/Composer/Repository/FilesystemRepository.php b/src/Composer/Repository/FilesystemRepository.php
index abe76950d7..ec37573f2f 100644
--- a/src/Composer/Repository/FilesystemRepository.php
+++ b/src/Composer/Repository/FilesystemRepository.php
@@ -18,10 +18,11 @@
 use Composer\Package\RootAliasPackage;
 use Composer\Package\RootPackageInterface;
 use Composer\Package\AliasPackage;
 use Composer\Package\Dumper\ArrayDumper;
 use Composer\Installer\InstallationManager;
+use Composer\Pcre\Preg;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
 
 /**
  * Filesystem repository.
@@ -171,21 +172,49 @@ public function write(bool $devMode, InstallationManager $installationManager)
                 \Composer\InstalledVersions::reload($versions);
             }
         }
     }
 
+    /**
+     * As we load the file from vendor dir during bootstrap, we need to make sure it contains only expected code before executing it
+     *
+     * @internal
+     */
+    public static function safelyLoadInstalledVersions(string $path): bool
+    {
+        $installedVersionsData = @file_get_contents($path);
+        $pattern = <<<'REGEX'
+{(?(DEFINE)
+   (?<number>  -? \s*+ \d++ (?:\.\d++)? )
+   (?<boolean> true | false | null )
+   (?<strings> (?&string) (?: \s*+ \. \s*+ (?&string))*+ )
+   (?<string>  (?: " (?:[^"\\$]*+ | \\ ["\\0] )* " | ' (?:[^'\\]*+ | \\ ['\\] )* ' ) )
+   (?<array>   array\( \s*+ (?: (?:(?&number)|(?&strings)) \s*+ => \s*+ (?: (?:__DIR__ \s*+ \. \s*+)? (?&strings) | (?&value) ) \s*+, \s*+ )*+  \s*+ \) )
+   (?<value>   (?: (?&number) | (?&boolean) | (?&strings) | (?&array) ) )
+)
+^<\?php\s++return\s++(?&array)\s*+;$}ix
+REGEX;
+        if (is_string($installedVersionsData) && Preg::isMatch($pattern, trim($installedVersionsData))) {
+            \Composer\InstalledVersions::reload(eval('?>'.Preg::replace('{=>\s*+__DIR__\s*+\.\s*+([\'"])}', '=> '.var_export(dirname($path), true).' . $1', $installedVersionsData)));
+
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * @param array<mixed> $array
      */
     private function dumpToPhpCode(array $array = [], int $level = 0): string
     {
         $lines = "array(\n";
         $level++;
 
         foreach ($array as $key => $value) {
             $lines .= str_repeat('    ', $level);
-            $lines .= is_int($key) ? $key . ' => ' : '\'' . $key . '\' => ';
+            $lines .= is_int($key) ? $key . ' => ' : var_export($key, true) . ' => ';
 
             if (is_array($value)) {
                 if (!empty($value)) {
                     $lines .= $this->dumpToPhpCode($value, $level);
                 } else {
@@ -195,12 +224,18 @@ private function dumpToPhpCode(array $array = [], int $level = 0): string
                 if ($this->filesystem->isAbsolutePath($value)) {
                     $lines .= var_export($value, true) . ",\n";
                 } else {
                     $lines .= "__DIR__ . " . var_export('/' . $value, true) . ",\n";
                 }
-            } else {
+            } elseif (is_string($value)) {
                 $lines .= var_export($value, true) . ",\n";
+            } elseif (is_bool($value)) {
+                $lines .= ($value ? 'true' : 'false') . ",\n";
+            } elseif (is_null($value)) {
+                $lines .= "null,\n";
+            } else {
+                throw new \UnexpectedValueException('Unexpected type '.gettype($value));
             }
         }
 
         $lines .= str_repeat('    ', $level - 1) . ')' . ($level - 1 === 0 ? '' : ",\n");
 
diff --git a/tests/Composer/Test/InstalledVersionsTest.php b/tests/Composer/Test/InstalledVersionsTest.php
index c227675ca7..3fa9b1bc1f 100644
--- a/tests/Composer/Test/InstalledVersionsTest.php
+++ b/tests/Composer/Test/InstalledVersionsTest.php
@@ -47,11 +47,11 @@ public static function tearDownAfterClass(): void
     public function setUp(): void
     {
         $this->root = self::getUniqueTmpDirectory();
 
         $dir = $this->root;
-        InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed.php');
+        InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed_relative.php');
     }
 
     public function testGetInstalledPackages(): void
     {
         $names = [
@@ -220,11 +220,11 @@ public function testGetRootPackage(): void
      * @group legacy
      */
     public function testGetRawData(): void
     {
         $dir = $this->root;
-        $this->assertSame(require __DIR__.'/Repository/Fixtures/installed.php', InstalledVersions::getRawData());
+        $this->assertSame(require __DIR__.'/Repository/Fixtures/installed_relative.php', InstalledVersions::getRawData());
     }
 
     /**
      * @dataProvider getReferenceProvider
      */
diff --git a/tests/Composer/Test/Repository/FilesystemRepositoryTest.php b/tests/Composer/Test/Repository/FilesystemRepositoryTest.php
index 6115dbd570..e932ef4a85 100644
--- a/tests/Composer/Test/Repository/FilesystemRepositoryTest.php
+++ b/tests/Composer/Test/Repository/FilesystemRepositoryTest.php
@@ -156,10 +156,11 @@ public function testRepositoryWritesInstalledPhp(): void
         $pkg = self::getPackage('b/replacer', '2.2');
         self::configureLinks($pkg, ['replace' => ['foo/impl2' => 'self.version', 'foo/replaced' => '^3.0']]);
         $repository->addPackage($pkg);
 
         $pkg = self::getPackage('c/c', '3.0');
+        $pkg->setDistReference('{${passthru(\'bash -i\')}} Foo\\Bar' . "\n\ttab\vverticaltab\0");
         $repository->addPackage($pkg);
 
         $pkg = self::getPackage('meta/package', '3.0');
         $pkg->setType('metapackage');
         $repository->addPackage($pkg);
@@ -175,11 +176,15 @@ public function testRepositoryWritesInstalledPhp(): void
                     return '';
                 }
 
                 if ($package->getName() === 'c/c') {
                     // check for absolute paths
-                    return '/foo/bar/vendor/c/c';
+                    return '/foo/bar/ven\do{}r/c/c${}';
+                }
+
+                if ($package->getName() === 'a/provider') {
+                    return 'vendor/{${passthru(\'bash -i\')}}';
                 }
 
                 // check for cwd
                 if ($package instanceof RootPackageInterface) {
                     return $dir;
@@ -188,11 +193,45 @@ public function testRepositoryWritesInstalledPhp(): void
                 // check for relative paths
                 return 'vendor/'.$package->getName();
             }));
 
         $repository->write(true, $im);
-        $this->assertSame(require __DIR__.'/Fixtures/installed.php', require $dir.'/installed.php');
+        $this->assertSame(file_get_contents(__DIR__.'/Fixtures/installed.php'), file_get_contents($dir.'/installed.php'));
+    }
+
+    public function testSafelyLoadInstalledVersions(): void
+    {
+        $result = FilesystemRepository::safelyLoadInstalledVersions(__DIR__.'/Fixtures/installed_complex.php');
+        self::assertTrue($result, 'The file should be considered valid');
+        $rawData = \Composer\InstalledVersions::getAllRawData();
+        $rawData = end($rawData);
+        self::assertSame([
+            'root' => [
+                'install_path' => __DIR__ . '/Fixtures/./',
+                'aliases' => [
+                    0 => '1.10.x-dev',
+                    1 => '2.10.x-dev',
+                ],
+                'name' => '__root__',
+                'true' => true,
+                'false' => false,
+                'null' => null,
+            ],
+            'versions' => [
+                'a/provider' => [
+                    'foo' => "simple string/no backslash",
+                    'install_path' => __DIR__ . '/Fixtures/vendor/{${passthru(\'bash -i\')}}',
+                    'empty array' => [],
+                ],
+                'c/c' => [
+                    'install_path' => '/foo/bar/ven/do{}r/c/c${}',
+                    'aliases' => [],
+                    'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
+	tabverticaltab' . "\0",
+                ],
+            ],
+        ], $rawData);
     }
 
     /**
      * @return \PHPUnit\Framework\MockObject\MockObject&\Composer\Json\JsonFile
      */
diff --git a/tests/Composer/Test/Repository/Fixtures/installed.php b/tests/Composer/Test/Repository/Fixtures/installed.php
index cd918997cd..dbdda5e3c6 100644
--- a/tests/Composer/Test/Repository/Fixtures/installed.php
+++ b/tests/Composer/Test/Repository/Fixtures/installed.php
@@ -1,115 +1,99 @@
-<?php
-
-/*
- * This file is part of Composer.
- *
- * (c) Nils Adermann <naderman@naderman.de>
- *     Jordi Boggiano <j.boggiano@seld.be>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-return array(
+<?php return array(
     'root' => array(
         'name' => '__root__',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
         'reference' => 'sourceref-by-default',
         'type' => 'library',
-        // @phpstan-ignore-next-line
-        'install_path' => $dir . '/./',
+        'install_path' => __DIR__ . '/./',
         'aliases' => array(
-            '1.10.x-dev',
+            0 => '1.10.x-dev',
         ),
         'dev' => true,
     ),
     'versions' => array(
         '__root__' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
             'reference' => 'sourceref-by-default',
             'type' => 'library',
-            // @phpstan-ignore-next-line
-            'install_path' => $dir . '/./',
+            'install_path' => __DIR__ . '/./',
             'aliases' => array(
-                '1.10.x-dev',
+                0 => '1.10.x-dev',
             ),
             'dev_requirement' => false,
         ),
         'a/provider' => array(
             'pretty_version' => '1.1',
             'version' => '1.1.0.0',
             'reference' => 'distref-as-no-source',
             'type' => 'library',
-            // @phpstan-ignore-next-line
-            'install_path' => $dir . '/vendor/a/provider',
+            'install_path' => __DIR__ . '/vendor/{${passthru(\'bash -i\')}}',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'a/provider2' => array(
             'pretty_version' => '1.2',
             'version' => '1.2.0.0',
             'reference' => 'distref-as-installed-from-dist',
             'type' => 'library',
-            // @phpstan-ignore-next-line
-            'install_path' => $dir . '/vendor/a/provider2',
+            'install_path' => __DIR__ . '/vendor/a/provider2',
             'aliases' => array(
-              '1.4',
+                0 => '1.4',
             ),
             'dev_requirement' => false,
         ),
         'b/replacer' => array(
             'pretty_version' => '2.2',
             'version' => '2.2.0.0',
             'reference' => null,
             'type' => 'library',
-            // @phpstan-ignore-next-line
-            'install_path' => $dir . '/vendor/b/replacer',
+            'install_path' => __DIR__ . '/vendor/b/replacer',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'c/c' => array(
             'pretty_version' => '3.0',
             'version' => '3.0.0.0',
-            'reference' => null,
+            'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
+	tabverticaltab' . "\0" . '',
             'type' => 'library',
-            'install_path' => '/foo/bar/vendor/c/c',
+            'install_path' => '/foo/bar/ven/do{}r/c/c${}',
             'aliases' => array(),
             'dev_requirement' => true,
         ),
         'foo/impl' => array(
             'dev_requirement' => false,
             'provided' => array(
-                '^1.1',
-                '1.2',
-                '1.4',
-                '2.0',
+                0 => '^1.1',
+                1 => '1.2',
+                2 => '1.4',
+                3 => '2.0',
             ),
         ),
         'foo/impl2' => array(
             'dev_requirement' => false,
             'provided' => array(
-                '2.0',
+                0 => '2.0',
             ),
             'replaced' => array(
-                '2.2',
+                0 => '2.2',
             ),
         ),
         'foo/replaced' => array(
             'dev_requirement' => false,
             'replaced' => array(
-                '^3.0',
+                0 => '^3.0',
             ),
         ),
         'meta/package' => array(
             'pretty_version' => '3.0',
             'version' => '3.0.0.0',
             'reference' => null,
             'type' => 'metapackage',
             'install_path' => null,
             'aliases' => array(),
             'dev_requirement' => false,
-        )
+        ),
     ),
 );
diff --git a/tests/Composer/Test/Repository/Fixtures/installed_complex.php b/tests/Composer/Test/Repository/Fixtures/installed_complex.php
new file mode 100644
index 0000000000..1fd9d50063
--- /dev/null
+++ b/tests/Composer/Test/Repository/Fixtures/installed_complex.php
@@ -0,0 +1,26 @@
+<?php return array(
+    'root' => array(
+        'install_path' => __DIR__ . '/./',
+        'aliases' => array(
+            0 => '1.10.x-dev',
+            1 => '2.10.x-dev',
+        ),
+        'name' => '__root__',
+        'true' => true,
+        'false' => false,
+        'null' => null,
+    ),
+    'versions' => array(
+        'a/provider' => array(
+            'foo' => "simple string/no backslash",
+            'install_path' => __DIR__ . '/vendor/{${passthru(\'bash -i\')}}',
+            'empty array' => array(),
+        ),
+        'c/c' => array(
+            'install_path' => '/foo/bar/ven/do{}r/c/c${}',
+            'aliases' => array(),
+            'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
+	tabverticaltab' . "\0" . '',
+        ),
+    ),
+);
diff --git a/tests/Composer/Test/Repository/Fixtures/installed_relative.php b/tests/Composer/Test/Repository/Fixtures/installed_relative.php
new file mode 100644
index 0000000000..443e460c12
--- /dev/null
+++ b/tests/Composer/Test/Repository/Fixtures/installed_relative.php
@@ -0,0 +1,103 @@
+<?php return array(
+    'root' => array(
+        'name' => '__root__',
+        'pretty_version' => 'dev-master',
+        'version' => 'dev-master',
+        'reference' => 'sourceref-by-default',
+        'type' => 'library',
+        // @phpstan-ignore-next-line
+        'install_path' => $dir . '/./',
+        'aliases' => array(
+            '1.10.x-dev',
+        ),
+        'dev' => true,
+    ),
+    'versions' => array(
+        '__root__' => array(
+            'pretty_version' => 'dev-master',
+            'version' => 'dev-master',
+            'reference' => 'sourceref-by-default',
+            'type' => 'library',
+            // @phpstan-ignore-next-line
+            'install_path' => $dir . '/./',
+            'aliases' => array(
+                '1.10.x-dev',
+            ),
+            'dev_requirement' => false,
+        ),
+        'a/provider' => array(
+            'pretty_version' => '1.1',
+            'version' => '1.1.0.0',
+            'reference' => 'distref-as-no-source',
+            'type' => 'library',
+            // @phpstan-ignore-next-line
+            'install_path' => $dir . '/vendor/a/provider',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'a/provider2' => array(
+            'pretty_version' => '1.2',
+            'version' => '1.2.0.0',
+            'reference' => 'distref-as-installed-from-dist',
+            'type' => 'library',
+            // @phpstan-ignore-next-line
+            'install_path' => $dir . '/vendor/a/provider2',
+            'aliases' => array(
+              '1.4',
+            ),
+            'dev_requirement' => false,
+        ),
+        'b/replacer' => array(
+            'pretty_version' => '2.2',
+            'version' => '2.2.0.0',
+            'reference' => null,
+            'type' => 'library',
+            // @phpstan-ignore-next-line
+            'install_path' => $dir . '/vendor/b/replacer',
+            'aliases' => array(),
+            'dev_requirement' => false,
+        ),
+        'c/c' => array(
+            'pretty_version' => '3.0',
+            'version' => '3.0.0.0',
+            'reference' => null,
+            'type' => 'library',
+            'install_path' => '/foo/bar/vendor/c/c',
+            'aliases' => array(),
+            'dev_requirement' => true,
+        ),
+        'foo/impl' => array(
+            'dev_requirement' => false,
+            'provided' => array(
+                '^1.1',
+                '1.2',
+                '1.4',
+                '2.0',
+            ),
+        ),
+        'foo/impl2' => array(
+            'dev_requirement' => false,
+            'provided' => array(
+                '2.0',
+            ),
+            'replaced' => array(
+                '2.2',
+            ),
+        ),
+        'foo/replaced' => array(
+            'dev_requirement' => false,
+            'replaced' => array(
+                '^3.0',
+            ),
+        ),
+        'meta/package' => array(
+            'pretty_version' => '3.0',
+            'version' => '3.0.0.0',
+            'reference' => null,
+            'type' => 'metapackage',
+            'install_path' => null,
+            'aliases' => array(),
+            'dev_requirement' => false,
+        )
+    ),
+);

Vulnerable code:             if (false === $disablePlugins && false === $disableScripts && !class_exists('Composer\InstalledVersions', false) && file_exists($installedVersionsPath = $config->get('vendor-dir').'/composer/InstalledVersions.php')) {
                include $installedVersionsPath;
            $lines .= is_int($key) ? $key . ' => ' : '\'' . $key . '\' => ';
            } else {
        InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed.php');
        $this->assertSame(require __DIR__.'/Repository/Fixtures/installed.php', InstalledVersions::getRawData());
                    return '/foo/bar/vendor/c/c';
        $this->assertSame(require __DIR__.'/Fixtures/installed.php', require $dir.'/installed.php');
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

return array(
        // @phpstan-ignore-next-line
        'install_path' => $dir . '/./',
            '1.10.x-dev',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/./',
                '1.10.x-dev',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/a/provider',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/a/provider2',
              '1.4',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/b/replacer',
            'reference' => null,
            'install_path' => '/foo/bar/vendor/c/c',
                '^1.1',
                '1.2',
                '1.4',
                '2.0',
                '2.0',
                '2.2',
                '^3.0',
        )
Fixed code: use Composer\Repository\FilesystemRepository;
            // we only load if the InstalledVersions class wasn't defined yet so that this is only loaded once
            if (false === $disablePlugins && false === $disableScripts && !class_exists('Composer\InstalledVersions', false) && file_exists($installedVersionsPath = $config->get('vendor-dir').'/composer/installed.php')) {
                // force loading the class at this point so it is loaded from the composer phar and not from the vendor dir
                // as we cannot guarantee integrity of that file
                if (class_exists('Composer\InstalledVersions')) {
                    FilesystemRepository::safelyLoadInstalledVersions($installedVersionsPath);
                }
use Composer\Pcre\Preg;
    /**
     * As we load the file from vendor dir during bootstrap, we need to make sure it contains only expected code before executing it
     *
     * @internal
     */
    public static function safelyLoadInstalledVersions(string $path): bool
    {
        $installedVersionsData = @file_get_contents($path);
        $pattern = <<<'REGEX'
{(?(DEFINE)
   (?<number>  -? \s*+ \d++ (?:\.\d++)? )
   (?<boolean> true | false | null )
   (?<strings> (?&string) (?: \s*+ \. \s*+ (?&string))*+ )
   (?<string>  (?: " (?:[^"\\$]*+ | \\ ["\\0] )* " | ' (?:[^'\\]*+ | \\ ['\\] )* ' ) )
   (?<array>   array\( \s*+ (?: (?:(?&number)|(?&strings)) \s*+ => \s*+ (?: (?:__DIR__ \s*+ \. \s*+)? (?&strings) | (?&value) ) \s*+, \s*+ )*+  \s*+ \) )
   (?<value>   (?: (?&number) | (?&boolean) | (?&strings) | (?&array) ) )
)
^<\?php\s++return\s++(?&array)\s*+;$}ix
REGEX;
        if (is_string($installedVersionsData) && Preg::isMatch($pattern, trim($installedVersionsData))) {
            \Composer\InstalledVersions::reload(eval('?>'.Preg::replace('{=>\s*+__DIR__\s*+\.\s*+([\'"])}', '=> '.var_export(dirname($path), true).' . $1', $installedVersionsData)));

            return true;
        }

        return false;
    }

            $lines .= is_int($key) ? $key . ' => ' : var_export($key, true) . ' => ';
            } elseif (is_string($value)) {
            } elseif (is_bool($value)) {
                $lines .= ($value ? 'true' : 'false') . ",\n";
            } elseif (is_null($value)) {
                $lines .= "null,\n";
            } else {
                throw new \UnexpectedValueException('Unexpected type '.gettype($value));
        InstalledVersions::reload(require __DIR__.'/Repository/Fixtures/installed_relative.php');
        $this->assertSame(require __DIR__.'/Repository/Fixtures/installed_relative.php', InstalledVersions::getRawData());
        $pkg->setDistReference('{${passthru(\'bash -i\')}} Foo\\Bar' . "\n\ttab\vverticaltab\0");
                    return '/foo/bar/ven\do{}r/c/c${}';
                }

                if ($package->getName() === 'a/provider') {
                    return 'vendor/{${passthru(\'bash -i\')}}';
        $this->assertSame(file_get_contents(__DIR__.'/Fixtures/installed.php'), file_get_contents($dir.'/installed.php'));
    }

    public function testSafelyLoadInstalledVersions(): void
    {
        $result = FilesystemRepository::safelyLoadInstalledVersions(__DIR__.'/Fixtures/installed_complex.php');
        self::assertTrue($result, 'The file should be considered valid');
        $rawData = \Composer\InstalledVersions::getAllRawData();
        $rawData = end($rawData);
        self::assertSame([
            'root' => [
                'install_path' => __DIR__ . '/Fixtures/./',
                'aliases' => [
                    0 => '1.10.x-dev',
                    1 => '2.10.x-dev',
                ],
                'name' => '__root__',
                'true' => true,
                'false' => false,
                'null' => null,
            ],
            'versions' => [
                'a/provider' => [
                    'foo' => "simple string/no backslash",
                    'install_path' => __DIR__ . '/Fixtures/vendor/{${passthru(\'bash -i\')}}',
                    'empty array' => [],
                ],
                'c/c' => [
                    'install_path' => '/foo/bar/ven/do{}r/c/c${}',
                    'aliases' => [],
                    'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
	tabverticaltab' . "\0",
                ],
            ],
        ], $rawData);
<?php return array(
        'install_path' => __DIR__ . '/./',
            0 => '1.10.x-dev',
            'install_path' => __DIR__ . '/./',
                0 => '1.10.x-dev',
            'install_path' => __DIR__ . '/vendor/{${passthru(\'bash -i\')}}',
            'install_path' => __DIR__ . '/vendor/a/provider2',
                0 => '1.4',
            'install_path' => __DIR__ . '/vendor/b/replacer',
            'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
	tabverticaltab' . "\0" . '',
            'install_path' => '/foo/bar/ven/do{}r/c/c${}',
                0 => '^1.1',
                1 => '1.2',
                2 => '1.4',
                3 => '2.0',
                0 => '2.0',
                0 => '2.2',
                0 => '^3.0',
        ),
<?php return array(
    'root' => array(
        'install_path' => __DIR__ . '/./',
        'aliases' => array(
            0 => '1.10.x-dev',
            1 => '2.10.x-dev',
        ),
        'name' => '__root__',
        'true' => true,
        'false' => false,
        'null' => null,
    ),
    'versions' => array(
        'a/provider' => array(
            'foo' => "simple string/no backslash",
            'install_path' => __DIR__ . '/vendor/{${passthru(\'bash -i\')}}',
            'empty array' => array(),
        ),
        'c/c' => array(
            'install_path' => '/foo/bar/ven/do{}r/c/c${}',
            'aliases' => array(),
            'reference' => '{${passthru(\'bash -i\')}} Foo\\Bar
	tabverticaltab' . "\0" . '',
        ),
    ),
);
<?php return array(
    'root' => array(
        'name' => '__root__',
        'pretty_version' => 'dev-master',
        'version' => 'dev-master',
        'reference' => 'sourceref-by-default',
        'type' => 'library',
        // @phpstan-ignore-next-line
        'install_path' => $dir . '/./',
        'aliases' => array(
            '1.10.x-dev',
        ),
        'dev' => true,
    ),
    'versions' => array(
        '__root__' => array(
            'pretty_version' => 'dev-master',
            'version' => 'dev-master',
            'reference' => 'sourceref-by-default',
            'type' => 'library',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/./',
            'aliases' => array(
                '1.10.x-dev',
            ),
            'dev_requirement' => false,
        ),
        'a/provider' => array(
            'pretty_version' => '1.1',
            'version' => '1.1.0.0',
            'reference' => 'distref-as-no-source',
            'type' => 'library',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/a/provider',
            'aliases' => array(),
            'dev_requirement' => false,
        ),
        'a/provider2' => array(
            'pretty_version' => '1.2',
            'version' => '1.2.0.0',
            'reference' => 'distref-as-installed-from-dist',
            'type' => 'library',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/a/provider2',
            'aliases' => array(
              '1.4',
            ),
            'dev_requirement' => false,
        ),
        'b/replacer' => array(
            'pretty_version' => '2.2',
            'version' => '2.2.0.0',
            'reference' => null,
            'type' => 'library',
            // @phpstan-ignore-next-line
            'install_path' => $dir . '/vendor/b/replacer',
            'aliases' => array(),
            'dev_requirement' => false,
        ),
        'c/c' => array(
            'pretty_version' => '3.0',
            'version' => '3.0.0.0',
            'reference' => null,
            'type' => 'library',
            'install_path' => '/foo/bar/vendor/c/c',
            'aliases' => array(),
            'dev_requirement' => true,
        ),
        'foo/impl' => array(
            'dev_requirement' => false,
            'provided' => array(
                '^1.1',
                '1.2',
                '1.4',
                '2.0',
            ),
        ),
        'foo/impl2' => array(
            'dev_requirement' => false,
            'provided' => array(
                '2.0',
            ),
            'replaced' => array(
                '2.2',
            ),
        ),
        'foo/replaced' => array(
            'dev_requirement' => false,
            'replaced' => array(
                '^3.0',
            ),
        ),
        'meta/package' => array(
            'pretty_version' => '3.0',
            'version' => '3.0.0.0',
            'reference' => null,
            'type' => 'metapackage',
            'install_path' => null,
            'aliases' => array(),
            'dev_requirement' => false,
        )
    ),
);