diff --git a/lib/private/App/Platform.php b/lib/private/App/Platform.php index 15966d85c34ed..e6ef73e3f501a 100644 --- a/lib/private/App/Platform.php +++ b/lib/private/App/Platform.php @@ -26,6 +26,7 @@ namespace OC\App; use OCP\IConfig; +use OC\BinaryFinder; /** * Class Platform @@ -70,9 +71,8 @@ public function getOS(): string { /** * @param $command */ - public function isCommandKnown($command): bool { - $path = \OC_Helper::findBinaryPath($command); - return ($path !== null); + public function isCommandKnown(string $command): bool { + return \OCP\Server::get(BinaryFinder::class)->findBinaryPath($command) !== false; } public function getLibraryVersion(string $name): ?string { diff --git a/lib/private/BinaryFinder.php b/lib/private/BinaryFinder.php new file mode 100644 index 0000000000000..15fab9321d6eb --- /dev/null +++ b/lib/private/BinaryFinder.php @@ -0,0 +1,70 @@ + + * @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 OC; + +use OCP\ICache; +use OCP\ICacheFactory; +use Symfony\Component\Process\ExecutableFinder; + +/** + * Service that find the binary path for a program + */ +class BinaryFinder { + private ICache $cache; + + public function __construct(ICacheFactory $cacheFactory) { + $this->cache = $cacheFactory->createLocal('findBinaryPath'); + } + + /** + * Try to find a program + * + * @return false|string + */ + public function findBinaryPath(string $program) { + $result = $this->cache->get($program); + if ($result !== null) { + return $result; + } + $result = false; + if (\OCP\Util::isFunctionEnabled('exec')) { + $exeSniffer = new ExecutableFinder(); + // Returns null if nothing is found + $result = $exeSniffer->find($program, null, [ + '/usr/local/sbin', + '/usr/local/bin', + '/usr/sbin', + '/usr/bin', + '/sbin', + '/bin', + '/opt/bin', + ]); + if ($result === null) { + $result = false; + } + } + // store the value for 5 minutes + $this->cache->set($program, $result, 300); + return $result; + } +} diff --git a/lib/private/LargeFileHelper.php b/lib/private/LargeFileHelper.php index e2984b4bacf22..82b3c5ae760be 100755 --- a/lib/private/LargeFileHelper.php +++ b/lib/private/LargeFileHelper.php @@ -147,7 +147,7 @@ public function getFileSizeViaCurl($fileName) { * null on failure. */ public function getFileSizeViaExec($filename) { - if (\OC_Helper::is_function_enabled('exec')) { + if (\OCP\Util::isFunctionEnabled('exec')) { $os = strtolower(php_uname('s')); $arg = escapeshellarg($filename); $result = null; @@ -195,7 +195,7 @@ public function getFileMtime($fullPath) { $result = - 1; } if ($result < 0) { - if (\OC_Helper::is_function_enabled('exec')) { + if (\OCP\Util::isFunctionEnabled('exec')) { $os = strtolower(php_uname('s')); if (strpos($os, 'linux') !== false) { return $this->exec('stat -c %Y ' . escapeshellarg($fullPath)); diff --git a/lib/private/Mail/Mailer.php b/lib/private/Mail/Mailer.php index 991d1b202ecf2..804739917195a 100644 --- a/lib/private/Mail/Mailer.php +++ b/lib/private/Mail/Mailer.php @@ -48,6 +48,7 @@ use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; use OCP\Mail\IMessage; +use OC\BinaryFinder; use Psr\Log\LoggerInterface; /** @@ -71,19 +72,14 @@ class Mailer implements IMailer { /** @var \Swift_Mailer Cached mailer */ private $instance = null; - /** @var IConfig */ - private $config; + private IConfig $config; private LoggerInterface $logger; /** @var Defaults */ private $defaults; - /** @var IURLGenerator */ - private $urlGenerator; - /** @var IL10N */ - private $l10n; - /** @var IEventDispatcher */ - private $dispatcher; - /** @var IFactory */ - private $l10nFactory; + private IURLGenerator $urlGenerator; + private IL10N $l10n; + private IEventDispatcher $dispatcher; + private IFactory $l10nFactory; public function __construct(IConfig $config, LoggerInterface $logger, @@ -309,7 +305,7 @@ protected function getSendMailInstance(): \Swift_SendmailTransport { $binaryPath = '/var/qmail/bin/sendmail'; break; default: - $sendmail = \OC_Helper::findBinaryPath('sendmail'); + $sendmail = \OCP\Server::get(BinaryFinder::class)->findBinaryPath('sendmail'); if ($sendmail === null) { $sendmail = '/usr/sbin/sendmail'; } diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php index 6c17dd58b4b87..fc943b61021b6 100644 --- a/lib/private/PreviewManager.php +++ b/lib/private/PreviewManager.php @@ -47,73 +47,41 @@ use function array_key_exists; class PreviewManager implements IPreview { - /** @var IConfig */ - protected $config; - - /** @var IRootFolder */ - protected $rootFolder; - - /** @var IAppData */ - protected $appData; - - /** @var EventDispatcherInterface */ - protected $eventDispatcher; - - /** @var Generator */ - private $generator; - - /** @var GeneratorHelper */ - private $helper; - - /** @var bool */ - protected $providerListDirty = false; - - /** @var bool */ - protected $registeredCoreProviders = false; - - /** @var array */ - protected $providers = []; + protected IConfig $config; + protected IRootFolder $rootFolder; + protected IAppData $appData; + protected EventDispatcherInterface $eventDispatcher; + private ?Generator $generator = null; + private GeneratorHelper $helper; + protected bool $providerListDirty = false; + protected bool $registeredCoreProviders = false; + protected array $providers = []; /** @var array mime type => support status */ - protected $mimeTypeSupportMap = []; - - /** @var array */ - protected $defaultProviders; - - /** @var string */ - protected $userId; - - /** @var Coordinator */ - private $bootstrapCoordinator; + protected array $mimeTypeSupportMap = []; + protected array $defaultProviders = []; + protected ?string $userId; + private Coordinator $bootstrapCoordinator; /** * Hash map (without value) of loaded bootstrap providers - * - * @var null[] * @psalm-var array */ - private $loadedBootstrapProviders = []; - - /** @var IServerContainer */ - private $container; - - /** - * PreviewManager constructor. - * - * @param IConfig $config - * @param IRootFolder $rootFolder - * @param IAppData $appData - * @param EventDispatcherInterface $eventDispatcher - * @param string $userId - */ - public function __construct(IConfig $config, - IRootFolder $rootFolder, - IAppData $appData, - EventDispatcherInterface $eventDispatcher, - GeneratorHelper $helper, - $userId, - Coordinator $bootstrapCoordinator, - IServerContainer $container) { + private array $loadedBootstrapProviders = []; + private IServerContainer $container; + private BinaryFinder $binaryFinder; + + public function __construct( + IConfig $config, + IRootFolder $rootFolder, + IAppData $appData, + EventDispatcherInterface $eventDispatcher, + GeneratorHelper $helper, + ?string $userId, + Coordinator $bootstrapCoordinator, + IServerContainer $container, + BinaryFinder $binaryFinder + ) { $this->config = $config; $this->rootFolder = $rootFolder; $this->appData = $appData; @@ -122,6 +90,7 @@ public function __construct(IConfig $config, $this->userId = $userId; $this->bootstrapCoordinator = $bootstrapCoordinator; $this->container = $container; + $this->binaryFinder = $binaryFinder; } /** @@ -134,7 +103,7 @@ public function __construct(IConfig $config, * @param \Closure $callable * @return void */ - public function registerProvider($mimeTypeRegex, \Closure $callable) { + public function registerProvider($mimeTypeRegex, \Closure $callable): void { if (!$this->config->getSystemValue('enable_previews', true)) { return; } @@ -148,9 +117,8 @@ public function registerProvider($mimeTypeRegex, \Closure $callable) { /** * Get all providers - * @return array */ - public function getProviders() { + public function getProviders(): array { if (!$this->config->getSystemValue('enable_previews', true)) { return []; } @@ -168,9 +136,8 @@ public function getProviders() { /** * Does the manager have any providers - * @return bool */ - public function hasProviders() { + public function hasProviders(): bool { $this->registerCoreProviders(); return !empty($this->providers); } @@ -257,11 +224,8 @@ public function isMimeSupported($mimeType = '*') { /** * Check if a preview can be generated for a file - * - * @param \OCP\Files\FileInfo $file - * @return bool */ - public function isAvailable(\OCP\Files\FileInfo $file) { + public function isAvailable(\OCP\Files\FileInfo $file): bool { if (!$this->config->getSystemValue('enable_previews', true)) { return false; } @@ -421,10 +385,10 @@ protected function registerCoreProviders() { // Office requires openoffice or libreoffice $officeBinary = $this->config->getSystemValue('preview_libreoffice_path', null); if (is_null($officeBinary)) { - $officeBinary = \OC_Helper::findBinaryPath('libreoffice'); + $officeBinary = $this->binaryFinder->findBinaryPath('libreoffice'); } if (is_null($officeBinary)) { - $officeBinary = \OC_Helper::findBinaryPath('openoffice'); + $officeBinary = $this->binaryFinder->findBinaryPath('openoffice'); } if (is_string($officeBinary)) { @@ -439,9 +403,9 @@ protected function registerCoreProviders() { // Video requires avconv or ffmpeg if (in_array(Preview\Movie::class, $this->getEnabledDefaultProvider())) { - $movieBinary = \OC_Helper::findBinaryPath('avconv'); + $movieBinary = $this->binaryFinder->findBinaryPath('avconv'); if (is_null($movieBinary)) { - $movieBinary = \OC_Helper::findBinaryPath('ffmpeg'); + $movieBinary = $this->binaryFinder->findBinaryPath('ffmpeg'); } if (is_string($movieBinary)) { @@ -469,7 +433,7 @@ private function registerBootstrapProviders(): void { $this->registerProvider($provider->getMimeTypeRegex(), function () use ($provider) { try { - return $this->container->query($provider->getService()); + return $this->container->get($provider->getService()); } catch (QueryException $e) { return null; } diff --git a/lib/private/Server.php b/lib/private/Server.php index 7223c3b8ae374..b7f5111e23692 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -68,6 +68,7 @@ use OC\Authentication\LoginCredentials\Store; use OC\Authentication\Token\IProvider; use OC\Avatar\AvatarManager; +use OC\BinaryFinder; use OC\Collaboration\Collaborators\GroupPlugin; use OC\Collaboration\Collaborators\MailPlugin; use OC\Collaboration\Collaborators\RemoteGroupPlugin; @@ -335,7 +336,8 @@ public function __construct($webRoot, \OC\Config $config) { $c->get(GeneratorHelper::class), $c->get(ISession::class)->get('user_id'), $c->get(Coordinator::class), - $c->get(IServerContainer::class) + $c->get(IServerContainer::class), + $c->get(BinaryFinder::class) ); }); /** @deprecated 19.0.0 */ diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php index 226f73a07111e..bde4396f015f3 100644 --- a/lib/private/legacy/OC_Helper.php +++ b/lib/private/legacy/OC_Helper.php @@ -45,11 +45,11 @@ */ use bantu\IniGetWrapper\IniGetWrapper; use OC\Files\Filesystem; +use OC\BinaryFinder; use OCP\Files\Mount\IMountPoint; use OCP\ICacheFactory; use OCP\IUser; use Psr\Log\LoggerInterface; -use Symfony\Component\Process\ExecutableFinder; /** * Collection of useful functions @@ -436,45 +436,19 @@ public static function uploadLimit() { * * @param string $function_name * @return bool + * @deprecated Since 25.0.0 use \OCP\Util::isFunctionEnabled instead */ public static function is_function_enabled($function_name) { - if (!function_exists($function_name)) { - return false; - } - $ini = \OC::$server->get(IniGetWrapper::class); - $disabled = explode(',', $ini->get('disable_functions') ?: ''); - $disabled = array_map('trim', $disabled); - if (in_array($function_name, $disabled)) { - return false; - } - $disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: ''); - $disabled = array_map('trim', $disabled); - if (in_array($function_name, $disabled)) { - return false; - } - return true; + return \OCP\Util::isFunctionEnabled($function_name); } /** * Try to find a program - * - * @param string $program - * @return null|string + * @deprecated Since 25.0.0 Use \OC\BinaryFinder directly */ - public static function findBinaryPath($program) { - $memcache = \OC::$server->getMemCacheFactory()->createDistributed('findBinaryPath'); - if ($memcache->hasKey($program)) { - return $memcache->get($program); - } - $result = null; - if (self::is_function_enabled('exec')) { - $exeSniffer = new ExecutableFinder(); - // Returns null if nothing is found - $result = $exeSniffer->find($program, null, ['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/opt/bin']); - } - // store the value for 5 minutes - $memcache->set($program, $result, 300); - return $result; + public static function findBinaryPath(string $program): ?string { + $result = \OCP\Server::get(BinaryFinder::class)->findBinaryPath($program); + return $result !== false ? $result : null; } /** diff --git a/lib/public/Util.php b/lib/public/Util.php index e5bb2a955ae93..02fe6903e6032 100644 --- a/lib/public/Util.php +++ b/lib/public/Util.php @@ -48,6 +48,7 @@ use OC\AppScriptDependency; use OC\AppScriptSort; +use bantu\IniGetWrapper\IniGetWrapper; /** * This class provides different helper functions to make the life of a developer easier @@ -604,4 +605,22 @@ public static function shortenMultibyteString(string $subject, int $dataLength, } return $temp; } + + static public function isFunctionEnabled(string $functionName): bool { + if (!function_exists($functionName)) { + return false; + } + $ini = \OCP\Server::get(IniGetWrapper::class); + $disabled = explode(',', $ini->get('disable_functions') ?: ''); + $disabled = array_map('trim', $disabled); + if (in_array($functionName, $disabled)) { + return false; + } + $disabled = explode(',', $ini->get('suhosin.executor.func.blacklist') ?: ''); + $disabled = array_map('trim', $disabled); + if (in_array($functionName, $disabled)) { + return false; + } + return true; + } } diff --git a/tests/lib/LargeFileHelperGetFileSizeTest.php b/tests/lib/LargeFileHelperGetFileSizeTest.php index 3066d48792ba5..33ceadcb62a8a 100644 --- a/tests/lib/LargeFileHelperGetFileSizeTest.php +++ b/tests/lib/LargeFileHelperGetFileSizeTest.php @@ -63,7 +63,7 @@ public function testGetFileSizeViaExec($filename, $fileSize) { if (escapeshellarg('strängé') !== '\'strängé\'') { $this->markTestSkipped('Your escapeshell args removes accents'); } - if (!\OC_Helper::is_function_enabled('exec')) { + if (!\OC\Util::isFunctionEnabled('exec')) { $this->markTestSkipped( 'The exec() function needs to be enabled for this test.' );