aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private')
-rw-r--r--lib/private/Accounts/AccountManager.php3
-rw-r--r--lib/private/AppFramework/App.php3
-rw-r--r--lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php52
-rw-r--r--lib/private/Avatar/AvatarManager.php9
-rw-r--r--lib/private/Files/Cache/Cache.php15
-rw-r--r--lib/private/Files/Cache/HomeCache.php2
-rw-r--r--lib/private/Files/Cache/Scanner.php2
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheJail.php2
-rw-r--r--lib/private/Files/Cache/Wrapper/CacheWrapper.php2
-rw-r--r--lib/private/Files/Node/LazyFolder.php7
-rw-r--r--lib/private/Files/Node/LazyUserFolder.php17
-rw-r--r--lib/private/Files/ObjectStore/ObjectStoreStorage.php24
-rw-r--r--lib/private/Files/Storage/DAV.php5
-rw-r--r--lib/private/Files/Storage/Local.php7
-rw-r--r--lib/private/Files/Type/Loader.php26
-rw-r--r--lib/private/Installer.php13
-rw-r--r--lib/private/Log.php1
-rw-r--r--lib/private/Memcache/Redis.php90
-rw-r--r--lib/private/Preview/Generator.php4
-rw-r--r--lib/private/Preview/Imaginary.php3
-rw-r--r--lib/private/Preview/MP3.php15
-rw-r--r--lib/private/RedisFactory.php4
-rw-r--r--lib/private/Repair/ClearGeneratedAvatarCache.php7
-rw-r--r--lib/private/Security/CertificateManager.php8
-rw-r--r--lib/private/Server.php8
-rw-r--r--lib/private/Template/JSResourceLocator.php2
-rw-r--r--lib/private/Updater.php5
-rw-r--r--lib/private/User/User.php2
-rw-r--r--lib/private/legacy/OC_App.php78
-rw-r--r--lib/private/legacy/OC_Defaults.php9
-rw-r--r--lib/private/legacy/OC_Helper.php2
31 files changed, 213 insertions, 214 deletions
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index 1d64d604578..60065272a58 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -38,7 +38,6 @@ namespace OC\Accounts;
use Exception;
use InvalidArgumentException;
use libphonenumber\NumberParseException;
-use libphonenumber\PhoneNumber;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use OC\Profile\TProfileHelper;
@@ -186,7 +185,7 @@ class AccountManager implements IAccountManager {
$phoneUtil = PhoneNumberUtil::getInstance();
try {
$phoneNumber = $phoneUtil->parse($input, $defaultRegion);
- if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
+ if ($phoneUtil->isValidNumber($phoneNumber)) {
return $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
}
} catch (NumberParseException $e) {
diff --git a/lib/private/AppFramework/App.php b/lib/private/AppFramework/App.php
index 0cbe47b75a5..ffd77da888e 100644
--- a/lib/private/AppFramework/App.php
+++ b/lib/private/AppFramework/App.php
@@ -34,6 +34,7 @@ namespace OC\AppFramework;
use OC\AppFramework\DependencyInjection\DIContainer;
use OC\AppFramework\Http\Dispatcher;
use OC\AppFramework\Http\Request;
+use OCP\App\IAppManager;
use OCP\Profiler\IProfiler;
use OC\Profiler\RoutingDataCollector;
use OCP\AppFramework\QueryException;
@@ -68,7 +69,7 @@ class App {
return $topNamespace . self::$nameSpaceCache[$appId];
}
- $appInfo = \OC_App::getAppInfo($appId);
+ $appInfo = \OCP\Server::get(IAppManager::class)->getAppInfo($appId);
if (isset($appInfo['namespace'])) {
self::$nameSpaceCache[$appId] = trim($appInfo['namespace']);
} else {
diff --git a/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php b/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php
index ba8c7f45b49..2ecd26a68e1 100644
--- a/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php
+++ b/lib/private/AppFramework/Middleware/Security/BruteForceMiddleware.php
@@ -90,32 +90,40 @@ class BruteForceMiddleware extends Middleware {
*/
public function afterController($controller, $methodName, Response $response) {
if ($response->isThrottled()) {
- if ($this->reflector->hasAnnotation('BruteForceProtection')) {
- $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action');
- $ip = $this->request->getRemoteAddress();
- $this->throttler->sleepDelay($ip, $action);
- $this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata());
- } else {
- $reflectionMethod = new ReflectionMethod($controller, $methodName);
- $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
-
- if (!empty($attributes)) {
+ try {
+ if ($this->reflector->hasAnnotation('BruteForceProtection')) {
+ $action = $this->reflector->getAnnotationParameter('BruteForceProtection', 'action');
$ip = $this->request->getRemoteAddress();
- $metaData = $response->getThrottleMetadata();
-
- foreach ($attributes as $attribute) {
- /** @var BruteForceProtection $protection */
- $protection = $attribute->newInstance();
- $action = $protection->getAction();
-
- if (!isset($metaData['action']) || $metaData['action'] === $action) {
- $this->throttler->sleepDelay($ip, $action);
- $this->throttler->registerAttempt($action, $ip, $metaData);
+ $this->throttler->registerAttempt($action, $ip, $response->getThrottleMetadata());
+ $this->throttler->sleepDelayOrThrowOnMax($ip, $action);
+ } else {
+ $reflectionMethod = new ReflectionMethod($controller, $methodName);
+ $attributes = $reflectionMethod->getAttributes(BruteForceProtection::class);
+
+ if (!empty($attributes)) {
+ $ip = $this->request->getRemoteAddress();
+ $metaData = $response->getThrottleMetadata();
+
+ foreach ($attributes as $attribute) {
+ /** @var BruteForceProtection $protection */
+ $protection = $attribute->newInstance();
+ $action = $protection->getAction();
+
+ if (!isset($metaData['action']) || $metaData['action'] === $action) {
+ $this->throttler->registerAttempt($action, $ip, $metaData);
+ $this->throttler->sleepDelayOrThrowOnMax($ip, $action);
+ }
}
+ } else {
+ $this->logger->debug('Response for ' . get_class($controller) . '::' . $methodName . ' got bruteforce throttled but has no annotation nor attribute defined.');
}
- } else {
- $this->logger->debug('Response for ' . get_class($controller) . '::' . $methodName . ' got bruteforce throttled but has no annotation nor attribute defined.');
}
+ } catch (MaxDelayReached $e) {
+ if ($controller instanceof OCSController) {
+ throw new OCSException($e->getMessage(), Http::STATUS_TOO_MANY_REQUESTS);
+ }
+
+ return new TooManyRequestsResponse();
}
}
diff --git a/lib/private/Avatar/AvatarManager.php b/lib/private/Avatar/AvatarManager.php
index 5c4f04de6d6..4125c8eb0a8 100644
--- a/lib/private/Avatar/AvatarManager.php
+++ b/lib/private/Avatar/AvatarManager.php
@@ -160,13 +160,8 @@ class AvatarManager implements IAvatarManager {
public function clearCachedAvatars() {
$users = $this->config->getUsersForUserValue('avatar', 'generated', 'true');
foreach ($users as $userId) {
- try {
- $folder = $this->appData->getFolder($userId);
- $folder->delete();
- } catch (NotFoundException $e) {
- $this->logger->debug("No cache for the user $userId. Ignoring...");
- }
- $this->config->setUserValue($userId, 'avatar', 'generated', 'false');
+ // This also bumps the avatar version leading to cache invalidation in browsers
+ $this->getAvatar($userId)->remove();
}
}
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index f085f8ade5e..5af15700764 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -60,6 +60,7 @@ use OCP\Files\Search\ISearchOperator;
use OCP\Files\Search\ISearchQuery;
use OCP\Files\Storage\IStorage;
use OCP\IDBConnection;
+use OCP\Util;
use Psr\Log\LoggerInterface;
/**
@@ -191,8 +192,8 @@ class Cache implements ICache {
$data['path'] = (string)$data['path'];
$data['fileid'] = (int)$data['fileid'];
$data['parent'] = (int)$data['parent'];
- $data['size'] = 0 + $data['size'];
- $data['unencrypted_size'] = 0 + ($data['unencrypted_size'] ?? 0);
+ $data['size'] = Util::numericToNumber($data['size']);
+ $data['unencrypted_size'] = Util::numericToNumber($data['unencrypted_size'] ?? 0);
$data['mtime'] = (int)$data['mtime'];
$data['storage_mtime'] = (int)$data['storage_mtime'];
$data['encryptedVersion'] = (int)$data['encrypted'];
@@ -900,7 +901,7 @@ class Cache implements ICache {
*
* @param string $path
* @param array|null|ICacheEntry $entry (optional) meta data of the folder
- * @return int
+ * @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
return $this->calculateFolderSizeInner($path, $entry);
@@ -913,7 +914,7 @@ class Cache implements ICache {
* @param string $path
* @param array|null|ICacheEntry $entry (optional) meta data of the folder
* @param bool $ignoreUnknown don't mark the folder size as unknown if any of it's children are unknown
- * @return int
+ * @return int|float
*/
protected function calculateFolderSizeInner(string $path, $entry = null, bool $ignoreUnknown = false) {
$totalSize = 0;
@@ -937,13 +938,13 @@ class Cache implements ICache {
if ($rows) {
$sizes = array_map(function (array $row) {
- return (int)$row['size'];
+ return Util::numericToNumber($row['size']);
}, $rows);
$unencryptedOnlySizes = array_map(function (array $row) {
- return (int)$row['unencrypted_size'];
+ return Util::numericToNumber($row['unencrypted_size']);
}, $rows);
$unencryptedSizes = array_map(function (array $row) {
- return (int)(($row['unencrypted_size'] > 0) ? $row['unencrypted_size'] : $row['size']);
+ return Util::numericToNumber(($row['unencrypted_size'] > 0) ? $row['unencrypted_size'] : $row['size']);
}, $rows);
$sum = array_sum($sizes);
diff --git a/lib/private/Files/Cache/HomeCache.php b/lib/private/Files/Cache/HomeCache.php
index 9dbbb46c57b..83e5cb89b8a 100644
--- a/lib/private/Files/Cache/HomeCache.php
+++ b/lib/private/Files/Cache/HomeCache.php
@@ -36,7 +36,7 @@ class HomeCache extends Cache {
*
* @param string $path
* @param array|null|ICacheEntry $entry (optional) meta data of the folder
- * @return int
+ * @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin' and $path !== 'files_versions') {
diff --git a/lib/private/Files/Cache/Scanner.php b/lib/private/Files/Cache/Scanner.php
index a34f1db3195..edf9b5697e7 100644
--- a/lib/private/Files/Cache/Scanner.php
+++ b/lib/private/Files/Cache/Scanner.php
@@ -386,7 +386,7 @@ class Scanner extends BasicEmitter implements IScanner {
* @param int $folderId id for the folder to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @param array $data the data of the folder before (re)scanning the children
- * @return int the size of the scanned folder or -1 if the size is unknown at this stage
+ * @return int|float the size of the scanned folder or -1 if the size is unknown at this stage
*/
protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderId = null, $lock = true, array $data = []) {
if ($reuse === -1) {
diff --git a/lib/private/Files/Cache/Wrapper/CacheJail.php b/lib/private/Files/Cache/Wrapper/CacheJail.php
index 2885a8bf5e0..d8cf3eb61d7 100644
--- a/lib/private/Files/Cache/Wrapper/CacheJail.php
+++ b/lib/private/Files/Cache/Wrapper/CacheJail.php
@@ -240,7 +240,7 @@ class CacheJail extends CacheWrapper {
*
* @param string $path
* @param array|null|ICacheEntry $entry (optional) meta data of the folder
- * @return int
+ * @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
if ($this->getCache() instanceof Cache) {
diff --git a/lib/private/Files/Cache/Wrapper/CacheWrapper.php b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
index c1043fbc6fb..6479ea793b0 100644
--- a/lib/private/Files/Cache/Wrapper/CacheWrapper.php
+++ b/lib/private/Files/Cache/Wrapper/CacheWrapper.php
@@ -250,7 +250,7 @@ class CacheWrapper extends Cache {
*
* @param string $path
* @param array|null|ICacheEntry $entry (optional) meta data of the folder
- * @return int
+ * @return int|float
*/
public function calculateFolderSize($path, $entry = null) {
if ($this->getCache() instanceof Cache) {
diff --git a/lib/private/Files/Node/LazyFolder.php b/lib/private/Files/Node/LazyFolder.php
index cc1f64889a1..c843baabade 100644
--- a/lib/private/Files/Node/LazyFolder.php
+++ b/lib/private/Files/Node/LazyFolder.php
@@ -27,6 +27,7 @@ declare(strict_types=1);
namespace OC\Files\Node;
use OC\Files\Utils\PathHelper;
+use OCP\Files\Folder;
use OCP\Constants;
/**
@@ -37,8 +38,8 @@ use OCP\Constants;
*
* @package OC\Files\Node
*/
-class LazyFolder implements \OCP\Files\Folder {
- /** @var \Closure */
+class LazyFolder implements Folder {
+ /** @var \Closure(): Folder */
private $folderClosure;
/** @var LazyFolder | null */
@@ -49,7 +50,7 @@ class LazyFolder implements \OCP\Files\Folder {
/**
* LazyFolder constructor.
*
- * @param \Closure $folderClosure
+ * @param \Closure(): Folder $folderClosure
*/
public function __construct(\Closure $folderClosure, array $data = []) {
$this->folderClosure = $folderClosure;
diff --git a/lib/private/Files/Node/LazyUserFolder.php b/lib/private/Files/Node/LazyUserFolder.php
index 81009532dbf..8fbdec4b49d 100644
--- a/lib/private/Files/Node/LazyUserFolder.php
+++ b/lib/private/Files/Node/LazyUserFolder.php
@@ -28,7 +28,10 @@ use OCP\Constants;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountManager;
use OCP\Files\NotFoundException;
+use OCP\Files\Folder;
+use OCP\Files\File;
use OCP\IUser;
+use Psr\Log\LoggerInterface;
class LazyUserFolder extends LazyFolder {
private IRootFolder $root;
@@ -41,14 +44,22 @@ class LazyUserFolder extends LazyFolder {
$this->user = $user;
$this->mountManager = $mountManager;
$this->path = '/' . $user->getUID() . '/files';
- parent::__construct(function () use ($user) {
+ parent::__construct(function () use ($user): Folder {
try {
- return $this->root->get('/' . $user->getUID() . '/files');
+ $node = $this->root->get($this->path);
+ if ($node instanceof File) {
+ $e = new \RuntimeException();
+ \OCP\Server::get(LoggerInterface::class)->error('User root storage is not a folder: ' . $this->path, [
+ 'exception' => $e,
+ ]);
+ throw $e;
+ }
+ return $node;
} catch (NotFoundException $e) {
if (!$this->root->nodeExists('/' . $user->getUID())) {
$this->root->newFolder('/' . $user->getUID());
}
- return $this->root->newFolder('/' . $user->getUID() . '/files');
+ return $this->root->newFolder($this->path);
}
}, [
'path' => $this->path,
diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
index ea60de137d2..978b5b0451c 100644
--- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php
+++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php
@@ -87,17 +87,13 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
if (isset($params['validateWrites'])) {
$this->validateWrites = (bool)$params['validateWrites'];
}
- //initialize cache with root directory in cache
- if (!$this->is_dir('/')) {
- $this->mkdir('/');
- }
$this->logger = \OC::$server->getLogger();
}
- public function mkdir($path) {
+ public function mkdir($path, bool $force = false) {
$path = $this->normalizePath($path);
- if ($this->file_exists($path)) {
+ if (!$force && $this->file_exists($path)) {
$this->logger->warning("Tried to create an object store folder that already exists: $path");
return false;
}
@@ -246,6 +242,13 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
if ($cacheEntry instanceof CacheEntry) {
return $cacheEntry->getData();
} else {
+ if ($path === '') {
+ $this->mkdir('', true);
+ $cacheEntry = $this->getCache()->get($path);
+ if ($cacheEntry instanceof CacheEntry) {
+ return $cacheEntry->getData();
+ }
+ }
return false;
}
}
@@ -357,6 +360,12 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
case 'wb':
case 'w+':
case 'wb+':
+ $dirName = dirname($path);
+ $parentExists = $this->is_dir($dirName);
+ if (!$parentExists) {
+ return false;
+ }
+
$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
$handle = fopen($tmpFile, $mode);
return CallbackWrapper::wrap($handle, null, null, function () use ($path, $tmpFile) {
@@ -469,6 +478,9 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common implements IChunkedFil
public function file_put_contents($path, $data) {
$handle = $this->fopen($path, 'w+');
+ if (!$handle) {
+ return false;
+ }
$result = fwrite($handle, $data);
fclose($handle);
return $result;
diff --git a/lib/private/Files/Storage/DAV.php b/lib/private/Files/Storage/DAV.php
index 6a05f54a0b4..733aa10cde6 100644
--- a/lib/private/Files/Storage/DAV.php
+++ b/lib/private/Files/Storage/DAV.php
@@ -51,6 +51,7 @@ use OCP\Files\StorageInvalidException;
use OCP\Files\StorageNotAvailableException;
use OCP\Http\Client\IClientService;
use OCP\ICertificateManager;
+use OCP\Util;
use Psr\Http\Message\ResponseInterface;
use Sabre\DAV\Client;
use Sabre\DAV\Xml\Property\ResourceType;
@@ -451,7 +452,7 @@ class DAV extends Common {
return FileInfo::SPACE_UNKNOWN;
}
if (isset($response['{DAV:}quota-available-bytes'])) {
- return (int)$response['{DAV:}quota-available-bytes'];
+ return Util::numericToNumber($response['{DAV:}quota-available-bytes']);
} else {
return FileInfo::SPACE_UNKNOWN;
}
@@ -605,7 +606,7 @@ class DAV extends Common {
}
return [
'mtime' => isset($response['{DAV:}getlastmodified']) ? strtotime($response['{DAV:}getlastmodified']) : null,
- 'size' => (int)($response['{DAV:}getcontentlength'] ?? 0),
+ 'size' => Util::numericToNumber($response['{DAV:}getcontentlength'] ?? 0),
];
} catch (\Exception $e) {
$this->convertException($e, $path);
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index ee86fe356f7..c0ce0e7021a 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -52,6 +52,7 @@ use OCP\Files\GenericFileException;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\Storage\IStorage;
use OCP\IConfig;
+use OCP\Util;
use Psr\Log\LoggerInterface;
/**
@@ -135,10 +136,10 @@ class Local extends \OC\Files\Storage\Common {
if (in_array($file->getBasename(), ['.', '..'])) {
$it->next();
continue;
- } elseif ($file->isDir()) {
- rmdir($file->getPathname());
} elseif ($file->isFile() || $file->isLink()) {
unlink($file->getPathname());
+ } elseif ($file->isDir()) {
+ rmdir($file->getPathname());
}
$it->next();
}
@@ -422,7 +423,7 @@ class Local extends \OC\Files\Storage\Common {
if ($space === false || is_null($space)) {
return \OCP\Files\FileInfo::SPACE_UNKNOWN;
}
- return (int)$space;
+ return Util::numericToNumber($space);
}
public function search($query) {
diff --git a/lib/private/Files/Type/Loader.php b/lib/private/Files/Type/Loader.php
index 32013bc3786..20c298f21b3 100644
--- a/lib/private/Files/Type/Loader.php
+++ b/lib/private/Files/Type/Loader.php
@@ -116,7 +116,7 @@ class Loader implements IMimeTypeLoader {
* @return int inserted ID
*/
protected function store($mimetype) {
- $row = $this->atomic(function () use ($mimetype) {
+ $mimetypeId = $this->atomic(function () use ($mimetype) {
try {
$insert = $this->dbConnection->getQueryBuilder();
$insert->insert('mimetypes')
@@ -124,34 +124,28 @@ class Loader implements IMimeTypeLoader {
'mimetype' => $insert->createNamedParameter($mimetype)
])
->executeStatement();
- return [
- 'mimetype' => $mimetype,
- 'id' => $insert->getLastInsertId(),
- ];
+ return $insert->getLastInsertId();
} catch (DbalException $e) {
if ($e->getReason() !== DBException::REASON_UNIQUE_CONSTRAINT_VIOLATION) {
throw $e;
}
$qb = $this->dbConnection->getQueryBuilder();
- $row = $qb->select('id')
+ $qb->select('id')
->from('mimetypes')
- ->where($qb->expr()->eq('mimetype', $qb->createNamedParameter($mimetype)))
- ->executeQuery()
- ->fetchOne();
- if ($row) {
- return [
- 'mimetype' => $mimetype,
- 'id' => $row['id'],
- ];
+ ->where($qb->expr()->eq('mimetype', $qb->createNamedParameter($mimetype)));
+ $result = $qb->executeQuery();
+ $id = $result->fetchOne();
+ $result->closeCursor();
+ if ($id !== false) {
+ return (int) $id;
}
throw new \Exception("Database threw an unique constraint on inserting a new mimetype, but couldn't return the ID for this very mimetype");
}
}, $this->dbConnection);
- if (!$row) {
+ if (!$mimetypeId) {
throw new \Exception("Failed to get mimetype id for $mimetype after trying to store it");
}
- $mimetypeId = (int) $row['id'];
$this->mimetypes[$mimetypeId] = $mimetype;
$this->mimetypeIds[$mimetype] = $mimetypeId;
diff --git a/lib/private/Installer.php b/lib/private/Installer.php
index 43c3db7c3fd..9b286cc85b0 100644
--- a/lib/private/Installer.php
+++ b/lib/private/Installer.php
@@ -48,6 +48,7 @@ use OC\DB\Connection;
use OC\DB\MigrationService;
use OC_App;
use OC_Helper;
+use OCP\App\IAppManager;
use OCP\HintException;
use OCP\Http\Client\IClientService;
use OCP\IConfig;
@@ -113,7 +114,7 @@ class Installer {
}
$l = \OC::$server->getL10N('core');
- $info = OC_App::getAppInfo($basedir.'/appinfo/info.xml', true, $l->getLanguageCode());
+ $info = \OCP\Server::get(IAppManager::class)->getAppInfo($basedir . '/appinfo/info.xml', true, $l->getLanguageCode());
if (!is_array($info)) {
throw new \Exception(
@@ -164,7 +165,7 @@ class Installer {
OC_App::executeRepairSteps($appId, $info['repair-steps']['install']);
//set the installed version
- \OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id'], false));
+ \OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', \OCP\Server::get(IAppManager::class)->getAppVersion($info['id'], false));
\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no');
//set remote/public handlers
@@ -349,7 +350,7 @@ class Installer {
}
// Check if the version is lower than before
- $currentVersion = OC_App::getAppVersion($appId);
+ $currentVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId, true);
$newVersion = (string)$xml->version;
if (version_compare($currentVersion, $newVersion) === 1) {
throw new \Exception(
@@ -423,7 +424,7 @@ class Installer {
foreach ($this->apps as $app) {
if ($app['id'] === $appId) {
- $currentVersion = OC_App::getAppVersion($appId);
+ $currentVersion = \OCP\Server::get(IAppManager::class)->getAppVersion($appId, true);
if (!isset($app['releases'][0]['version'])) {
return false;
@@ -593,7 +594,7 @@ class Installer {
//run appinfo/install.php
self::includeAppScript("$appPath/appinfo/install.php");
- $info = OC_App::getAppInfo($app);
+ $info = \OCP\Server::get(IAppManager::class)->getAppInfo($app);
if (is_null($info)) {
return false;
}
@@ -601,7 +602,7 @@ class Installer {
OC_App::executeRepairSteps($app, $info['repair-steps']['install']);
- $config->setAppValue($app, 'installed_version', OC_App::getAppVersion($app));
+ $config->setAppValue($app, 'installed_version', \OCP\Server::get(IAppManager::class)->getAppVersion($app));
if (array_key_exists('ocsid', $info)) {
$config->setAppValue($app, 'ocsid', $info['ocsid']);
}
diff --git a/lib/private/Log.php b/lib/private/Log.php
index 99797b938db..c27c42fe271 100644
--- a/lib/private/Log.php
+++ b/lib/private/Log.php
@@ -359,6 +359,7 @@ class Log implements ILogger, IDataLogger {
$context['level'] = $level;
} catch (Throwable $e) {
// make sure we dont hard crash if logging fails
+ error_log('Error when trying to log exception: ' . $e->getMessage() . ' ' . $e->getTraceAsString());
}
}
diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php
index b6f96fffba4..bde25a3385a 100644
--- a/lib/private/Memcache/Redis.php
+++ b/lib/private/Memcache/Redis.php
@@ -32,6 +32,22 @@ namespace OC\Memcache;
use OCP\IMemcacheTTL;
class Redis extends Cache implements IMemcacheTTL {
+ /** name => [script, sha1] */
+ public const LUA_SCRIPTS = [
+ 'dec' => [
+ 'if redis.call("exists", KEYS[1]) == 1 then return redis.call("decrby", KEYS[1], ARGV[1]) else return "NEX" end',
+ '720b40cb66cef1579f2ef16ec69b3da8c85510e9',
+ ],
+ 'cas' => [
+ 'if redis.call("get", KEYS[1]) == ARGV[1] then redis.call("set", KEYS[1], ARGV[2]) return 1 else return 0 end',
+ '94eac401502554c02b811e3199baddde62d976d4',
+ ],
+ 'cad' => [
+ 'if redis.call("get", KEYS[1]) == ARGV[1] then return redis.call("del", KEYS[1]) else return 0 end',
+ 'cf0e94b2e9ffc7e04395cf88f7583fc309985910',
+ ],
+ ];
+
/**
* @var \Redis|\RedisCluster $cache
*/
@@ -54,18 +70,19 @@ class Redis extends Cache implements IMemcacheTTL {
public function get($key) {
$result = $this->getCache()->get($this->getPrefix() . $key);
- if ($result === false && !$this->getCache()->exists($this->getPrefix() . $key)) {
+ if ($result === false) {
return null;
- } else {
- return json_decode($result, true);
}
+
+ return self::decodeValue($result);
}
public function set($key, $value, $ttl = 0) {
+ $value = self::encodeValue($value);
if ($ttl > 0) {
- return $this->getCache()->setex($this->getPrefix() . $key, $ttl, json_encode($value));
+ return $this->getCache()->setex($this->getPrefix() . $key, $ttl, $value);
} else {
- return $this->getCache()->set($this->getPrefix() . $key, json_encode($value));
+ return $this->getCache()->set($this->getPrefix() . $key, $value);
}
}
@@ -82,6 +99,7 @@ class Redis extends Cache implements IMemcacheTTL {
}
public function clear($prefix = '') {
+ // TODO: this is slow and would fail with Redis cluster
$prefix = $this->getPrefix() . $prefix . '*';
$keys = $this->getCache()->keys($prefix);
$deleted = $this->getCache()->del($keys);
@@ -98,17 +116,14 @@ class Redis extends Cache implements IMemcacheTTL {
* @return bool
*/
public function add($key, $value, $ttl = 0) {
- // don't encode ints for inc/dec
- if (!is_int($value)) {
- $value = json_encode($value);
- }
+ $value = self::encodeValue($value);
$args = ['nx'];
if ($ttl !== 0 && is_int($ttl)) {
$args['ex'] = $ttl;
}
- return $this->getCache()->set($this->getPrefix() . $key, (string)$value, $args);
+ return $this->getCache()->set($this->getPrefix() . $key, $value, $args);
}
/**
@@ -130,10 +145,8 @@ class Redis extends Cache implements IMemcacheTTL {
* @return int | bool
*/
public function dec($key, $step = 1) {
- if (!$this->hasKey($key)) {
- return false;
- }
- return $this->getCache()->decrBy($this->getPrefix() . $key, $step);
+ $res = $this->evalLua('dec', [$key], [$step]);
+ return ($res === 'NEX') ? false : $res;
}
/**
@@ -145,18 +158,10 @@ class Redis extends Cache implements IMemcacheTTL {
* @return bool
*/
public function cas($key, $old, $new) {
- if (!is_int($new)) {
- $new = json_encode($new);
- }
- $this->getCache()->watch($this->getPrefix() . $key);
- if ($this->get($key) === $old) {
- $result = $this->getCache()->multi()
- ->set($this->getPrefix() . $key, $new)
- ->exec();
- return $result !== false;
- }
- $this->getCache()->unwatch();
- return false;
+ $old = self::encodeValue($old);
+ $new = self::encodeValue($new);
+
+ return $this->evalLua('cas', [$key], [$old, $new]) > 0;
}
/**
@@ -167,15 +172,9 @@ class Redis extends Cache implements IMemcacheTTL {
* @return bool
*/
public function cad($key, $old) {
- $this->getCache()->watch($this->getPrefix() . $key);
- if ($this->get($key) === $old) {
- $result = $this->getCache()->multi()
- ->unlink($this->getPrefix() . $key)
- ->exec();
- return $result !== false;
- }
- $this->getCache()->unwatch();
- return false;
+ $old = self::encodeValue($old);
+
+ return $this->evalLua('cad', [$key], [$old]) > 0;
}
public function setTTL($key, $ttl) {
@@ -185,4 +184,25 @@ class Redis extends Cache implements IMemcacheTTL {
public static function isAvailable(): bool {
return \OC::$server->getGetRedisFactory()->isAvailable();
}
+
+ protected function evalLua(string $scriptName, array $keys, array $args) {
+ $keys = array_map(fn ($key) => $this->getPrefix() . $key, $keys);
+ $args = array_merge($keys, $args);
+ $script = self::LUA_SCRIPTS[$scriptName];
+
+ $result = $this->getCache()->evalSha($script[1], $args, count($keys));
+ if (false === $result) {
+ $result = $this->getCache()->eval($script[0], $args, count($keys));
+ }
+
+ return $result;
+ }
+
+ protected static function encodeValue(mixed $value): string {
+ return is_int($value) ? (string) $value : json_encode($value);
+ }
+
+ protected static function decodeValue(string $value): mixed {
+ return is_numeric($value) ? (int) $value : json_decode($value, true);
+ }
}
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 3ed263b7826..3ce44913498 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -172,6 +172,10 @@ class Generator {
[$maxWidth, $maxHeight] = $this->getPreviewSize($maxPreview, $previewVersion);
+ if ($maxWidth <= 0 || $maxHeight <= 0) {
+ throw new NotFoundException('The maximum preview sizes are zero or less pixels');
+ }
+
$preview = null;
foreach ($specifications as $specification) {
diff --git a/lib/private/Preview/Imaginary.php b/lib/private/Preview/Imaginary.php
index ed8b9eaa838..74f04e09250 100644
--- a/lib/private/Preview/Imaginary.php
+++ b/lib/private/Preview/Imaginary.php
@@ -136,9 +136,10 @@ class Imaginary extends ProviderV2 {
];
try {
+ $imaginaryKey = $this->config->getSystemValueString('preview_imaginary_key', '');
$response = $httpClient->post(
$imaginaryUrl . '/pipeline', [
- 'query' => ['operations' => json_encode($operations)],
+ 'query' => ['operations' => json_encode($operations), 'key' => $imaginaryKey],
'stream' => true,
'content-type' => $file->getMimeType(),
'body' => $stream,
diff --git a/lib/private/Preview/MP3.php b/lib/private/Preview/MP3.php
index 47d752af477..ff6ff86c966 100644
--- a/lib/private/Preview/MP3.php
+++ b/lib/private/Preview/MP3.php
@@ -32,6 +32,7 @@ use ID3Parser\ID3Parser;
use OCP\Files\File;
use OCP\IImage;
+use Psr\Log\LoggerInterface;
class MP3 extends ProviderV2 {
/**
@@ -48,8 +49,18 @@ class MP3 extends ProviderV2 {
$getID3 = new ID3Parser();
$tmpPath = $this->getLocalFile($file);
- $tags = $getID3->analyze($tmpPath);
- $this->cleanTmpFiles();
+ try {
+ $tags = $getID3->analyze($tmpPath);
+ } catch (\Throwable $e) {
+ \OC::$server->get(LoggerInterface::class)->info($e->getMessage(), [
+ 'exception' => $e,
+ 'app' => 'core',
+ ]);
+ return null;
+ } finally {
+ $this->cleanTmpFiles();
+ }
+
$picture = isset($tags['id3v2']['APIC'][0]['data']) ? $tags['id3v2']['APIC'][0]['data'] : null;
if (is_null($picture) && isset($tags['id3v2']['PIC'][0]['data'])) {
$picture = $tags['id3v2']['PIC'][0]['data'];
diff --git a/lib/private/RedisFactory.php b/lib/private/RedisFactory.php
index 5c38ed0807d..6b509b1c1a9 100644
--- a/lib/private/RedisFactory.php
+++ b/lib/private/RedisFactory.php
@@ -72,8 +72,8 @@ class RedisFactory {
}
$auth = null;
- if (isset($config['password']) && $config['password'] !== '') {
- if (isset($config['user']) && $config['user'] !== '') {
+ if (isset($config['password']) && (string)$config['password'] !== '') {
+ if (isset($config['user']) && (string)$config['user'] !== '') {
$auth = [$config['user'], $config['password']];
} else {
$auth = $config['password'];
diff --git a/lib/private/Repair/ClearGeneratedAvatarCache.php b/lib/private/Repair/ClearGeneratedAvatarCache.php
index 844bf6cf346..fb3b42847dc 100644
--- a/lib/private/Repair/ClearGeneratedAvatarCache.php
+++ b/lib/private/Repair/ClearGeneratedAvatarCache.php
@@ -42,7 +42,7 @@ class ClearGeneratedAvatarCache implements IRepairStep {
}
public function getName(): string {
- return 'Clear every generated avatar on major updates';
+ return 'Clear every generated avatar';
}
/**
@@ -51,8 +51,9 @@ class ClearGeneratedAvatarCache implements IRepairStep {
private function shouldRun(): bool {
$versionFromBeforeUpdate = $this->config->getSystemValueString('version', '0.0.0.0');
- // was added to 25.0.0.10
- return version_compare($versionFromBeforeUpdate, '25.0.0.10', '<=');
+ // This job only runs if the server was on a version lower than or equal to 27.0.0 before the upgrade.
+ // To clear the avatar cache again, bump the version to the currently released version (and change the operator to <= if it's not the master branch) and wait for the next release.
+ return version_compare($versionFromBeforeUpdate, '27.0.0', '<');
}
public function run(IOutput $output): void {
diff --git a/lib/private/Security/CertificateManager.php b/lib/private/Security/CertificateManager.php
index b9fbdcc9f02..3a87b7f1a00 100644
--- a/lib/private/Security/CertificateManager.php
+++ b/lib/private/Security/CertificateManager.php
@@ -83,8 +83,14 @@ class CertificateManager implements ICertificateManager {
while (false !== ($file = readdir($handle))) {
if ($file != '.' && $file != '..') {
try {
- $result[] = new Certificate($this->view->file_get_contents($path . $file), $file);
+ $content = $this->view->file_get_contents($path . $file);
+ if ($content !== false) {
+ $result[] = new Certificate($content, $file);
+ } else {
+ $this->logger->error("Failed to read certificate from $path");
+ }
} catch (\Exception $e) {
+ $this->logger->error("Failed to read certificate from $path", ['exception' => $e]);
}
}
}
diff --git a/lib/private/Server.php b/lib/private/Server.php
index bb4e217efa3..84860f8c494 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -730,7 +730,13 @@ class Server extends ServerContainer implements IServerContainer {
if ($config->getSystemValueBool('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
if (!$config->getSystemValueBool('log_query')) {
- $v = \OC_App::getAppVersions();
+ try {
+ $v = \OC_App::getAppVersions();
+ } catch (\Doctrine\DBAL\Exception $e) {
+ // Database service probably unavailable
+ // Probably related to https://github.com/nextcloud/server/issues/37424
+ return $arrayCacheFactory;
+ }
} else {
// If the log_query is enabled, we can not get the app versions
// as that does a query, which will be logged and the logging
diff --git a/lib/private/Template/JSResourceLocator.php b/lib/private/Template/JSResourceLocator.php
index ab5de182d89..b283f0b610f 100644
--- a/lib/private/Template/JSResourceLocator.php
+++ b/lib/private/Template/JSResourceLocator.php
@@ -100,7 +100,7 @@ class JSResourceLocator extends ResourceLocator {
$app_path = realpath($app_path);
// check combined files
- if ($this->cacheAndAppendCombineJsonIfExist($app_path, $script.'.json', $app)) {
+ if (!str_starts_with($script, 'l10n/') && $this->cacheAndAppendCombineJsonIfExist($app_path, $script.'.json', $app)) {
return;
}
diff --git a/lib/private/Updater.php b/lib/private/Updater.php
index 56285166322..5a14bb17507 100644
--- a/lib/private/Updater.php
+++ b/lib/private/Updater.php
@@ -40,6 +40,7 @@ declare(strict_types=1);
*/
namespace OC;
+use OCP\App\IAppManager;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\HintException;
@@ -355,9 +356,9 @@ class Updater extends BasicEmitter {
$stack = $stacks[$type];
foreach ($stack as $appId) {
if (\OC_App::shouldUpgrade($appId)) {
- $this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OC_App::getAppVersion($appId)]);
+ $this->emit('\OC\Updater', 'appUpgradeStarted', [$appId, \OCP\Server::get(IAppManager::class)->getAppVersion($appId)]);
\OC_App::updateApp($appId);
- $this->emit('\OC\Updater', 'appUpgrade', [$appId, \OC_App::getAppVersion($appId)]);
+ $this->emit('\OC\Updater', 'appUpgrade', [$appId, \OCP\Server::get(IAppManager::class)->getAppVersion($appId)]);
}
if ($type !== $pseudoOtherType) {
// load authentication, filesystem and logging apps after
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index bdc9a4d6fb7..b7f3b0e3740 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -571,7 +571,7 @@ class User implements IUser {
}
$avatar = $this->avatarManager->getAvatar($this->uid);
- $image = $avatar->get(-1);
+ $image = $avatar->get($size);
if ($image) {
return $image;
}
diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php
index d790c1c2261..a1aeb50bbf4 100644
--- a/lib/private/legacy/OC_App.php
+++ b/lib/private/legacy/OC_App.php
@@ -242,19 +242,6 @@ class OC_App {
}
/**
- * checks whether or not an app is enabled
- *
- * @param string $app app
- * @return bool
- * @deprecated 13.0.0 use \OC::$server->getAppManager()->isEnabledForUser($appId)
- *
- * This function checks whether or not an app is enabled.
- */
- public static function isEnabled(string $app): bool {
- return \OC::$server->getAppManager()->isEnabledForUser($app);
- }
-
- /**
* enables an app
*
* @param string $appId
@@ -396,18 +383,6 @@ class OC_App {
}
/**
- * get the last version of the app from appinfo/info.xml
- *
- * @param string $appId
- * @param bool $useCache
- * @return string
- * @deprecated 14.0.0 use \OC::$server->getAppManager()->getAppVersion()
- */
- public static function getAppVersion(string $appId, bool $useCache = true): string {
- return \OC::$server->getAppManager()->getAppVersion($appId, $useCache);
- }
-
- /**
* get app's version based on it's path
*
* @param string $path
@@ -419,49 +394,6 @@ class OC_App {
return isset($appData['version']) ? $appData['version'] : '';
}
-
- /**
- * Read all app metadata from the info.xml file
- *
- * @param string $appId id of the app or the path of the info.xml file
- * @param bool $path
- * @param string $lang
- * @return array|null
- * @note all data is read from info.xml, not just pre-defined fields
- * @deprecated 14.0.0 use \OC::$server->getAppManager()->getAppInfo()
- */
- public static function getAppInfo(string $appId, bool $path = false, string $lang = null) {
- return \OC::$server->getAppManager()->getAppInfo($appId, $path, $lang);
- }
-
- /**
- * Returns the navigation
- *
- * @return array
- * @deprecated 14.0.0 use \OC::$server->getNavigationManager()->getAll()
- *
- * This function returns an array containing all entries added. The
- * entries are sorted by the key 'order' ascending. Additional to the keys
- * given for each app the following keys exist:
- * - active: boolean, signals if the user is on this navigation entry
- */
- public static function getNavigation(): array {
- return OC::$server->getNavigationManager()->getAll();
- }
-
- /**
- * Returns the Settings Navigation
- *
- * @return string[]
- * @deprecated 14.0.0 use \OC::$server->getNavigationManager()->getAll('settings')
- *
- * This function returns an array containing all settings pages added. The
- * entries are sorted by the key 'order' ascending.
- */
- public static function getSettingsNavigation(): array {
- return OC::$server->getNavigationManager()->getAll('settings');
- }
-
/**
* get the id of loaded app
*
@@ -634,7 +566,7 @@ class OC_App {
foreach ($installedApps as $app) {
if (array_search($app, $blacklist) === false) {
- $info = OC_App::getAppInfo($app, false, $langCode);
+ $info = $appManager->getAppInfo($app, false, $langCode);
if (!is_array($info)) {
\OCP\Util::writeLog('core', 'Could not read app info file for app "' . $app . '"', ILogger::ERROR);
continue;
@@ -698,7 +630,7 @@ class OC_App {
}
}
- $info['version'] = OC_App::getAppVersion($app);
+ $info['version'] = $appManager->getAppVersion($app);
$appList[] = $info;
}
}
@@ -708,7 +640,7 @@ class OC_App {
public static function shouldUpgrade(string $app): bool {
$versions = self::getAppVersions();
- $currentVersion = OC_App::getAppVersion($app);
+ $currentVersion = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppVersion($app);
if ($currentVersion && isset($versions[$app])) {
$installedVersion = $versions[$app];
if (!version_compare($currentVersion, $installedVersion, '=')) {
@@ -826,7 +758,7 @@ class OC_App {
\OC::$server->getAppManager()->clearAppsCache();
$l = \OC::$server->getL10N('core');
- $appData = self::getAppInfo($appId, false, $l->getLanguageCode());
+ $appData = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppInfo($appId, false, $l->getLanguageCode());
$ignoreMaxApps = \OC::$server->getConfig()->getSystemValue('app_install_overwrite', []);
$ignoreMax = in_array($appId, $ignoreMaxApps, true);
@@ -866,7 +798,7 @@ class OC_App {
self::setAppTypes($appId);
- $version = \OC_App::getAppVersion($appId);
+ $version = \OCP\Server::get(\OCP\App\IAppManager::class)->getAppVersion($appId);
\OC::$server->getConfig()->setAppValue($appId, 'installed_version', $version);
\OC::$server->get(IEventDispatcher::class)->dispatchTyped(new AppUpdateEvent($appId));
diff --git a/lib/private/legacy/OC_Defaults.php b/lib/private/legacy/OC_Defaults.php
index 707df7279bb..ce89a642741 100644
--- a/lib/private/legacy/OC_Defaults.php
+++ b/lib/private/legacy/OC_Defaults.php
@@ -245,15 +245,6 @@ class OC_Defaults {
}
/**
- * Returns logo claim
- * @return string logo claim
- * @deprecated 13.0.0
- */
- public function getLogoClaim() {
- return '';
- }
-
- /**
* Returns short version of the footer
* @return string short footer
*/
diff --git a/lib/private/legacy/OC_Helper.php b/lib/private/legacy/OC_Helper.php
index 07d81933d00..8c8be0e1069 100644
--- a/lib/private/legacy/OC_Helper.php
+++ b/lib/private/legacy/OC_Helper.php
@@ -487,7 +487,7 @@ class OC_Helper {
$rootInfo = \OC\Files\Filesystem::getFileInfo($path, $includeExtStorage ? 'ext' : false);
}
if (!$rootInfo instanceof \OCP\Files\FileInfo) {
- throw new \OCP\Files\NotFoundException();
+ throw new \OCP\Files\NotFoundException('The root directory of the user\'s files is missing');
}
$used = $rootInfo->getSize($includeMountPoints);
if ($used < 0) {