From 782b428fc1077036feb12e897047850d9855a1cd Mon Sep 17 00:00:00 2001 From: Benjamin Gaussorgues Date: Thu, 9 Nov 2023 12:16:02 +0100 Subject: [PATCH] Improve iterators Signed-off-by: Benjamin Gaussorgues --- Makefile | 4 +- index.php | 98 +++++++++--------- lib/RecursiveDirectoryIteratorWithoutData.php | 42 -------- lib/Updater.php | 66 ++++++------ updater.phar | Bin 760620 -> 760899 bytes vendor/composer/autoload_classmap.php | 2 +- vendor/composer/autoload_static.php | 2 +- 7 files changed, 92 insertions(+), 122 deletions(-) delete mode 100644 lib/RecursiveDirectoryIteratorWithoutData.php diff --git a/Makefile b/Makefile index 7a7b2073..ad9d80b2 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,11 @@ updater.phar: updater.php lib/*.php buildVersionFile.php clean: rm updater.phar index.php -index.php: lib/UpdateException.php lib/LogException.php lib/RecursiveDirectoryIteratorWithoutData.php lib/Updater.php index.web.php +index.php: lib/UpdateException.php lib/LogException.php lib/RecursiveDirectoryIteratorFilter.php lib/Updater.php index.web.php # First put openining php tag and license awk '/^<\?php$$/,/\*\//' index.web.php > index.php # Then concat all files while filtering php tag and license - cat lib/UpdateException.php lib/LogException.php lib/RecursiveDirectoryIteratorWithoutData.php lib/Updater.php index.web.php| grep -v "^namespace" | awk '/^<\?php$$/,/\*\//{next} 1' >> index.php + cat lib/UpdateException.php lib/LogException.php lib/RecursiveDirectoryIteratorFilter.php lib/Updater.php index.web.php| grep -v "^namespace" | awk '/^<\?php$$/,/\*\//{next} 1' >> index.php test/vendor: cd tests && composer install diff --git a/index.php b/index.php index 5dc80709..4f2fe247 100644 --- a/index.php +++ b/index.php @@ -41,28 +41,25 @@ class LogException extends \Exception { } -class RecursiveDirectoryIteratorWithoutData extends \RecursiveFilterIterator { - public function accept(): bool { - $excludes = [ - '.rnd', - '.well-known', - 'data', - '..', - ]; +class RecursiveDirectoryIteratorFilter extends \RecursiveFilterIterator { + private array $excludedPaths; - /** @var \SplFileInfo|false */ - $current = $this->current(); - if (!$current) { - return false; - } + public function __construct( + \RecursiveDirectoryIterator $iterator, + array $excludedPaths = ['data'], + ) { + parent::__construct($iterator); + $this->excludedPaths = array_flip($excludedPaths); + } - return !(in_array($current->getFilename(), $excludes, true) || $current->isDir()); + public function accept(): bool { + return !isset($this->excludedPaths[$this->current()->getFilename()]); } } class Updater { - private string $baseDir; + private string $nextcloudDir; private array $configValues = []; private string $currentVersion = 'unknown'; private string $buildTime; @@ -75,13 +72,15 @@ class Updater { * @param string $baseDir the absolute path to the /updater/ directory in the Nextcloud root * @throws \Exception */ - public function __construct(string $baseDir) { - $this->baseDir = $baseDir; + public function __construct( + private string $baseDir + ) { + $this->nextcloudDir = realpath(dirname($baseDir)); if ($dir = getenv('NEXTCLOUD_CONFIG_DIR')) { - $configFileName = rtrim($dir, '/') . '/config.php'; + $configFileName = realpath($dir . '/config.php'); } else { - $configFileName = $this->baseDir . '/../config/config.php'; + $configFileName = $this->nextcloudDir . '/config/config.php'; } if (!file_exists($configFileName)) { throw new \Exception('Could not find config.php. Is this file in the "updater" subfolder of Nextcloud?'); @@ -102,7 +101,7 @@ public function __construct(string $baseDir) { throw new \Exception('Could not read data directory from config.php.'); } - $versionFileName = $this->baseDir . '/../version.php'; + $versionFileName = $this->nextcloudDir . '/version.php'; if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -133,19 +132,15 @@ public function __construct(string $baseDir) { /** * Returns whether the web updater is disabled - * - * @return bool */ - public function isDisabled() { + public function isDisabled(): bool { return $this->disabled; } /** * Returns current version or "unknown" if this could not be determined. - * - * @return string */ - public function getCurrentVersion() { + public function getCurrentVersion(): string { return $this->currentVersion; } @@ -153,7 +148,7 @@ public function getCurrentVersion() { * Returns currently used release channel */ private function getCurrentReleaseChannel(): string { - return ($this->getConfigOptionString('updater.release.channel') ?? 'stable'); + return $this->getConfigOptionString('updater.release.channel') ?? 'stable'; } /** @@ -325,14 +320,17 @@ private function getAppDirectories(): array { * * @return \RecursiveIteratorIterator<\RecursiveDirectoryIterator> */ - private function getRecursiveDirectoryIterator(?string $folder = null): \RecursiveIteratorIterator { + private function getRecursiveDirectoryIterator(?string $folder = null, array $excludedPaths = []): \RecursiveIteratorIterator { if ($folder === null) { $folder = $this->baseDir . '/../'; } - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST - ); + + $iterator = new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS); + if (!empty($excludedPaths)) { + $iterator = new RecursiveDirectoryIteratorFilter($iterator, $excludedPaths); + } + + return new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); } /** @@ -343,7 +341,7 @@ public function checkForExpectedFilesAndFolders(): void { $expectedElements = $this->getExpectedElementsList(); $unexpectedElements = []; - foreach (new \DirectoryIterator($this->baseDir . '/../') as $fileInfo) { + foreach (new \DirectoryIterator($this->nextcloudDir) as $fileInfo) { if (array_search($fileInfo->getFilename(), $expectedElements) === false) { $unexpectedElements[] = $fileInfo->getFilename(); } @@ -361,15 +359,21 @@ public function checkForExpectedFilesAndFolders(): void { public function checkWritePermissions(): void { $this->silentLog('[info] checkWritePermissions()'); - $notWritablePaths = array(); - $dir = new \RecursiveDirectoryIterator($this->baseDir . '/../'); - $filter = new RecursiveDirectoryIteratorWithoutData($dir); - /** @var iterable */ - $it = new \RecursiveIteratorIterator($filter); + $excludedPaths = [ + '.rnd', + '.well-known', + 'data', + ]; + + $it = new \DirectoryIterator($this->nextcloudDir); - foreach ($it as $path => $dir) { - if (!is_writable($path)) { - $notWritablePaths[] = $path; + $notWritablePaths = []; + foreach ($it as $path => $fileInfo) { + if ($fileInfo->isDot() || isset($excludedPaths[$fileInfo->getFilename()])) { + continue; + } + if (!$fileInfo->isWritable()) { + $notWritablePaths[] = $fileInfo->getFilename(); } } if (count($notWritablePaths) > 0) { @@ -442,7 +446,7 @@ public function createBackup(): void { * @var string $path * @var \SplFileInfo $fileInfo */ - foreach ($this->getRecursiveDirectoryIterator($currentDir) as $path => $fileInfo) { + foreach ($this->getRecursiveDirectoryIterator($currentDir, $excludedElements) as $path => $fileInfo) { $fileName = explode($currentDir, $path)[1]; $folderStructure = explode('/', $fileName, -1); @@ -459,6 +463,7 @@ public function createBackup(): void { // Create folder if it doesn't exist if (!file_exists($backupFolderLocation . '/' . dirname($fileName))) { + echo 'Create directory ', $backupFolderLocation . '/' . dirname($fileName), PHP_EOL; $state = mkdir($backupFolderLocation . '/' . dirname($fileName), 0750, true); if ($state === false) { throw new \Exception('Could not create folder: ' . $backupFolderLocation . '/' . dirname($fileName)); @@ -467,6 +472,8 @@ public function createBackup(): void { // If it is a file copy it if ($fileInfo->isFile()) { + echo 'Copy file ',$fileInfo->getRealPath(), 'to ', $backupFolderLocation, PHP_EOL; + $state = true; $state = copy($fileInfo->getRealPath(), $backupFolderLocation . $fileName); if ($state === false) { $message = sprintf( @@ -971,8 +978,9 @@ public function deleteOldFiles(): void { } /** - * Moves the specified filed except the excluded elements to the correct position + * Moves the specified files except the excluded elements to the correct position * + * @param string[] $excludedElements * @throws \Exception */ private function moveWithExclusions(string $dataLocation, array $excludedElements): void { @@ -1294,7 +1302,6 @@ public function isAuthenticated(): bool { if (isset($_POST['step'])) { // mark step as failed http_response_code(500); - header('Content-Type: application/json'); echo(json_encode(['proceed' => false, 'response' => $e->getMessage()])); die(); } @@ -1381,7 +1388,6 @@ public function isAuthenticated(): bool { break; } $updater->endStep($step); - header('Content-Type: application/json'); echo(json_encode(['proceed' => true])); } catch (UpdateException $e) { $data = $e->getData(); @@ -1397,7 +1403,6 @@ public function isAuthenticated(): bool { $updater->rollbackChanges($step); } http_response_code(500); - header('Content-Type: application/json'); echo(json_encode(['proceed' => false, 'response' => $data])); } catch (\Exception $e) { $message = $e->getMessage(); @@ -1413,7 +1418,6 @@ public function isAuthenticated(): bool { $updater->rollbackChanges($step); } http_response_code(500); - header('Content-Type: application/json'); echo(json_encode(['proceed' => false, 'response' => $message])); } diff --git a/lib/RecursiveDirectoryIteratorWithoutData.php b/lib/RecursiveDirectoryIteratorWithoutData.php deleted file mode 100644 index 52980eb7..00000000 --- a/lib/RecursiveDirectoryIteratorWithoutData.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright Copyright (c) 2016 Morris Jobke - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ - -namespace NC\Updater; - -class RecursiveDirectoryIteratorWithoutData extends \RecursiveFilterIterator { - public function accept(): bool { - $excludes = [ - '.rnd', - '.well-known', - 'data', - '..', - ]; - - /** @var \SplFileInfo|false */ - $current = $this->current(); - if (!$current) { - return false; - } - - return !(in_array($current->getFilename(), $excludes, true) || $current->isDir()); - } -} diff --git a/lib/Updater.php b/lib/Updater.php index 4adc6820..db237784 100644 --- a/lib/Updater.php +++ b/lib/Updater.php @@ -24,7 +24,7 @@ namespace NC\Updater; class Updater { - private string $baseDir; + private string $nextcloudDir; private array $configValues = []; private string $currentVersion = 'unknown'; private string $buildTime; @@ -37,13 +37,15 @@ class Updater { * @param string $baseDir the absolute path to the /updater/ directory in the Nextcloud root * @throws \Exception */ - public function __construct(string $baseDir) { - $this->baseDir = $baseDir; + public function __construct( + private string $baseDir + ) { + $this->nextcloudDir = realpath(dirname($baseDir)); if ($dir = getenv('NEXTCLOUD_CONFIG_DIR')) { - $configFileName = rtrim($dir, '/') . '/config.php'; + $configFileName = realpath($dir . '/config.php'); } else { - $configFileName = $this->baseDir . '/../config/config.php'; + $configFileName = $this->nextcloudDir . '/config/config.php'; } if (!file_exists($configFileName)) { throw new \Exception('Could not find config.php. Is this file in the "updater" subfolder of Nextcloud?'); @@ -64,7 +66,7 @@ public function __construct(string $baseDir) { throw new \Exception('Could not read data directory from config.php.'); } - $versionFileName = $this->baseDir . '/../version.php'; + $versionFileName = $this->nextcloudDir . '/version.php'; if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -95,19 +97,15 @@ public function __construct(string $baseDir) { /** * Returns whether the web updater is disabled - * - * @return bool */ - public function isDisabled() { + public function isDisabled(): bool { return $this->disabled; } /** * Returns current version or "unknown" if this could not be determined. - * - * @return string */ - public function getCurrentVersion() { + public function getCurrentVersion(): string { return $this->currentVersion; } @@ -115,7 +113,7 @@ public function getCurrentVersion() { * Returns currently used release channel */ private function getCurrentReleaseChannel(): string { - return ($this->getConfigOptionString('updater.release.channel') ?? 'stable'); + return $this->getConfigOptionString('updater.release.channel') ?? 'stable'; } /** @@ -287,14 +285,17 @@ private function getAppDirectories(): array { * * @return \RecursiveIteratorIterator<\RecursiveDirectoryIterator> */ - private function getRecursiveDirectoryIterator(?string $folder = null): \RecursiveIteratorIterator { + private function getRecursiveDirectoryIterator(?string $folder = null, array $excludedPaths = []): \RecursiveIteratorIterator { if ($folder === null) { $folder = $this->baseDir . '/../'; } - return new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST - ); + + $iterator = new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS); + if (!empty($excludedPaths)) { + $iterator = new RecursiveDirectoryIteratorFilter($iterator, $excludedPaths); + } + + return new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST); } /** @@ -305,7 +306,7 @@ public function checkForExpectedFilesAndFolders(): void { $expectedElements = $this->getExpectedElementsList(); $unexpectedElements = []; - foreach (new \DirectoryIterator($this->baseDir . '/../') as $fileInfo) { + foreach (new \DirectoryIterator($this->nextcloudDir) as $fileInfo) { if (array_search($fileInfo->getFilename(), $expectedElements) === false) { $unexpectedElements[] = $fileInfo->getFilename(); } @@ -323,15 +324,21 @@ public function checkForExpectedFilesAndFolders(): void { public function checkWritePermissions(): void { $this->silentLog('[info] checkWritePermissions()'); - $notWritablePaths = array(); - $dir = new \RecursiveDirectoryIterator($this->baseDir . '/../'); - $filter = new RecursiveDirectoryIteratorWithoutData($dir); - /** @var iterable */ - $it = new \RecursiveIteratorIterator($filter); + $excludedPaths = [ + '.rnd', + '.well-known', + 'data', + ]; + + $it = new \DirectoryIterator($this->nextcloudDir); - foreach ($it as $path => $dir) { - if (!is_writable($path)) { - $notWritablePaths[] = $path; + $notWritablePaths = []; + foreach ($it as $path => $fileInfo) { + if ($fileInfo->isDot() || isset($excludedPaths[$fileInfo->getFilename()])) { + continue; + } + if (!$fileInfo->isWritable()) { + $notWritablePaths[] = $fileInfo->getFilename(); } } if (count($notWritablePaths) > 0) { @@ -404,7 +411,7 @@ public function createBackup(): void { * @var string $path * @var \SplFileInfo $fileInfo */ - foreach ($this->getRecursiveDirectoryIterator($currentDir) as $path => $fileInfo) { + foreach ($this->getRecursiveDirectoryIterator($currentDir, $excludedElements) as $path => $fileInfo) { $fileName = explode($currentDir, $path)[1]; $folderStructure = explode('/', $fileName, -1); @@ -933,8 +940,9 @@ public function deleteOldFiles(): void { } /** - * Moves the specified filed except the excluded elements to the correct position + * Moves the specified files except the excluded elements to the correct position * + * @param string[] $excludedElements * @throws \Exception */ private function moveWithExclusions(string $dataLocation, array $excludedElements): void { diff --git a/updater.phar b/updater.phar index d21639a669907179291ef3afec22d9e3970e7c78..ff9560999449fbc91aceaa52a3d8f6a0d4990b64 100755 GIT binary patch delta 7021 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 z z@_V(NOo`-==l`b0B_sJPe6(I4OwJVXgyAk6A4={e@s&Kuvhdpi$w4z;p~D@w zG$!&u$GFt# z{D->hg#-&c91p*$m2g6pW&<9+L!-lCEqXKg?5Z|bqL3biht8*6^*|$$7;3eR&Oc(O zof62wx!RdJnxLM9&DIXnD34N&)~Hcx#kL9EAv8=G|K10JJJ?&>FALkwbE$akBCVgo zTw>6^1-t4zS4F++@&0cFGrrRYDj#v1E3gn?w)p>Hgu=i`GQZ%i8cEe>+yM=_+{`Uc z#5o3SJT*{CN?zq&_GfAs)J$aid@e1BY?{OE;s^kxk3LoFk`2aKlPJs^<)b2?#gW1>(Z?6O)eK{Ui8N=57NXb zQw~tclfn_2O%ho-NK+?bxsvaTQ;T$ZY}*U_WooT9gYJSDa=*J~dKcuHt3?;K`jH-X z&1DW9s1-@^0rgoI{@WUZFR3q5e>9N{%2y8waxZT`QihA(QC~nwuUjxE3GVbG{jKhl z!?N0ats$-}I@Q+?3>e)@H$29H-2ivb^(kt1((5-lkI05T-q01Nq;sOX{>3+ZDA#?U zc8=g~TX0RMke2&SzZf<|Id-NQu8r%lCht2$t4wgl^k2{?j z_ORm_8|OYU^&*D~M}?#5(SEP*((~@VV_!14hmC5}x}Pt+CQvMxFpLh_otaf&c9*3t lkV3=P9f^3$uXy!uqkBZ}*|%n9+{xr*_!^`dl=pbv{{ev&exm>Y delta 6662 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 s=F*fNH&2W5V}JB3oVfl $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', 'NC\\Updater\\CommandApplication' => $baseDir . '/lib/CommandApplication.php', 'NC\\Updater\\LogException' => $baseDir . '/lib/LogException.php', - 'NC\\Updater\\RecursiveDirectoryIteratorWithoutData' => $baseDir . '/lib/RecursiveDirectoryIteratorWithoutData.php', + 'NC\\Updater\\RecursiveDirectoryIteratorFilter' => $baseDir . '/lib/RecursiveDirectoryIteratorFilter.php', 'NC\\Updater\\UpdateCommand' => $baseDir . '/lib/UpdateCommand.php', 'NC\\Updater\\UpdateException' => $baseDir . '/lib/UpdateException.php', 'NC\\Updater\\Updater' => $baseDir . '/lib/Updater.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index d9f93773..d1b65dfe 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -95,7 +95,7 @@ class ComposerStaticInitba7c5c8f0885d00c3b669d0399f96c80 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', 'NC\\Updater\\CommandApplication' => __DIR__ . '/../..' . '/lib/CommandApplication.php', 'NC\\Updater\\LogException' => __DIR__ . '/../..' . '/lib/LogException.php', - 'NC\\Updater\\RecursiveDirectoryIteratorWithoutData' => __DIR__ . '/../..' . '/lib/RecursiveDirectoryIteratorWithoutData.php', + 'NC\\Updater\\RecursiveDirectoryIteratorFilter' => __DIR__ . '/../..' . '/lib/RecursiveDirectoryIteratorFilter.php', 'NC\\Updater\\UpdateCommand' => __DIR__ . '/../..' . '/lib/UpdateCommand.php', 'NC\\Updater\\UpdateException' => __DIR__ . '/../..' . '/lib/UpdateException.php', 'NC\\Updater\\Updater' => __DIR__ . '/../..' . '/lib/Updater.php',