From 50b560fe4c6a618930ecfcd5339736b4ef07284e Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Fri, 12 Jun 2015 22:24:31 +0200 Subject: [PATCH 1/6] Add the hash of the parsed content of the composer.json to the lock file, and use it to verify the json is not changed --- src/Composer/Factory.php | 16 +++++++- src/Composer/Package/Locker.php | 11 ++++- tests/Composer/Test/InstallerTest.php | 4 +- tests/Composer/Test/Package/LockerTest.php | 47 ++++++++++++++++++---- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 6f9a5da36..755b8884f 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -306,7 +306,7 @@ class Factory $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4).'lock' : $composerFile . '.lock'; - $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, md5_file($composerFile)); + $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, md5_file($composerFile), $this->getContentHash($composerFile)); $composer->setLocker($locker); } @@ -485,4 +485,18 @@ class Factory return $factory->createComposer($io, $config, $disablePlugins); } + + /** + * Returns the md5 hash of the sorted content of the composer file. + * + * @param string $composerFilePath Path to the composer file. + * + * @return string + */ + private function getContentHash($composerFilePath) + { + $content = json_decode(file_get_contents($composerFilePath), true); + ksort($content); + return md5(json_encode($content)); + } } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 9f9a0abf8..ef5e4fc75 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -35,6 +35,7 @@ class Locker private $repositoryManager; private $installationManager; private $hash; + private $contentHash; private $loader; private $dumper; private $process; @@ -48,13 +49,15 @@ class Locker * @param RepositoryManager $repositoryManager repository manager instance * @param InstallationManager $installationManager installation manager instance * @param string $hash unique hash of the current composer configuration + * @param string $contentHash unique hash of the content of the current composer configuration */ - public function __construct(IOInterface $io, JsonFile $lockFile, RepositoryManager $repositoryManager, InstallationManager $installationManager, $hash) + public function __construct(IOInterface $io, JsonFile $lockFile, RepositoryManager $repositoryManager, InstallationManager $installationManager, $hash, $contentHash) { $this->lockFile = $lockFile; $this->repositoryManager = $repositoryManager; $this->installationManager = $installationManager; $this->hash = $hash; + $this->contentHash = $contentHash; $this->loader = new ArrayLoader(null, true); $this->dumper = new ArrayDumper(); $this->process = new ProcessExecutor($io); @@ -85,6 +88,11 @@ class Locker { $lock = $this->lockFile->read(); + if (!empty($lock['content-hash'])) { + // There is a content hash key, use that instead of the file hash + return $this->contentHash == $lock['content-hash']; + } + return $this->hash === $lock['hash']; } @@ -241,6 +249,7 @@ class Locker 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file', 'This file is @gener'.'ated automatically'), 'hash' => $this->hash, + 'content-hash' => $this->contentHash, 'packages' => null, 'packages-dev' => null, 'aliases' => array(), diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 7fa85d76d..0a1dff0e4 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -191,7 +191,8 @@ class InstallerTest extends TestCase })); } - $locker = new Locker($io, $lockJsonMock, $repositoryManager, $composer->getInstallationManager(), md5(json_encode($composerConfig))); + $hash = md5(json_encode($composerConfig)); + $locker = new Locker($io, $lockJsonMock, $repositoryManager, $composer->getInstallationManager(), $hash, $hash); $composer->setLocker($locker); $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); @@ -237,6 +238,7 @@ class InstallerTest extends TestCase if ($expectLock) { unset($actualLock['hash']); + unset($actualLock['content-hash']); unset($actualLock['_readme']); $this->assertEquals($expectLock, $actualLock); } diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php index 914bbe2f9..6d0937ef1 100644 --- a/tests/Composer/Test/Package/LockerTest.php +++ b/tests/Composer/Test/Package/LockerTest.php @@ -20,7 +20,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase public function testIsLocked() { $json = $this->createJsonFileMock(); - $locker = new Locker(new NullIO, $json, $this->createRepositoryManagerMock(), $this->createInstallationManagerMock(), 'md5'); + $locker = new Locker(new NullIO, $json, $this->createRepositoryManagerMock(), $this->createInstallationManagerMock(), 'md5', 'contentMd5'); $json ->expects($this->any()) @@ -40,7 +40,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); $json ->expects($this->once()) @@ -58,7 +58,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); $json ->expects($this->once()) @@ -85,7 +85,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); $package1 = $this->createPackageMock(); $package2 = $this->createPackageMock(); @@ -124,6 +124,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file', 'This file is @gener'.'ated automatically'), 'hash' => 'md5', + 'content-hash' => 'contentMd5', 'packages' => array( array('name' => 'pkg1', 'version' => '1.0.0-beta'), array('name' => 'pkg2', 'version' => '0.1.10') @@ -148,7 +149,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'md5'); $package1 = $this->createPackageMock(); $package1 @@ -167,7 +168,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); $json ->expects($this->once()) @@ -183,7 +184,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); $json ->expects($this->once()) @@ -193,6 +194,38 @@ class LockerTest extends \PHPUnit_Framework_TestCase $this->assertFalse($locker->isFresh()); } + public function testIsFreshWithContentHash() + { + $json = $this->createJsonFileMock(); + $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); + + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + + $json + ->expects($this->once()) + ->method('read') + ->will($this->returnValue(array('hash' => 'oldMd5', 'content-hash' => 'contentMd5'))); + + $this->assertTrue($locker->isFresh()); + } + + public function testIsFreshFalseWithContentHash() + { + $json = $this->createJsonFileMock(); + $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); + + $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + + $json + ->expects($this->once()) + ->method('read') + ->will($this->returnValue(array('hash' => 'md5', 'content-hash' => 'oldMd5'))); + + $this->assertFalse($locker->isFresh()); + } + private function createJsonFileMock() { return $this->getMockBuilder('Composer\Json\JsonFile') From 3e0219c4384465bc0f66369817426e3baa103583 Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Sat, 13 Jun 2015 10:15:56 +0200 Subject: [PATCH 2/6] Change the content hash to be only based on values that affect dependency resolution --- src/Composer/Factory.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 755b8884f..d14cee7bd 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -496,7 +496,26 @@ class Factory private function getContentHash($composerFilePath) { $content = json_decode(file_get_contents($composerFilePath), true); - ksort($content); - return md5(json_encode($content)); + + $relevantKeys = array( + 'require', + 'require-dev', + 'conflict', + 'replace', + 'provide', + 'suggest', + 'minimum-stability', + 'prefer-stable', + 'repositories', + ); + + $relevantContent = array(); + + foreach (array_intersect($relevantKeys, array_keys($content)) as $key) { + $relevantContent[$key] = $content[$key]; + } + + ksort($relevantContent); + return md5(json_encode($relevantContent)); } } From 9b50ca01614f8aa2c8f5e0fcc2d0f7eaf8d75b54 Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Mon, 15 Jun 2015 11:31:33 +0200 Subject: [PATCH 3/6] Add the extra attribute to the content hash --- src/Composer/Factory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index d14cee7bd..8a2a6a815 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -507,6 +507,7 @@ class Factory 'minimum-stability', 'prefer-stable', 'repositories', + 'extra', ); $relevantContent = array(); From bfb83f1fb7ba811baf9508a6d337fa5608ce4379 Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Fri, 21 Aug 2015 16:54:28 +1200 Subject: [PATCH 4/6] Add name and version to the relevant fields, move content hash checking to the Locker --- src/Composer/Factory.php | 36 +-------------- src/Composer/Package/Locker.php | 50 +++++++++++++++++---- tests/Composer/Test/InstallerTest.php | 4 +- tests/Composer/Test/Package/LockerTest.php | 51 +++++++++++++++------- 4 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/Composer/Factory.php b/src/Composer/Factory.php index 8a2a6a815..6a206d039 100644 --- a/src/Composer/Factory.php +++ b/src/Composer/Factory.php @@ -306,7 +306,7 @@ class Factory $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4).'lock' : $composerFile . '.lock'; - $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, md5_file($composerFile), $this->getContentHash($composerFile)); + $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, file_get_contents($composerFile)); $composer->setLocker($locker); } @@ -485,38 +485,4 @@ class Factory return $factory->createComposer($io, $config, $disablePlugins); } - - /** - * Returns the md5 hash of the sorted content of the composer file. - * - * @param string $composerFilePath Path to the composer file. - * - * @return string - */ - private function getContentHash($composerFilePath) - { - $content = json_decode(file_get_contents($composerFilePath), true); - - $relevantKeys = array( - 'require', - 'require-dev', - 'conflict', - 'replace', - 'provide', - 'suggest', - 'minimum-stability', - 'prefer-stable', - 'repositories', - 'extra', - ); - - $relevantContent = array(); - - foreach (array_intersect($relevantKeys, array_keys($content)) as $key) { - $relevantContent[$key] = $content[$key]; - } - - ksort($relevantContent); - return md5(json_encode($relevantContent)); - } } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index ef5e4fc75..6b6d913ff 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -45,19 +45,18 @@ class Locker * Initializes packages locker. * * @param IOInterface $io - * @param JsonFile $lockFile lockfile loader - * @param RepositoryManager $repositoryManager repository manager instance - * @param InstallationManager $installationManager installation manager instance - * @param string $hash unique hash of the current composer configuration - * @param string $contentHash unique hash of the content of the current composer configuration + * @param JsonFile $lockFile lockfile loader + * @param RepositoryManager $repositoryManager repository manager instance + * @param InstallationManager $installationManager installation manager instance + * @param string $composerFileContents The contents of the composer file */ - public function __construct(IOInterface $io, JsonFile $lockFile, RepositoryManager $repositoryManager, InstallationManager $installationManager, $hash, $contentHash) + public function __construct(IOInterface $io, JsonFile $lockFile, RepositoryManager $repositoryManager, InstallationManager $installationManager, $composerFileContents) { $this->lockFile = $lockFile; $this->repositoryManager = $repositoryManager; $this->installationManager = $installationManager; - $this->hash = $hash; - $this->contentHash = $contentHash; + $this->hash = md5($composerFileContents); + $this->contentHash = $this->getContentHash($composerFileContents); $this->loader = new ArrayLoader(null, true); $this->dumper = new ArrayDumper(); $this->process = new ProcessExecutor($io); @@ -387,4 +386,39 @@ class Locker return $datetime ? $datetime->format('Y-m-d H:i:s') : null; } + + /** + * Returns the md5 hash of the sorted content of the composer file. + * + * @param string $composerFileContents The contents of the composer file. + * + * @return string + */ + private function getContentHash($composerFileContents) + { + $content = json_decode($composerFileContents, true); + + $relevantKeys = array( + 'require', + 'require-dev', + 'conflict', + 'replace', + 'provide', + 'minimum-stability', + 'prefer-stable', + 'repositories', + 'extra', + 'version', + 'name', + ); + + $relevantContent = array(); + + foreach (array_intersect($relevantKeys, array_keys($content)) as $key) { + $relevantContent[$key] = $content[$key]; + } + + ksort($relevantContent); + return md5(json_encode($relevantContent)); + } } diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 0a1dff0e4..4b8aa28f9 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -191,8 +191,8 @@ class InstallerTest extends TestCase })); } - $hash = md5(json_encode($composerConfig)); - $locker = new Locker($io, $lockJsonMock, $repositoryManager, $composer->getInstallationManager(), $hash, $hash); + $contents = json_encode($composerConfig); + $locker = new Locker($io, $lockJsonMock, $repositoryManager, $composer->getInstallationManager(), $contents); $composer->setLocker($locker); $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(); diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php index 6d0937ef1..960d4f9c5 100644 --- a/tests/Composer/Test/Package/LockerTest.php +++ b/tests/Composer/Test/Package/LockerTest.php @@ -20,7 +20,8 @@ class LockerTest extends \PHPUnit_Framework_TestCase public function testIsLocked() { $json = $this->createJsonFileMock(); - $locker = new Locker(new NullIO, $json, $this->createRepositoryManagerMock(), $this->createInstallationManagerMock(), 'md5', 'contentMd5'); + $locker = new Locker(new NullIO, $json, $this->createRepositoryManagerMock(), $this->createInstallationManagerMock(), + $this->getJsonContent()); $json ->expects($this->any()) @@ -40,7 +41,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); $json ->expects($this->once()) @@ -58,7 +59,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); $json ->expects($this->once()) @@ -85,7 +86,8 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $jsonContent = $this->getJsonContent() . ' '; + $locker = new Locker(new NullIO, $json, $repo, $inst, $jsonContent); $package1 = $this->createPackageMock(); $package2 = $this->createPackageMock(); @@ -116,6 +118,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase ->method('getVersion') ->will($this->returnValue('0.1.10.0')); + $hash = md5($jsonContent); + $contentHash = md5(trim($jsonContent)); + $json ->expects($this->once()) ->method('write') @@ -123,8 +128,8 @@ class LockerTest extends \PHPUnit_Framework_TestCase '_readme' => array('This file locks the dependencies of your project to a known state', 'Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file', 'This file is @gener'.'ated automatically'), - 'hash' => 'md5', - 'content-hash' => 'contentMd5', + 'hash' => $hash, + 'content-hash' => $contentHash, 'packages' => array( array('name' => 'pkg1', 'version' => '1.0.0-beta'), array('name' => 'pkg2', 'version' => '0.1.10') @@ -149,7 +154,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'md5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); $package1 = $this->createPackageMock(); $package1 @@ -168,12 +173,13 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $jsonContent = $this->getJsonContent(); + $locker = new Locker(new NullIO, $json, $repo, $inst, $jsonContent); $json ->expects($this->once()) ->method('read') - ->will($this->returnValue(array('hash' => 'md5'))); + ->will($this->returnValue(array('hash' => md5($jsonContent)))); $this->assertTrue($locker->isFresh()); } @@ -184,12 +190,12 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); $json ->expects($this->once()) ->method('read') - ->will($this->returnValue(array('hash' => 'oldmd5'))); + ->will($this->returnValue(array('hash' => $this->getJsonContent(array('name' => 'test2'))))); $this->assertFalse($locker->isFresh()); } @@ -200,12 +206,13 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $jsonContent = $this->getJsonContent(); + $locker = new Locker(new NullIO, $json, $repo, $inst, $jsonContent); $json ->expects($this->once()) ->method('read') - ->will($this->returnValue(array('hash' => 'oldMd5', 'content-hash' => 'contentMd5'))); + ->will($this->returnValue(array('hash' => md5($jsonContent . ' '), 'content-hash' => md5($jsonContent)))); $this->assertTrue($locker->isFresh()); } @@ -216,12 +223,14 @@ class LockerTest extends \PHPUnit_Framework_TestCase $repo = $this->createRepositoryManagerMock(); $inst = $this->createInstallationManagerMock(); - $locker = new Locker(new NullIO, $json, $repo, $inst, 'md5', 'contentMd5'); + $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); + + $differentHash = md5($this->getJsonContent(['name' => 'test2'])); $json ->expects($this->once()) ->method('read') - ->will($this->returnValue(array('hash' => 'md5', 'content-hash' => 'oldMd5'))); + ->will($this->returnValue(array('hash' => $differentHash, 'content-hash' => $differentHash))); $this->assertFalse($locker->isFresh()); } @@ -260,4 +269,16 @@ class LockerTest extends \PHPUnit_Framework_TestCase return $this->getMockBuilder('Composer\Package\PackageInterface') ->getMock(); } + + private function getJsonContent(array $customData = array()) + { + $data = array_merge(array( + 'minimum-stability' => 'beta', + 'name' => 'test', + ), $customData); + + ksort($data); + + return json_encode($data); + } } From 62630e5c69c3fcc10dc1b15c4222724caa76f1d1 Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Fri, 21 Aug 2015 16:55:44 +1200 Subject: [PATCH 5/6] Fix strict comparison of the content hash --- src/Composer/Package/Locker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 6b6d913ff..bbd45012d 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -89,7 +89,7 @@ class Locker if (!empty($lock['content-hash'])) { // There is a content hash key, use that instead of the file hash - return $this->contentHash == $lock['content-hash']; + return $this->contentHash === $lock['content-hash']; } return $this->hash === $lock['hash']; From d7a94bda1bcd50bae9080533bdc4b0dccbd0ca31 Mon Sep 17 00:00:00 2001 From: Zsolt Szeberenyi Date: Fri, 21 Aug 2015 16:57:31 +1200 Subject: [PATCH 6/6] Change short array syntax to long for 5.3 compatibility --- tests/Composer/Test/Package/LockerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php index 960d4f9c5..2a45b1c66 100644 --- a/tests/Composer/Test/Package/LockerTest.php +++ b/tests/Composer/Test/Package/LockerTest.php @@ -225,7 +225,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase $locker = new Locker(new NullIO, $json, $repo, $inst, $this->getJsonContent()); - $differentHash = md5($this->getJsonContent(['name' => 'test2'])); + $differentHash = md5($this->getJsonContent(array('name' => 'test2'))); $json ->expects($this->once())