diff --git a/src/Composer/Cache.php b/src/Composer/Cache.php index 518b63ee3..a3b9114ba 100644 --- a/src/Composer/Cache.php +++ b/src/Composer/Cache.php @@ -104,6 +104,16 @@ class Cache return false; } + public function remove($file) + { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if ($this->enabled && file_exists($this->root . $file)) { + return unlink($this->root . $file); + } + + return false; + } + public function gc($ttl) { $expire = new \DateTime(); diff --git a/src/Composer/Downloader/ArchiveDownloader.php b/src/Composer/Downloader/ArchiveDownloader.php index fea972b30..917fe56e2 100644 --- a/src/Composer/Downloader/ArchiveDownloader.php +++ b/src/Composer/Downloader/ArchiveDownloader.php @@ -35,7 +35,13 @@ abstract class ArchiveDownloader extends FileDownloader $this->io->write(' Unpacking archive'); } try { - $this->extract($fileName, $path); + try { + $this->extract($fileName, $path); + } catch (\Exception $e) { + // remove cache if the file was corrupted + parent::clearCache($package, $path); + throw $e; + } if ($this->io->isVerbose()) { $this->io->write(' Cleaning up'); diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 12c5d2471..2e5cf0192 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -121,10 +121,19 @@ class FileDownloader implements DownloaderInterface } catch (\Exception $e) { // clean up $this->filesystem->removeDirectory($path); + $this->clearCache($package, $path); throw $e; } } + protected function clearCache(PackageInterface $package, $path) + { + if ($this->cache) { + $fileName = $this->getFileName($package, $path); + $this->cache->remove($this->getCacheKey($package)); + } + } + /** * {@inheritDoc} */