diff options
Diffstat (limited to 'lib/private/Installer.php')
-rw-r--r-- | lib/private/Installer.php | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/lib/private/Installer.php b/lib/private/Installer.php index a1d27c9255b..3bbef3252f4 100644 --- a/lib/private/Installer.php +++ b/lib/private/Installer.php @@ -10,14 +10,15 @@ declare(strict_types=1); namespace OC; use Doctrine\DBAL\Exception\TableExistsException; +use OC\App\AppStore\AppNotFoundException; use OC\App\AppStore\Bundles\Bundle; use OC\App\AppStore\Fetcher\AppFetcher; use OC\AppFramework\Bootstrap\Coordinator; use OC\Archive\TAR; use OC\DB\Connection; use OC\DB\MigrationService; +use OC\Files\FilenameValidator; use OC_App; -use OC_Helper; use OCP\App\IAppManager; use OCP\Files; use OCP\HintException; @@ -25,6 +26,7 @@ use OCP\Http\Client\IClientService; use OCP\IConfig; use OCP\ITempManager; use OCP\Migration\IOutput; +use OCP\Server; use phpseclib\File\X509; use Psr\Log\LoggerInterface; @@ -173,6 +175,7 @@ class Installer { * @param string $appId * @param bool [$allowUnstable] * + * @throws AppNotFoundException If the app is not found on the appstore * @throws \Exception If the installation was not successful */ public function downloadApp(string $appId, bool $allowUnstable = false): void { @@ -242,6 +245,10 @@ class Installer { // Download the release $tempFile = $this->tempManager->getTemporaryFile('.tar.gz'); + if ($tempFile === false) { + throw new \RuntimeException('Could not create temporary file for downloading app archive.'); + } + $timeout = $this->isCLI ? 0 : 120; $client = $this->clientService->newClient(); $client->get($app['releases'][0]['download'], ['sink' => $tempFile, 'timeout' => $timeout]); @@ -253,8 +260,11 @@ class Installer { if ($verified === true) { // Seems to match, let's proceed $extractDir = $this->tempManager->getTemporaryFolder(); - $archive = new TAR($tempFile); + if ($extractDir === false) { + throw new \RuntimeException('Could not create temporary directory for unpacking app.'); + } + $archive = new TAR($tempFile); if (!$archive->extract($extractDir)) { $errorMessage = 'Could not extract app ' . $appId; @@ -329,10 +339,13 @@ class Installer { // Move to app folder if (@mkdir($baseDir)) { $extractDir .= '/' . $folders[0]; - OC_Helper::copyr($extractDir, $baseDir); } - OC_Helper::copyr($extractDir, $baseDir); + // otherwise we just copy the outer directory + $this->copyRecursive($extractDir, $baseDir); Files::rmdirr($extractDir); + if (function_exists('opcache_reset')) { + opcache_reset(); + } return; } // Signature does not match @@ -345,9 +358,9 @@ class Installer { } } - throw new \Exception( + throw new AppNotFoundException( sprintf( - 'Could not download app %s', + 'Could not download app %s, it was not found on the appstore', $appId ) ); @@ -588,4 +601,33 @@ class Installer { include $script; } } + + /** + * Recursive copying of local folders. + * + * @param string $src source folder + * @param string $dest target folder + */ + private function copyRecursive(string $src, string $dest): void { + if (!file_exists($src)) { + return; + } + + if (is_dir($src)) { + if (!is_dir($dest)) { + mkdir($dest); + } + $files = scandir($src); + foreach ($files as $file) { + if ($file != '.' && $file != '..') { + $this->copyRecursive("$src/$file", "$dest/$file"); + } + } + } else { + $validator = Server::get(FilenameValidator::class); + if (!$validator->isForbidden($src)) { + copy($src, $dest); + } + } + } } |