From c353ac835c8e09600b91b9c20778390ee0ff1099 Mon Sep 17 00:00:00 2001 From: Wissem Riahi Date: Tue, 21 Jul 2020 17:10:26 +0200 Subject: [PATCH] Add exception for multiple composer.json files (#3) --- .../Repository/ArtifactRepository.php | 7 +++- src/Composer/Util/Zip.php | 12 +++--- .../Util/Fixtures/Zip/multiple_subfolders.zip | Bin 0 -> 3724 bytes tests/Composer/Test/Util/ZipTest.php | 39 ++++++++++++------ 4 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip diff --git a/src/Composer/Repository/ArtifactRepository.php b/src/Composer/Repository/ArtifactRepository.php index a0acb7a61..f8b068218 100644 --- a/src/Composer/Repository/ArtifactRepository.php +++ b/src/Composer/Repository/ArtifactRepository.php @@ -88,7 +88,12 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito private function getComposerInformation(\SplFileInfo $file) { - $json = Zip::getComposerJson($file->getPathname()); + $json = null; + try { + $json = Zip::getComposerJson($file->getPathname()); + } catch (\Exception $exception) { + $this->io->write('Failed loading package '.$file->getPathname().': '.$exception->getMessage(), false, IOInterface::VERBOSE); + } if (null === $json) { return false; diff --git a/src/Composer/Util/Zip.php b/src/Composer/Util/Zip.php index 3ebdcdd85..ad6617edf 100644 --- a/src/Composer/Util/Zip.php +++ b/src/Composer/Util/Zip.php @@ -66,8 +66,9 @@ class Zip * * @param \ZipArchive $zip * @param string $filename + * @throws \RuntimeException * - * @return bool|int + * @return int */ private static function locateFile(\ZipArchive $zip, $filename) { @@ -85,8 +86,7 @@ class Zip if ($dirname === '.') { $topLevelPaths[$name] = true; if (\count($topLevelPaths) > 1) { - // archive can only contain one top level directory - return false; + throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths))); } continue; } @@ -95,8 +95,7 @@ class Zip if (false === strpos('\\', $dirname) && false === strpos('/', $dirname)) { $topLevelPaths[$dirname.'/'] = true; if (\count($topLevelPaths) > 1) { - // archive can only contain one top level directory - return false; + throw new \RuntimeException('Archive has more than one top level directories, and no composer.json was found on the top level, so it\'s an invalid archive. Top level paths found were: '.implode(',', array_keys($topLevelPaths))); } } } @@ -105,7 +104,6 @@ class Zip return $index; } - // no composer.json found either at the top level or within the topmost directory - return false; + throw new \RuntimeException('No composer.json found either at the top level or within the topmost directory'); } } diff --git a/tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip b/tests/Composer/Test/Util/Fixtures/Zip/multiple_subfolders.zip new file mode 100644 index 0000000000000000000000000000000000000000..5c5bc5adf86e747df57a7e1d2b7218612e3134ec GIT binary patch literal 3724 zcmWIWW@h1H0D<-iHv+&6D8b4gz>t=oZ>%30!Nc&j=u2E}<>$Dsj3NvHa4nZ&Z=z`7 zglS1kN``Bz0cwS56Jg*0!bvfx+Jum`>A3{Q2bbg*rGl(gDEtzqQUKBacE(1oLk0qE z?{D$3PVecfWWBH8RVp6u5E9_Hvb);s{^{_7kA)`B+_|Gk-Wu=`ir#<5)C13G)@W#$$jo}R4(|;d+)#7cr6LM|S#J72|r`=QH#f~P0>&dmo z+<9VU%fI^K)!8o+Kf8vu2sn9^UtF>0dY)v<1bLM?{9~bq^qF(Rgl#(*1H9Qe4lj+2dku^V76}HV5a*9W4LVSW z$H)6RI{ODlz(X7qS+Ed?#4WluK4fhukxW=GD7N5Mg7qTDHnM)~u`P>Lzg|4fh)+%s zO-@fpO8DUG6ZU~WtRtX-X@Uf^x_~s}MrncOAEFLt7=j-v9B5#+Xlr3{oGEG$`vMeX z>>S)32P{m1L0AFAphOFCPjFC*A2f-BDKVgX;ND2i&n?I=PA$^QD$dUXrNA;^SmwR0 zi2;S@>SsX=OiTA1xf7zQ&AN2UpPIi*jwq?Fi_!zzR-aeAT?%L-2;;U*5r^;bT8ujc z3T1&IAT80s)TgNE7@+2HoJm2-z;v&3=dXI}Xq@o8dfHP*PgB>=*V9wSGn9{m zO_N9Cmk|4+)>~^U9ZkSa7s=T7I|k_N4Jb~ZgjOJc5)C+@Fk)&7v}AZY!`APxfkfMV z{j&m{N0k?^zaTwBLx$li(}cG93qyC6sHHy^nbX|M8?(RFqj18EsDr;ft_i;^{bSi( z&vf8b?RFNK2CkE0@XyV&cqk5m5nY^%MzW%j<_ zzw__ke|3HK^wov8{!Vx|&uDSkj^obT?kUb(d%R@XJ;k$Egq=7Pk3|HP7T(I_P&_wb zhh2r$1?NqM`Y(#U^ewiPeW7^s#`*=`yB5j5ed)k|GGNX!F}^56=tf;%NO4PK1YBNZbM zFHFHzaD%jAqzd)Xf*Vm)qL;v!r6_XHW0s=mL62FAg5vFCQ)Ww4J#gCISU33ZyiB2v; zFvJK@a6^oM7Cpdxi`b0V4b*KsMZ*n>9?LL(r~ z0i|YqM)08+aR=E5l#n504zjoYI!Z7hIR#$9W4Z|uM9A$0StK_tX^g;X7D{=I9$JWO zg4{3=LoxOR&{(+3(9$jkyy<})lc2^6a&4`MVqO?CHZSYN6J<20x<{_LkYi;@qaX{^ zsTc_aR7D{>5o8W>NJ^qOF@Y7`iC97rVI;2V3Xy)_I=%rK2@XX_2?|Mbpvnu`RiN?{ zcNS1)Lox!xhoB-9U;0H&cX90KK16mGA`L?l2*_Q?p@o|6=3zApONb$yNKCrZ<3RE* rM&f`K*2uw!Ki$m%ng`GI@TkC&?hr<^0z;gEK@bS#fzcPv3E}|&bq`N_ literal 0 HcmV?d00001 diff --git a/tests/Composer/Test/Util/ZipTest.php b/tests/Composer/Test/Util/ZipTest.php index 78c7e9657..ba61e8bf6 100644 --- a/tests/Composer/Test/Util/ZipTest.php +++ b/tests/Composer/Test/Util/ZipTest.php @@ -55,28 +55,30 @@ class ZipTest extends TestCase $this->assertNull($result); } - public function testReturnsNullIfTheZipHasNoComposerJson() + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfTheZipHasNoComposerJson() { if (!extension_loaded('zip')) { $this->markTestSkipped('The PHP zip extension is not loaded.'); return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/nojson.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/nojson.zip'); } - public function testReturnsNullIfTheComposerJsonIsInASubSubfolder() + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfTheComposerJsonIsInASubSubfolder() { if (!extension_loaded('zip')) { $this->markTestSkipped('The PHP zip extension is not loaded.'); return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/subfolders.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/subfolders.zip'); } public function testReturnsComposerJsonInZipRoot() @@ -99,10 +101,12 @@ class ZipTest extends TestCase } $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/folder.zip'); - $this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result); } + /** + * @expectedException \RuntimeException + */ public function testMultipleTopLevelDirsIsInvalid() { if (!extension_loaded('zip')) { @@ -110,9 +114,7 @@ class ZipTest extends TestCase return; } - $result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple.zip'); - - $this->assertNull($result); + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple.zip'); } public function testReturnsComposerJsonFromFirstSubfolder() @@ -126,4 +128,17 @@ class ZipTest extends TestCase $this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result); } + + /** + * @expectedException \RuntimeException + */ + public function testThrowsExceptionIfMultipleComposerInSubFoldersWereFound() + { + if (!extension_loaded('zip')) { + $this->markTestSkipped('The PHP zip extension is not loaded.'); + return; + } + + Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple_subfolders.zip'); + } }