summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php4
-rw-r--r--lib/composer/composer/autoload_static.php4
-rw-r--r--lib/l10n/es.js2
-rw-r--r--lib/l10n/es.json2
-rw-r--r--lib/l10n/he.js4
-rw-r--r--lib/l10n/he.json4
-rw-r--r--lib/l10n/pt_BR.js1
-rw-r--r--lib/l10n/pt_BR.json1
-rw-r--r--lib/private/App/AppStore/Fetcher/AppFetcher.php4
-rw-r--r--lib/private/DB/Adapter.php10
-rw-r--r--lib/private/DB/Connection.php25
-rw-r--r--lib/private/DB/ConnectionAdapter.php118
-rw-r--r--lib/private/DB/Exceptions/DbalException.php136
-rw-r--r--lib/private/DB/Migrator.php7
-rw-r--r--lib/private/DB/QueryBuilder/QueryBuilder.php30
-rw-r--r--lib/private/Files/Storage/Local.php5
-rw-r--r--lib/private/IntegrityCheck/Checker.php29
-rw-r--r--lib/private/Log/ExceptionSerializer.php1
-rw-r--r--lib/private/Preview/MarkDown.php110
-rw-r--r--lib/private/Preview/WebP.php42
-rw-r--r--lib/private/PreviewManager.php4
-rw-r--r--lib/private/Server.php3
-rw-r--r--lib/private/Setup/MySQL.php3
-rw-r--r--lib/private/legacy/OC_Image.php9
-rw-r--r--lib/public/AppFramework/Bootstrap/IRegistrationContext.php3
-rw-r--r--lib/public/DB/Exception.php149
-rw-r--r--lib/public/DB/QueryBuilder/IQueryBuilder.php2
-rw-r--r--lib/public/EventDispatcher/IEventDispatcher.php6
-rw-r--r--lib/public/IDBConnection.php15
-rw-r--r--lib/public/User/Events/UserLoggedInEvent.php13
30 files changed, 687 insertions, 59 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index dc5f9dc9e8e..6d93d8c1d51 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -161,6 +161,7 @@ return array(
'OCP\\Contacts\\ContactsMenu\\IProvider' => $baseDir . '/lib/public/Contacts/ContactsMenu/IProvider.php',
'OCP\\Contacts\\Events\\ContactInteractedWithEvent' => $baseDir . '/lib/public/Contacts/Events/ContactInteractedWithEvent.php',
'OCP\\Contacts\\IManager' => $baseDir . '/lib/public/Contacts/IManager.php',
+ 'OCP\\DB\\Exception' => $baseDir . '/lib/public/DB/Exception.php',
'OCP\\DB\\IPreparedStatement' => $baseDir . '/lib/public/DB/IPreparedStatement.php',
'OCP\\DB\\IResult' => $baseDir . '/lib/public/DB/IResult.php',
'OCP\\DB\\ISchemaWrapper' => $baseDir . '/lib/public/DB/ISchemaWrapper.php',
@@ -943,6 +944,7 @@ return array(
'OC\\Core\\Migrations\\Version20000Date20201111081915' => $baseDir . '/core/Migrations/Version20000Date20201111081915.php',
'OC\\Core\\Migrations\\Version21000Date20201120141228' => $baseDir . '/core/Migrations/Version21000Date20201120141228.php',
'OC\\Core\\Migrations\\Version21000Date20201202095923' => $baseDir . '/core/Migrations/Version21000Date20201202095923.php',
+ 'OC\\Core\\Migrations\\Version21000Date20210119195004' => $baseDir . '/core/Migrations/Version21000Date20210119195004.php',
'OC\\Core\\Notification\\CoreNotifier' => $baseDir . '/core/Notification/CoreNotifier.php',
'OC\\Core\\Service\\LoginFlowV2Service' => $baseDir . '/core/Service/LoginFlowV2Service.php',
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',
@@ -953,6 +955,7 @@ return array(
'OC\\DB\\Connection' => $baseDir . '/lib/private/DB/Connection.php',
'OC\\DB\\ConnectionAdapter' => $baseDir . '/lib/private/DB/ConnectionAdapter.php',
'OC\\DB\\ConnectionFactory' => $baseDir . '/lib/private/DB/ConnectionFactory.php',
+ 'OC\\DB\\Exceptions\\DbalException' => $baseDir . '/lib/private/DB/Exceptions/DbalException.php',
'OC\\DB\\MDB2SchemaManager' => $baseDir . '/lib/private/DB/MDB2SchemaManager.php',
'OC\\DB\\MDB2SchemaReader' => $baseDir . '/lib/private/DB/MDB2SchemaReader.php',
'OC\\DB\\MigrationException' => $baseDir . '/lib/private/DB/MigrationException.php',
@@ -1251,6 +1254,7 @@ return array(
'OC\\Preview\\TXT' => $baseDir . '/lib/private/Preview/TXT.php',
'OC\\Preview\\Watcher' => $baseDir . '/lib/private/Preview/Watcher.php',
'OC\\Preview\\WatcherConnector' => $baseDir . '/lib/private/Preview/WatcherConnector.php',
+ 'OC\\Preview\\WebP' => $baseDir . '/lib/private/Preview/WebP.php',
'OC\\Preview\\XBitmap' => $baseDir . '/lib/private/Preview/XBitmap.php',
'OC\\RedisFactory' => $baseDir . '/lib/private/RedisFactory.php',
'OC\\Remote\\Api\\ApiBase' => $baseDir . '/lib/private/Remote/Api/ApiBase.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 455fb01b18e..2b6aa27ea46 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -190,6 +190,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\Contacts\\ContactsMenu\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Contacts/ContactsMenu/IProvider.php',
'OCP\\Contacts\\Events\\ContactInteractedWithEvent' => __DIR__ . '/../../..' . '/lib/public/Contacts/Events/ContactInteractedWithEvent.php',
'OCP\\Contacts\\IManager' => __DIR__ . '/../../..' . '/lib/public/Contacts/IManager.php',
+ 'OCP\\DB\\Exception' => __DIR__ . '/../../..' . '/lib/public/DB/Exception.php',
'OCP\\DB\\IPreparedStatement' => __DIR__ . '/../../..' . '/lib/public/DB/IPreparedStatement.php',
'OCP\\DB\\IResult' => __DIR__ . '/../../..' . '/lib/public/DB/IResult.php',
'OCP\\DB\\ISchemaWrapper' => __DIR__ . '/../../..' . '/lib/public/DB/ISchemaWrapper.php',
@@ -972,6 +973,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Core\\Migrations\\Version20000Date20201111081915' => __DIR__ . '/../../..' . '/core/Migrations/Version20000Date20201111081915.php',
'OC\\Core\\Migrations\\Version21000Date20201120141228' => __DIR__ . '/../../..' . '/core/Migrations/Version21000Date20201120141228.php',
'OC\\Core\\Migrations\\Version21000Date20201202095923' => __DIR__ . '/../../..' . '/core/Migrations/Version21000Date20201202095923.php',
+ 'OC\\Core\\Migrations\\Version21000Date20210119195004' => __DIR__ . '/../../..' . '/core/Migrations/Version21000Date20210119195004.php',
'OC\\Core\\Notification\\CoreNotifier' => __DIR__ . '/../../..' . '/core/Notification/CoreNotifier.php',
'OC\\Core\\Service\\LoginFlowV2Service' => __DIR__ . '/../../..' . '/core/Service/LoginFlowV2Service.php',
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',
@@ -982,6 +984,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\DB\\Connection' => __DIR__ . '/../../..' . '/lib/private/DB/Connection.php',
'OC\\DB\\ConnectionAdapter' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionAdapter.php',
'OC\\DB\\ConnectionFactory' => __DIR__ . '/../../..' . '/lib/private/DB/ConnectionFactory.php',
+ 'OC\\DB\\Exceptions\\DbalException' => __DIR__ . '/../../..' . '/lib/private/DB/Exceptions/DbalException.php',
'OC\\DB\\MDB2SchemaManager' => __DIR__ . '/../../..' . '/lib/private/DB/MDB2SchemaManager.php',
'OC\\DB\\MDB2SchemaReader' => __DIR__ . '/../../..' . '/lib/private/DB/MDB2SchemaReader.php',
'OC\\DB\\MigrationException' => __DIR__ . '/../../..' . '/lib/private/DB/MigrationException.php',
@@ -1280,6 +1283,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Preview\\TXT' => __DIR__ . '/../../..' . '/lib/private/Preview/TXT.php',
'OC\\Preview\\Watcher' => __DIR__ . '/../../..' . '/lib/private/Preview/Watcher.php',
'OC\\Preview\\WatcherConnector' => __DIR__ . '/../../..' . '/lib/private/Preview/WatcherConnector.php',
+ 'OC\\Preview\\WebP' => __DIR__ . '/../../..' . '/lib/private/Preview/WebP.php',
'OC\\Preview\\XBitmap' => __DIR__ . '/../../..' . '/lib/private/Preview/XBitmap.php',
'OC\\RedisFactory' => __DIR__ . '/../../..' . '/lib/private/RedisFactory.php',
'OC\\Remote\\Api\\ApiBase' => __DIR__ . '/../../..' . '/lib/private/Remote/Api/ApiBase.php',
diff --git a/lib/l10n/es.js b/lib/l10n/es.js
index b8f5d958e55..dfc39ec74c5 100644
--- a/lib/l10n/es.js
+++ b/lib/l10n/es.js
@@ -167,7 +167,7 @@ OC.L10N.register(
"Oct." : "Oct.",
"Nov." : "Nov.",
"Dec." : "Dic.",
- "The user limit has been reached and the user was not created." : "Ha sido alcanzado el límite de usuarios y el usuario no fue creado.",
+ "The user limit has been reached and the user was not created." : "Ha sido alcanzado el límite de usuarios, por tanto el usuario no fue creado.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Solo los siguientes caracteres están permitidos en un nombre de usuario: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"",
"A valid username must be provided" : "Se debe proporcionar un nombre de usuario válido",
"Username contains whitespace at the beginning or at the end" : "El nombre de usuario contiene espacios en blanco al principio o al final",
diff --git a/lib/l10n/es.json b/lib/l10n/es.json
index 45a3411570d..04dda45afe3 100644
--- a/lib/l10n/es.json
+++ b/lib/l10n/es.json
@@ -165,7 +165,7 @@
"Oct." : "Oct.",
"Nov." : "Nov.",
"Dec." : "Dic.",
- "The user limit has been reached and the user was not created." : "Ha sido alcanzado el límite de usuarios y el usuario no fue creado.",
+ "The user limit has been reached and the user was not created." : "Ha sido alcanzado el límite de usuarios, por tanto el usuario no fue creado.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Solo los siguientes caracteres están permitidos en un nombre de usuario: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"",
"A valid username must be provided" : "Se debe proporcionar un nombre de usuario válido",
"Username contains whitespace at the beginning or at the end" : "El nombre de usuario contiene espacios en blanco al principio o al final",
diff --git a/lib/l10n/he.js b/lib/l10n/he.js
index ae304992bbe..7b8b82269d3 100644
--- a/lib/l10n/he.js
+++ b/lib/l10n/he.js
@@ -10,6 +10,7 @@ OC.L10N.register(
"The files of the app %1$s were not replaced correctly. Make sure it is a version compatible with the server." : "הקבצים של היישומון %1$s לא מוקמו במקום הנכון. נא לוודא שזו גרסה שהשרת תומך בה.",
"Sample configuration detected" : "התגלתה דוגמת תצורה",
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "התגלה שדוגמת התצורה הועתקה. דבר זה עלול לשבור את ההתקנה ולא נתמך.יש לקרוא את מסמכי התיעוד לפני שמבצעים שינויים ב- config.php",
+ "Other activities" : "פעילויות אחרות",
"Education Edition" : "מהדורה חינוכית",
"Enterprise bundle" : "מהדורה מסחרית",
"Groupware bundle" : "מהדורה קבוצתית",
@@ -46,7 +47,7 @@ OC.L10N.register(
"_in %n minute_::_in %n minutes_" : ["בעוד דקה","בעוד 2 דקות","בעוד %n דקות","בעוד %n דקות"],
"_%n minute ago_::_%n minutes ago_" : ["לפני דקה","לפני 2 דקות","לפני %n דקות","לפני %n דקות"],
"in a few seconds" : "בעוד מספר שניות",
- "seconds ago" : "שניות",
+ "seconds ago" : "לפני מספר שניות",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "המודול עם המזהה: %s לא קיים. נא להפעיל אותו בהגדרות היישומונים שלך או ליצור קשר עם מנהל המערכת.",
"File name is a reserved word" : "שם קובץ הוא מילה שמורה",
"File name contains at least one invalid character" : "שם הקובץ כולל לפחות תו אחד לא חוקי",
@@ -145,6 +146,7 @@ OC.L10N.register(
"A valid username must be provided" : "יש לספק שם משתמש תקני",
"Username contains whitespace at the beginning or at the end" : "שם המשתמש מכיל רווח בתחילתו או בסופו",
"Username must not consist of dots only" : "שם המשתמש לא יכול להיות מורכב מנקודות בלבד",
+ "Username is invalid because files already exist for this user" : "שם המשתמש שגוי כיוון שכבר קיימים קבצים למשתמש הזה",
"A valid password must be provided" : "יש לספק ססמה תקנית",
"The username is already being used" : "השם משתמש כבר בשימוש",
"Could not create user" : "לא ניתן ליצור משתמש",
diff --git a/lib/l10n/he.json b/lib/l10n/he.json
index 0b1fc1917cf..ca5382f2041 100644
--- a/lib/l10n/he.json
+++ b/lib/l10n/he.json
@@ -8,6 +8,7 @@
"The files of the app %1$s were not replaced correctly. Make sure it is a version compatible with the server." : "הקבצים של היישומון %1$s לא מוקמו במקום הנכון. נא לוודא שזו גרסה שהשרת תומך בה.",
"Sample configuration detected" : "התגלתה דוגמת תצורה",
"It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "התגלה שדוגמת התצורה הועתקה. דבר זה עלול לשבור את ההתקנה ולא נתמך.יש לקרוא את מסמכי התיעוד לפני שמבצעים שינויים ב- config.php",
+ "Other activities" : "פעילויות אחרות",
"Education Edition" : "מהדורה חינוכית",
"Enterprise bundle" : "מהדורה מסחרית",
"Groupware bundle" : "מהדורה קבוצתית",
@@ -44,7 +45,7 @@
"_in %n minute_::_in %n minutes_" : ["בעוד דקה","בעוד 2 דקות","בעוד %n דקות","בעוד %n דקות"],
"_%n minute ago_::_%n minutes ago_" : ["לפני דקה","לפני 2 דקות","לפני %n דקות","לפני %n דקות"],
"in a few seconds" : "בעוד מספר שניות",
- "seconds ago" : "שניות",
+ "seconds ago" : "לפני מספר שניות",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "המודול עם המזהה: %s לא קיים. נא להפעיל אותו בהגדרות היישומונים שלך או ליצור קשר עם מנהל המערכת.",
"File name is a reserved word" : "שם קובץ הוא מילה שמורה",
"File name contains at least one invalid character" : "שם הקובץ כולל לפחות תו אחד לא חוקי",
@@ -143,6 +144,7 @@
"A valid username must be provided" : "יש לספק שם משתמש תקני",
"Username contains whitespace at the beginning or at the end" : "שם המשתמש מכיל רווח בתחילתו או בסופו",
"Username must not consist of dots only" : "שם המשתמש לא יכול להיות מורכב מנקודות בלבד",
+ "Username is invalid because files already exist for this user" : "שם המשתמש שגוי כיוון שכבר קיימים קבצים למשתמש הזה",
"A valid password must be provided" : "יש לספק ססמה תקנית",
"The username is already being used" : "השם משתמש כבר בשימוש",
"Could not create user" : "לא ניתן ליצור משתמש",
diff --git a/lib/l10n/pt_BR.js b/lib/l10n/pt_BR.js
index 8e99127b62c..33186b7f293 100644
--- a/lib/l10n/pt_BR.js
+++ b/lib/l10n/pt_BR.js
@@ -167,6 +167,7 @@ OC.L10N.register(
"Oct." : "Out.",
"Nov." : "Nov.",
"Dec." : "Dez.",
+ "The user limit has been reached and the user was not created." : "O limite de usuários foi atingido e o usuário não foi criado.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Somente os seguintes caracteres são permitidos em um nome de usuário: \"a-z\", \"A-Z\", \"0-9\", e \"_.@-'\"",
"A valid username must be provided" : "Um nome de usuário válido deve ser fornecido",
"Username contains whitespace at the beginning or at the end" : "O nome de usuário contém espaço em branco no início ou no fim",
diff --git a/lib/l10n/pt_BR.json b/lib/l10n/pt_BR.json
index d33c4f9d7dd..73ba5f793ba 100644
--- a/lib/l10n/pt_BR.json
+++ b/lib/l10n/pt_BR.json
@@ -165,6 +165,7 @@
"Oct." : "Out.",
"Nov." : "Nov.",
"Dec." : "Dez.",
+ "The user limit has been reached and the user was not created." : "O limite de usuários foi atingido e o usuário não foi criado.",
"Only the following characters are allowed in a username: \"a-z\", \"A-Z\", \"0-9\", and \"_.@-'\"" : "Somente os seguintes caracteres são permitidos em um nome de usuário: \"a-z\", \"A-Z\", \"0-9\", e \"_.@-'\"",
"A valid username must be provided" : "Um nome de usuário válido deve ser fornecido",
"Username contains whitespace at the beginning or at the end" : "O nome de usuário contém espaço em branco no início ou no fim",
diff --git a/lib/private/App/AppStore/Fetcher/AppFetcher.php b/lib/private/App/AppStore/Fetcher/AppFetcher.php
index 4dc517879e8..70bf2a37d9d 100644
--- a/lib/private/App/AppStore/Fetcher/AppFetcher.php
+++ b/lib/private/App/AppStore/Fetcher/AppFetcher.php
@@ -113,12 +113,12 @@ class AppFetcher extends Fetcher {
$phpVersion = $versionParser->getVersion($release['rawPhpVersionSpec']);
$minPhpVersion = $phpVersion->getMinimumVersion();
$maxPhpVersion = $phpVersion->getMaximumVersion();
- $minPhpFulfilled = $minPhpVersion === '' || $this->compareVersion->isCompatible(
+ $minPhpFulfilled = $minPhpVersion === '' || version_compare(
PHP_VERSION,
$minPhpVersion,
'>='
);
- $maxPhpFulfilled = $maxPhpVersion === '' || $this->compareVersion->isCompatible(
+ $maxPhpFulfilled = $maxPhpVersion === '' || version_compare(
PHP_VERSION,
$maxPhpVersion,
'<='
diff --git a/lib/private/DB/Adapter.php b/lib/private/DB/Adapter.php
index 49b831301be..62514e7d83a 100644
--- a/lib/private/DB/Adapter.php
+++ b/lib/private/DB/Adapter.php
@@ -30,6 +30,7 @@
namespace OC\DB;
+use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
/**
@@ -49,7 +50,9 @@ class Adapter {
/**
* @param string $table name
+ *
* @return int id of last insert statement
+ * @throws Exception
*/
public function lastInsertId($table) {
return (int) $this->conn->realLastInsertId($table);
@@ -67,6 +70,7 @@ class Adapter {
* Create an exclusive read+write lock on a table
*
* @param string $tableName
+ * @throws Exception
* @since 9.1.0
*/
public function lockTable($tableName) {
@@ -77,6 +81,7 @@ class Adapter {
/**
* Release a previous acquired lock again
*
+ * @throws Exception
* @since 9.1.0
*/
public function unlockTable() {
@@ -94,7 +99,7 @@ class Adapter {
* If this is null or an empty array, all keys of $input will be compared
* Please note: text fields (clob) must not be used in the compare array
* @return int number of inserted rows
- * @throws \Doctrine\DBAL\Exception
+ * @throws Exception
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
*/
public function insertIfNotExist($table, $input, array $compare = null) {
@@ -130,6 +135,9 @@ class Adapter {
}
}
+ /**
+ * @throws \OCP\DB\Exception
+ */
public function insertIgnoreConflict(string $table,array $values) : int {
try {
$builder = $this->conn->getQueryBuilder();
diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php
index c67c6df0826..cb7af4d51e2 100644
--- a/lib/private/DB/Connection.php
+++ b/lib/private/DB/Connection.php
@@ -74,6 +74,9 @@ class Connection extends ReconnectWrapper {
/** @var int */
protected $queriesExecuted = 0;
+ /**
+ * @throws Exception
+ */
public function connect() {
try {
return parent::connect();
@@ -183,7 +186,9 @@ class Connection extends ReconnectWrapper {
* @param string $statement The SQL statement to prepare.
* @param int $limit
* @param int $offset
+ *
* @return Statement The prepared statement.
+ * @throws Exception
*/
public function prepare($statement, $limit = null, $offset = null): Statement {
if ($limit === -1) {
@@ -221,6 +226,9 @@ class Connection extends ReconnectWrapper {
return parent::executeQuery($sql, $params, $types, $qcp);
}
+ /**
+ * @throws Exception
+ */
public function executeUpdate(string $sql, array $params = [], array $types = []): int {
$sql = $this->replaceTablePrefix($sql);
$sql = $this->adapter->fixupStatement($sql);
@@ -258,7 +266,9 @@ class Connection extends ReconnectWrapper {
* columns or sequences.
*
* @param string $seqName Name of the sequence object from which the ID should be returned.
+ *
* @return string the last inserted ID.
+ * @throws Exception
*/
public function lastInsertId($seqName = null) {
if ($seqName) {
@@ -267,7 +277,10 @@ class Connection extends ReconnectWrapper {
return $this->adapter->lastInsertId($seqName);
}
- // internal use
+ /**
+ * @internal
+ * @throws Exception
+ */
public function realLastInsertId($seqName = null) {
return parent::lastInsertId($seqName);
}
@@ -364,7 +377,9 @@ class Connection extends ReconnectWrapper {
* Create an exclusive read+write lock on a table
*
* @param string $tableName
+ *
* @throws \BadMethodCallException When trying to acquire a second lock
+ * @throws Exception
* @since 9.1.0
*/
public function lockTable($tableName) {
@@ -380,6 +395,7 @@ class Connection extends ReconnectWrapper {
/**
* Release a previous acquired lock again
*
+ * @throws Exception
* @since 9.1.0
*/
public function unlockTable() {
@@ -415,6 +431,8 @@ class Connection extends ReconnectWrapper {
* Drop a table from the database if it exists
*
* @param string $table table name without the prefix
+ *
+ * @throws Exception
*/
public function dropTable($table) {
$table = $this->tablePrefix . trim($table);
@@ -428,7 +446,9 @@ class Connection extends ReconnectWrapper {
* Check if a table exists
*
* @param string $table table name without the prefix
+ *
* @return bool
+ * @throws Exception
*/
public function tableExists($table) {
$table = $this->tablePrefix . trim($table);
@@ -483,6 +503,7 @@ class Connection extends ReconnectWrapper {
* Create the schema of the connected database
*
* @return Schema
+ * @throws Exception
*/
public function createSchema() {
$schemaManager = new MDB2SchemaManager($this);
@@ -494,6 +515,8 @@ class Connection extends ReconnectWrapper {
* Migrate the database to the given schema
*
* @param Schema $toSchema
+ *
+ * @throws Exception
*/
public function migrateToSchema(Schema $toSchema) {
$schemaManager = new MDB2SchemaManager($this);
diff --git a/lib/private/DB/ConnectionAdapter.php b/lib/private/DB/ConnectionAdapter.php
index 97a0b60044d..62c013e4dcf 100644
--- a/lib/private/DB/ConnectionAdapter.php
+++ b/lib/private/DB/ConnectionAdapter.php
@@ -25,8 +25,10 @@ declare(strict_types=1);
namespace OC\DB;
+use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Schema;
+use OC\DB\Exceptions\DbalException;
use OCP\DB\IPreparedStatement;
use OCP\DB\IResult;
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -49,51 +51,95 @@ class ConnectionAdapter implements IDBConnection {
}
public function prepare($sql, $limit = null, $offset = null): IPreparedStatement {
- return new PreparedStatement(
- $this->inner->prepare($sql, $limit, $offset)
- );
+ try {
+ return new PreparedStatement(
+ $this->inner->prepare($sql, $limit, $offset)
+ );
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function executeQuery(string $sql, array $params = [], $types = []): IResult {
- return new ResultAdapter(
- $this->inner->executeQuery($sql, $params, $types)
- );
+ try {
+ return new ResultAdapter(
+ $this->inner->executeQuery($sql, $params, $types)
+ );
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function executeUpdate(string $sql, array $params = [], array $types = []): int {
- return $this->inner->executeUpdate($sql, $params, $types);
+ try {
+ return $this->inner->executeUpdate($sql, $params, $types);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function executeStatement($sql, array $params = [], array $types = []): int {
- return $this->inner->executeStatement($sql, $params, $types);
+ try {
+ return $this->inner->executeStatement($sql, $params, $types);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function lastInsertId(string $table): int {
- return (int) $this->inner->lastInsertId($table);
+ try {
+ return (int)$this->inner->lastInsertId($table);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function insertIfNotExist(string $table, array $input, array $compare = null) {
- return $this->inner->insertIfNotExist($table, $input, $compare);
+ try {
+ return $this->inner->insertIfNotExist($table, $input, $compare);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function insertIgnoreConflict(string $table, array $values): int {
- return $this->inner->insertIgnoreConflict($table, $values);
+ try {
+ return $this->inner->insertIgnoreConflict($table, $values);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function setValues($table, array $keys, array $values, array $updatePreconditionValues = []): int {
- return $this->inner->setValues($table, $keys, $values, $updatePreconditionValues);
+ try {
+ return $this->inner->setValues($table, $keys, $values, $updatePreconditionValues);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function lockTable($tableName): void {
- $this->inner->lockTable($tableName);
+ try {
+ $this->inner->lockTable($tableName);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function unlockTable(): void {
- $this->inner->unlockTable();
+ try {
+ $this->inner->unlockTable();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function beginTransaction(): void {
- $this->inner->beginTransaction();
+ try {
+ $this->inner->beginTransaction();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function inTransaction(): bool {
@@ -101,11 +147,19 @@ class ConnectionAdapter implements IDBConnection {
}
public function commit(): void {
- $this->inner->commit();
+ try {
+ $this->inner->commit();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function rollBack(): void {
- $this->inner->rollBack();
+ try {
+ $this->inner->rollBack();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function getError(): string {
@@ -121,7 +175,11 @@ class ConnectionAdapter implements IDBConnection {
}
public function connect(): bool {
- return $this->inner->connect();
+ try {
+ return $this->inner->connect();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function close(): void {
@@ -140,11 +198,19 @@ class ConnectionAdapter implements IDBConnection {
}
public function dropTable(string $table): void {
- $this->inner->dropTable($table);
+ try {
+ $this->inner->dropTable($table);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function tableExists(string $table): bool {
- return $this->inner->tableExists($table);
+ try {
+ return $this->inner->tableExists($table);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function escapeLikeParameter(string $param): string {
@@ -159,11 +225,19 @@ class ConnectionAdapter implements IDBConnection {
* @todo leaks a 3rdparty type
*/
public function createSchema(): Schema {
- return $this->inner->createSchema();
+ try {
+ return $this->inner->createSchema();
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function migrateToSchema(Schema $toSchema): void {
- $this->inner->migrateToSchema($toSchema);
+ try {
+ $this->inner->migrateToSchema($toSchema);
+ } catch (Exception $e) {
+ throw DbalException::wrap($e);
+ }
}
public function getInner(): Connection {
diff --git a/lib/private/DB/Exceptions/DbalException.php b/lib/private/DB/Exceptions/DbalException.php
new file mode 100644
index 00000000000..4e0e1517048
--- /dev/null
+++ b/lib/private/DB/Exceptions/DbalException.php
@@ -0,0 +1,136 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\DB\Exceptions;
+
+use Doctrine\DBAL\ConnectionException;
+use Doctrine\DBAL\Exception\ConstraintViolationException;
+use Doctrine\DBAL\Exception\DatabaseObjectExistsException;
+use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
+use Doctrine\DBAL\Exception\DeadlockException;
+use Doctrine\DBAL\Exception\DriverException;
+use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
+use Doctrine\DBAL\Exception\InvalidArgumentException;
+use Doctrine\DBAL\Exception\InvalidFieldNameException;
+use Doctrine\DBAL\Exception\NonUniqueFieldNameException;
+use Doctrine\DBAL\Exception\NotNullConstraintViolationException;
+use Doctrine\DBAL\Exception\ServerException;
+use Doctrine\DBAL\Exception\SyntaxErrorException;
+use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
+use OCP\DB\Exception;
+
+/**
+ * Wrapper around the raw dbal exception, so we can pass it to apps that catch
+ * our OCP db exception
+ *
+ * @psalm-immutable
+ */
+class DbalException extends Exception {
+
+ /** @var \Doctrine\DBAL\Exception */
+ private $original;
+
+ /**
+ * @param \Doctrine\DBAL\Exception $original
+ * @param int $code
+ * @param string $message
+ */
+ private function __construct(\Doctrine\DBAL\Exception $original, int $code, string $message) {
+ parent::__construct(
+ $message,
+ $code,
+ $original
+ );
+ $this->original = $original;
+ }
+
+ public static function wrap(\Doctrine\DBAL\Exception $original, string $message = ''): self {
+ return new self(
+ $original,
+ is_int($original->getCode()) ? $original->getCode() : 0,
+ empty($message) ? $original->getMessage() : $message
+ );
+ }
+
+ public function getReason(): ?int {
+ /**
+ * Generic errors
+ */
+ if ($this->original instanceof ConnectionException) {
+ return parent::REASON_CONNECTION_LOST;
+ }
+ if ($this->original instanceof DriverException) {
+ return parent::REASON_DRIVER;
+ }
+ if ($this->original instanceof InvalidArgumentException) {
+ return parent::REASON_INVALID_ARGUMENT;
+ }
+
+ /**
+ * Constraint errors
+ */
+ if ($this->original instanceof ForeignKeyConstraintViolationException) {
+ return parent::REASON_FOREIGN_KEY_VIOLATION;
+ }
+ if ($this->original instanceof NotNullConstraintViolationException) {
+ return parent::REASON_NOT_NULL_CONSTRAINT_VIOLATION;
+ }
+ if ($this->original instanceof UniqueConstraintViolationException) {
+ return parent::REASON_UNIQUE_CONSTRAINT_VIOLATION;
+ }
+ // The base exception comes last
+ if ($this->original instanceof ConstraintViolationException) {
+ return parent::REASON_CONSTRAINT_VIOLATION;
+ }
+
+ /**
+ * Other server errors
+ */
+ if ($this->original instanceof DatabaseObjectExistsException) {
+ return parent::REASON_DATABASE_OBJECT_EXISTS;
+ }
+ if ($this->original instanceof DatabaseObjectNotFoundException) {
+ return parent::REASON_DATABASE_OBJECT_NOT_FOUND;
+ }
+ if ($this->original instanceof DeadlockException) {
+ return parent::REASON_DEADLOCK;
+ }
+ if ($this->original instanceof InvalidFieldNameException) {
+ return parent::REASON_INVALID_FIELD_NAME;
+ }
+ if ($this->original instanceof NonUniqueFieldNameException) {
+ return parent::REASON_NON_UNIQUE_FIELD_NAME;
+ }
+ if ($this->original instanceof SyntaxErrorException) {
+ return parent::REASON_SYNTAX_ERROR;
+ }
+ // The base server exception class comes last
+ if ($this->original instanceof ServerException) {
+ return parent::REASON_SERVER;
+ }
+
+ return null;
+ }
+}
diff --git a/lib/private/DB/Migrator.php b/lib/private/DB/Migrator.php
index e50927f620b..dcf0db89f72 100644
--- a/lib/private/DB/Migrator.php
+++ b/lib/private/DB/Migrator.php
@@ -82,6 +82,8 @@ class Migrator {
/**
* @param \Doctrine\DBAL\Schema\Schema $targetSchema
+ *
+ * @throws Exception
*/
public function migrate(Schema $targetSchema) {
$this->noEmit = true;
@@ -171,6 +173,9 @@ class Migrator {
return new Table($newName, $table->getColumns(), $newIndexes, [], [], $table->getOptions());
}
+ /**
+ * @throws Exception
+ */
public function createSchema() {
$this->connection->getConfiguration()->setSchemaAssetsFilter(function ($asset) {
/** @var string|AbstractAsset $asset */
@@ -231,6 +236,8 @@ class Migrator {
/**
* @param \Doctrine\DBAL\Schema\Schema $targetSchema
* @param \Doctrine\DBAL\Connection $connection
+ *
+ * @throws Exception
*/
protected function applySchema(Schema $targetSchema, \Doctrine\DBAL\Connection $connection = null) {
if (is_null($connection)) {
diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php
index 657e52e54bc..fb28fa28649 100644
--- a/lib/private/DB/QueryBuilder/QueryBuilder.php
+++ b/lib/private/DB/QueryBuilder/QueryBuilder.php
@@ -253,6 +253,36 @@ class QueryBuilder implements IQueryBuilder {
}
}
+ $numberOfParameters = 0;
+ $hasTooLargeArrayParameter = false;
+ foreach ($this->getParameters() as $parameter) {
+ if (is_array($parameter)) {
+ $count = count($parameter);
+ $numberOfParameters += $count;
+ $hasTooLargeArrayParameter = $hasTooLargeArrayParameter || ($count > 1000);
+ }
+ }
+
+ if ($hasTooLargeArrayParameter) {
+ $exception = new QueryException('More than 1000 expressions in a list are not allowed on Oracle.');
+ $this->logger->logException($exception, [
+ 'message' => 'More than 1000 expressions in a list are not allowed on Oracle.',
+ 'query' => $this->getSQL(),
+ 'level' => ILogger::ERROR,
+ 'app' => 'core',
+ ]);
+ }
+
+ if ($numberOfParameters > 65535) {
+ $exception = new QueryException('The number of parameters must not exceed 65535. Restriction by PostgreSQL.');
+ $this->logger->logException($exception, [
+ 'message' => 'The number of parameters must not exceed 65535. Restriction by PostgreSQL.',
+ 'query' => $this->getSQL(),
+ 'level' => ILogger::ERROR,
+ 'app' => 'core',
+ ]);
+ }
+
$result = $this->queryBuilder->execute();
if (is_int($result)) {
return $result;
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index 81d1d083eb8..944b0b69959 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -86,7 +86,10 @@ class Local extends \OC\Files\Storage\Common {
}
public function mkdir($path) {
- return @mkdir($this->getSourcePath($path), 0777, true);
+ $sourcePath = $this->getSourcePath($path);
+ $result = @mkdir($sourcePath, 0777, true);
+ chmod($sourcePath, 0755);
+ return $result;
}
public function rmdir($path) {
diff --git a/lib/private/IntegrityCheck/Checker.php b/lib/private/IntegrityCheck/Checker.php
index 504cd391c42..fc28d0e7393 100644
--- a/lib/private/IntegrityCheck/Checker.php
+++ b/lib/private/IntegrityCheck/Checker.php
@@ -44,7 +44,6 @@ use OCP\Files\IMimeTypeDetector;
use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IConfig;
-use OCP\ITempManager;
use phpseclib\Crypt\RSA;
use phpseclib\File\X509;
@@ -66,14 +65,12 @@ class Checker {
private $appLocator;
/** @var FileAccessHelper */
private $fileAccessHelper;
- /** @var IConfig */
+ /** @var IConfig|null */
private $config;
/** @var ICache */
private $cache;
- /** @var IAppManager */
+ /** @var IAppManager|null */
private $appManager;
- /** @var ITempManager */
- private $tempManager;
/** @var IMimeTypeDetector */
private $mimeTypeDetector;
@@ -81,19 +78,17 @@ class Checker {
* @param EnvironmentHelper $environmentHelper
* @param FileAccessHelper $fileAccessHelper
* @param AppLocator $appLocator
- * @param IConfig $config
+ * @param IConfig|null $config
* @param ICacheFactory $cacheFactory
- * @param IAppManager $appManager
- * @param ITempManager $tempManager
+ * @param IAppManager|null $appManager
* @param IMimeTypeDetector $mimeTypeDetector
*/
public function __construct(EnvironmentHelper $environmentHelper,
FileAccessHelper $fileAccessHelper,
AppLocator $appLocator,
- IConfig $config = null,
+ ?IConfig $config,
ICacheFactory $cacheFactory,
- IAppManager $appManager = null,
- ITempManager $tempManager,
+ ?IAppManager $appManager,
IMimeTypeDetector $mimeTypeDetector) {
$this->environmentHelper = $environmentHelper;
$this->fileAccessHelper = $fileAccessHelper;
@@ -101,7 +96,6 @@ class Checker {
$this->config = $config;
$this->cache = $cacheFactory->createDistributed(self::CACHE_KEY);
$this->appManager = $appManager;
- $this->tempManager = $tempManager;
$this->mimeTypeDetector = $mimeTypeDetector;
}
@@ -311,12 +305,13 @@ class Checker {
* @param string $signaturePath
* @param string $basePath
* @param string $certificateCN
+ * @param bool $forceVerify
* @return array
* @throws InvalidSignatureException
* @throws \Exception
*/
- private function verify(string $signaturePath, string $basePath, string $certificateCN): array {
- if (!$this->isCodeCheckEnforced()) {
+ private function verify(string $signaturePath, string $basePath, string $certificateCN, bool $forceVerify = false): array {
+ if (!$forceVerify && !$this->isCodeCheckEnforced()) {
return [];
}
@@ -495,9 +490,10 @@ class Checker {
*
* @param string $appId
* @param string $path Optional path. If none is given it will be guessed.
+ * @param bool $forceVerify
* @return array
*/
- public function verifyAppSignature(string $appId, string $path = ''): array {
+ public function verifyAppSignature(string $appId, string $path = '', bool $forceVerify = false): array {
try {
if ($path === '') {
$path = $this->appLocator->getAppPath($appId);
@@ -505,7 +501,8 @@ class Checker {
$result = $this->verify(
$path . '/appinfo/signature.json',
$path,
- $appId
+ $appId,
+ $forceVerify
);
} catch (\Exception $e) {
$result = [
diff --git a/lib/private/Log/ExceptionSerializer.php b/lib/private/Log/ExceptionSerializer.php
index ae3e6ba100d..b62293946d0 100644
--- a/lib/private/Log/ExceptionSerializer.php
+++ b/lib/private/Log/ExceptionSerializer.php
@@ -82,6 +82,7 @@ class ExceptionSerializer {
// Encryption
'storeKeyPair',
'setupUser',
+ 'checkSignature',
// files_external: OCA\Files_External\MountConfig
'getBackendStatus',
diff --git a/lib/private/Preview/MarkDown.php b/lib/private/Preview/MarkDown.php
index 91e276eb170..54648ac1837 100644
--- a/lib/private/Preview/MarkDown.php
+++ b/lib/private/Preview/MarkDown.php
@@ -24,6 +24,9 @@
namespace OC\Preview;
+use OCP\Files\File;
+use OCP\IImage;
+
class MarkDown extends TXT {
/**
* {@inheritDoc}
@@ -31,4 +34,111 @@ class MarkDown extends TXT {
public function getMimeType(): string {
return '/text\/(x-)?markdown/';
}
+
+ public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
+ $content = $file->fopen('r');
+
+ if ($content === false) {
+ return null;
+ }
+
+ $content = stream_get_contents($content,3000);
+
+ //don't create previews of empty text files
+ if (trim($content) === '') {
+ return null;
+ }
+
+ // Merge text paragraph lines that might belong together
+ $content = preg_replace('/^(\s*)\*\s/mU', '$1- ', $content);
+
+ $content = preg_replace('/((?!^(\s*-|#)).*)(\w|\\|\.)(\r\n|\n|\r)(\w|\*)/mU', '$1 $3', $content);
+
+ // Remove markdown symbols that we cannot easily represent in rendered text in the preview
+ $content = preg_replace('/\*\*(.*)\*\*/U', '$1', $content);
+ $content = preg_replace('/\*(.*)\*/U', '$1', $content);
+ $content = preg_replace('/\_\_(.*)\_\_/U', '$1', $content);
+ $content = preg_replace('/\_(.*)\_/U', '$1', $content);
+ $content = preg_replace('/\~\~(.*)\~\~/U', '$1', $content);
+
+ $content = preg_replace('/\!?\[((.|\n)*)\]\((.*)\)/mU', '$1 ($3)', $content);
+ $content = preg_replace('/\n\n+/', "\n", $content);
+
+ $content = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $content);
+
+ $lines = preg_split("/\r\n|\n|\r/", $content);
+
+ // Define text size of text file preview
+ $fontSize = $maxX ? (int) ((1 / ($maxX >= 512 ? 60 : 40) * $maxX)) : 10;
+
+ $image = imagecreate($maxX, $maxY);
+ imagecolorallocate($image, 255, 255, 255);
+ $textColor = imagecolorallocate($image, 0, 0, 0);
+
+ $fontFile = __DIR__ . '/../../../core/fonts/NotoSans-Regular.ttf';
+ $fontFileBold = __DIR__ . '/../../../core/fonts/NotoSans-Bold.ttf';
+
+ $canUseTTF = function_exists('imagettftext');
+
+ $textOffset = (int)min($maxX * 0.05, $maxY * 0.05);
+ $nextLineStart = 0;
+ $y = $textOffset;
+ foreach ($lines as $line) {
+ $actualFontSize = $fontSize;
+ if (mb_strpos($line, '# ') === 0) {
+ $actualFontSize *= 2;
+ }
+ if (mb_strpos($line, '## ') === 0) {
+ $actualFontSize *= 1.8;
+ }
+ if (mb_strpos($line, '### ') === 0) {
+ $actualFontSize *= 1.6;
+ }
+ if (mb_strpos($line, '#### ') === 0) {
+ $actualFontSize *= 1.4;
+ }
+ if (mb_strpos($line, '##### ') === 0) {
+ $actualFontSize *= 1.2;
+ }
+ if (mb_strpos($line, '###### ') === 0) {
+ $actualFontSize *= 1.1;
+ }
+
+ // Add spacing before headlines
+ if ($actualFontSize !== $fontSize && $y !== $textOffset) {
+ $y += (int)($actualFontSize * 2);
+ }
+
+ $x = $textOffset;
+ $y += (int)($nextLineStart + $actualFontSize);
+
+ if ($canUseTTF === true) {
+ $wordWrap = (int)((1 / $actualFontSize * 1.3) * $maxX);
+
+ // Get rid of markdown symbols that we still needed for the font size
+ $line = preg_replace('/^#*\s/', '', $line);
+
+ $wrappedText = wordwrap($line, $wordWrap,"\n");
+ $linesWrapped = count(explode("\n", $wrappedText));
+ imagettftext($image, $actualFontSize, 0, $x, $y, $textColor, $actualFontSize === $fontSize ? $fontFile : $fontFileBold, $wrappedText);
+ $nextLineStart = (int)($linesWrapped * ceil($actualFontSize * 2));
+ if ($actualFontSize !== $fontSize && $y !== $textOffset) {
+ $nextLineStart -= $actualFontSize;
+ }
+ } else {
+ $y -= (int)$fontSize;
+ imagestring($image, 1, $x, $y, $line, $textColor);
+ $nextLineStart = $fontSize;
+ }
+
+ if ($y >= $maxY) {
+ break;
+ }
+ }
+
+ $imageObject = new \OC_Image();
+ $imageObject->setResource($image);
+
+ return $imageObject->valid() ? $imageObject : null;
+ }
}
diff --git a/lib/private/Preview/WebP.php b/lib/private/Preview/WebP.php
new file mode 100644
index 00000000000..8f10a08206b
--- /dev/null
+++ b/lib/private/Preview/WebP.php
@@ -0,0 +1,42 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ * @author John Molakvoæ <skjnldsv@protonmail.com>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Preview;
+
+use OCP\Files\FileInfo;
+
+class WebP extends Image {
+ /**
+ * {@inheritDoc}
+ */
+ public function getMimeType(): string {
+ return '/image\/webp/';
+ }
+
+ public function isAvailable(FileInfo $file): bool {
+ return (bool)(imagetypes() && IMG_WEBP);
+ }
+}
diff --git a/lib/private/PreviewManager.php b/lib/private/PreviewManager.php
index 8fa0fc92da5..1d65da8ca59 100644
--- a/lib/private/PreviewManager.php
+++ b/lib/private/PreviewManager.php
@@ -58,7 +58,7 @@ class PreviewManager implements IPreview {
/** @var Generator */
private $generator;
-
+
/** @var GeneratorHelper */
private $helper;
@@ -314,6 +314,7 @@ class PreviewManager implements IPreview {
Preview\HEIC::class,
Preview\XBitmap::class,
Preview\Krita::class,
+ Preview\WebP::class,
];
$this->defaultProviders = $this->config->getSystemValue('enabledPreviewProviders', array_merge([
@@ -360,6 +361,7 @@ class PreviewManager implements IPreview {
$this->registerCoreProvider(Preview\GIF::class, '/image\/gif/');
$this->registerCoreProvider(Preview\BMP::class, '/image\/bmp/');
$this->registerCoreProvider(Preview\XBitmap::class, '/image\/x-xbitmap/');
+ $this->registerCoreProvider(Preview\WebP::class, '/image\/webp/');
$this->registerCoreProvider(Preview\Krita::class, '/application\/x-krita/');
$this->registerCoreProvider(Preview\MP3::class, '/audio\/mpeg/');
$this->registerCoreProvider(Preview\OpenDocument::class, '/application\/vnd.oasis.opendocument.*/');
diff --git a/lib/private/Server.php b/lib/private/Server.php
index 680eea3beca..ba954165799 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -575,7 +575,7 @@ class Server extends ServerContainer implements IServerContainer {
/** @var IEventDispatcher $dispatcher */
$dispatcher = $this->get(IEventDispatcher::class);
- $dispatcher->dispatchTyped(new UserLoggedInEvent($user, $password, $isTokenLogin));
+ $dispatcher->dispatchTyped(new UserLoggedInEvent($user, $loginName, $password, $isTokenLogin));
});
$userSession->listen('\OC\User', 'preRememberedLogin', function ($uid) {
/** @var IEventDispatcher $dispatcher */
@@ -942,7 +942,6 @@ class Server extends ServerContainer implements IServerContainer {
$config,
$c->get(ICacheFactory::class),
$appManager,
- $c->get(ITempManager::class),
$c->get(IMimeTypeDetector::class)
);
});
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 21339dc46d0..229d47160f5 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -36,6 +36,7 @@ use OC\DB\MySqlTools;
use OCP\IDBConnection;
use OCP\ILogger;
use Doctrine\DBAL\Platforms\MySQL80Platform;
+use OCP\Security\ISecureRandom;
class MySQL extends AbstractDatabase {
public $dbprettyname = 'MySQL/MariaDB';
@@ -165,7 +166,7 @@ class MySQL extends AbstractDatabase {
$this->dbUser = $adminUser;
//create a random password so we don't need to store the admin password in the config file
- $this->dbPassword = $this->random->generate(30);
+ $this->dbPassword = $this->random->generate(30, ISecureRandom::CHAR_DIGITS . ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER);
$this->createDBUser($connection);
diff --git a/lib/private/legacy/OC_Image.php b/lib/private/legacy/OC_Image.php
index b97413aa922..f1b9101045a 100644
--- a/lib/private/legacy/OC_Image.php
+++ b/lib/private/legacy/OC_Image.php
@@ -555,7 +555,7 @@ class OC_Image implements \OCP\IImage {
*/
public function loadFromFile($imagePath = false) {
// exif_imagetype throws "read error!" if file is less than 12 byte
- if (!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
+ if (is_bool($imagePath) || !@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
return false;
}
$iType = exif_imagetype($imagePath);
@@ -608,6 +608,13 @@ class OC_Image implements \OCP\IImage {
case IMAGETYPE_BMP:
$this->resource = $this->imagecreatefrombmp($imagePath);
break;
+ case IMAGETYPE_WEBP:
+ if (imagetypes() & IMG_WEBP) {
+ $this->resource = @imagecreatefromwebp($imagePath);
+ } else {
+ $this->logger->debug('OC_Image->loadFromFile, webp images not supported: ' . $imagePath, ['app' => 'core']);
+ }
+ break;
/*
case IMAGETYPE_TIFF_II: // (intel byte order)
break;
diff --git a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
index 002db267293..197275fb8e3 100644
--- a/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
+++ b/lib/public/AppFramework/Bootstrap/IRegistrationContext.php
@@ -119,7 +119,8 @@ interface IRegistrationContext {
* @psalm-param string|class-string<T> $event preferably the fully-qualified class name of the Event sub class to listen for
* @param string $listener fully qualified class name (or ::class notation) of a \OCP\EventDispatcher\IEventListener that can be built by the DI container
* @psalm-param class-string<\OCP\EventDispatcher\IEventListener<T>> $listener fully qualified class name that can be built by the DI container
- * @param int $priority
+ * @param int $priority The higher this value, the earlier an event
+ * listener will be triggered in the chain (defaults to 0)
*
* @see IEventDispatcher::addServiceListener()
*
diff --git a/lib/public/DB/Exception.php b/lib/public/DB/Exception.php
new file mode 100644
index 00000000000..1154530e85d
--- /dev/null
+++ b/lib/public/DB/Exception.php
@@ -0,0 +1,149 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+namespace OCP\DB;
+
+use Exception as BaseException;
+
+/**
+ * Database exception
+ *
+ * Thrown by Nextcloud's database abstraction layer. This is the base class that
+ * any specific exception will extend. Use this class in your try-catch to catch
+ * *any* error related to the database. Use any of the subclasses in the same
+ * namespace if you are only interested in specific errors.
+ *
+ * @psalm-immutable
+ * @since 21.0.0
+ */
+class Exception extends BaseException {
+
+ /**
+ * Nextcloud lost connection to the database
+ *
+ * @since 21.0.0
+ */
+ public const REASON_CONNECTION_LOST = 1;
+
+ /**
+ * A database constraint was violated
+ *
+ * @since 21.0.0
+ */
+ public const REASON_CONSTRAINT_VIOLATION = 2;
+
+ /**
+ * A database object (table, column, index) already exists
+ *
+ * @since 21.0.0
+ */
+ public const REASON_DATABASE_OBJECT_EXISTS = 3;
+
+ /**
+ * A database object (table, column, index) can't be found
+ *
+ * @since 21.0.0
+ */
+ public const REASON_DATABASE_OBJECT_NOT_FOUND = 4;
+
+ /**
+ * The database ran into a deadlock
+ *
+ * @since 21.0.0
+ */
+ public const REASON_DEADLOCK = 5;
+
+ /**
+ * The database driver encountered an issue
+ *
+ * @since 21.0.0
+ */
+ public const REASON_DRIVER = 6;
+
+ /**
+ * A foreign key constraint was violated
+ *
+ * @since 21.0.0
+ */
+ public const REASON_FOREIGN_KEY_VIOLATION = 7;
+
+ /**
+ * An invalid argument was passed to the database abstraction
+ *
+ * @since 21.0.0
+ */
+ public const REASON_INVALID_ARGUMENT = 8;
+
+ /**
+ * A field name was invalid
+ *
+ * @since 21.0.0
+ */
+ public const REASON_INVALID_FIELD_NAME = 9;
+
+ /**
+ * A name in the query was ambiguous
+ *
+ * @since 21.0.0
+ */
+ public const REASON_NON_UNIQUE_FIELD_NAME = 10;
+
+ /**
+ * A not null contraint was violated
+ *
+ * @since 21.0.0
+ */
+ public const REASON_NOT_NULL_CONSTRAINT_VIOLATION = 11;
+
+ /**
+ * A generic server error was encountered
+ *
+ * @since 21.0.0
+ */
+ public const REASON_SERVER = 12;
+
+ /**
+ * A syntax error was reported by the server
+ *
+ * @since 21.0.0
+ */
+ public const REASON_SYNTAX_ERROR = 13;
+
+ /**
+ * A unique constraint was violated
+ *
+ * @since 21.0.0
+ */
+ public const REASON_UNIQUE_CONSTRAINT_VIOLATION = 14;
+
+ /**
+ * @return int|null
+ * @psalm-return Exception::REASON_*
+ * @since 21.0.0
+ */
+ public function getReason(): ?int {
+ return null;
+ }
+}
diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php
index 8fcbd6c3276..24de7b4ce60 100644
--- a/lib/public/DB/QueryBuilder/IQueryBuilder.php
+++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php
@@ -29,6 +29,7 @@
namespace OCP\DB\QueryBuilder;
use Doctrine\DBAL\Connection;
+use OCP\DB\Exception;
use OCP\DB\IResult;
/**
@@ -154,6 +155,7 @@ interface IQueryBuilder {
* to bridge old code to the new API
*
* @return IResult|int
+ * @throws Exception since 21.0.0
* @since 8.2.0
*/
public function execute();
diff --git a/lib/public/EventDispatcher/IEventDispatcher.php b/lib/public/EventDispatcher/IEventDispatcher.php
index 6f3adf159c0..f38c0828bce 100644
--- a/lib/public/EventDispatcher/IEventDispatcher.php
+++ b/lib/public/EventDispatcher/IEventDispatcher.php
@@ -40,7 +40,8 @@ interface IEventDispatcher {
* @psalm-param string|class-string<T> $eventName preferably the fully-qualified class name of the Event sub class
* @param callable $listener the object that is invoked when a matching event is dispatched
* @psalm-param callable(T):void $listener
- * @param int $priority
+ * @param int $priority The higher this value, the earlier an event
+ * listener will be triggered in the chain (defaults to 0)
*
* @since 17.0.0
*/
@@ -63,7 +64,8 @@ interface IEventDispatcher {
* @psalm-param string|class-string<T> $eventName preferably the fully-qualified class name of the Event sub class to listen for
* @param string $className fully qualified class name (or ::class notation) of a \OCP\EventDispatcher\IEventListener that can be built by the DI container
* @psalm-param class-string<\OCP\EventDispatcher\IEventListener<T>> $className fully qualified class name that can be built by the DI container
- * @param int $priority
+ * @param int $priority The higher this value, the earlier an event
+ * listener will be triggered in the chain (defaults to 0)
*
* @since 17.0.0
*/
diff --git a/lib/public/IDBConnection.php b/lib/public/IDBConnection.php
index 16a5f998fde..5618e3ec40b 100644
--- a/lib/public/IDBConnection.php
+++ b/lib/public/IDBConnection.php
@@ -39,8 +39,8 @@
namespace OCP;
-use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\Schema;
+use OCP\DB\Exception;
use OCP\DB\IPreparedStatement;
use OCP\DB\IResult;
use OCP\DB\QueryBuilder\IQueryBuilder;
@@ -103,6 +103,7 @@ interface IDBConnection {
* @param array $types The parameter types.
* @return int The number of affected rows.
* @since 8.0.0
+ * @throws Exception since 21.0.0
*
* @deprecated 21.0.0 use executeStatement
*/
@@ -119,6 +120,7 @@ interface IDBConnection {
* @param array $types The parameter types.
* @return int The number of affected rows.
* @since 21.0.0
+ * @throws Exception since 21.0.0
*/
public function executeStatement($sql, array $params = [], array $types = []): int;
@@ -143,7 +145,7 @@ interface IDBConnection {
* If this is null or an empty array, all keys of $input will be compared
* Please note: text fields (clob) must not be used in the compare array
* @return int number of inserted rows
- * @throws Exception
+ * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
* @since 6.0.0 - parameter $compare was added in 8.1.0, return type changed from boolean in 8.1.0
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
*/
@@ -171,7 +173,7 @@ interface IDBConnection {
* @param array $values (column name => value)
* @param array $updatePreconditionValues ensure values match preconditions (column name => value)
* @return int number of new rows
- * @throws Exception
+ * @throws Exception used to be the removed dbal exception, since 21.0.0 it's \OCP\DB\Exception
* @throws PreconditionNotMetException
* @since 9.0.0
*/
@@ -185,6 +187,7 @@ interface IDBConnection {
* transaction while holding a lock.
*
* @param string $tableName
+ * @throws Exception since 21.0.0
* @since 9.1.0
*/
public function lockTable($tableName): void;
@@ -192,6 +195,7 @@ interface IDBConnection {
/**
* Release a previous acquired lock again
*
+ * @throws Exception since 21.0.0
* @since 9.1.0
*/
public function unlockTable(): void;
@@ -255,6 +259,7 @@ interface IDBConnection {
* Establishes the connection with the database.
*
* @return bool
+ * @throws Exception since 21.0.0
* @since 8.0.0
*/
public function connect(): bool;
@@ -288,6 +293,7 @@ interface IDBConnection {
* Drop a table from the database if it exists
*
* @param string $table table name without the prefix
+ * @throws Exception since 21.0.0
* @since 8.0.0
*/
public function dropTable(string $table): void;
@@ -297,6 +303,7 @@ interface IDBConnection {
*
* @param string $table table name without the prefix
* @return bool
+ * @throws Exception since 21.0.0
* @since 8.0.0
*/
public function tableExists(string $table): bool;
@@ -322,6 +329,7 @@ interface IDBConnection {
* Create the schema of the connected database
*
* @return Schema
+ * @throws Exception since 21.0.0
* @since 13.0.0
*/
public function createSchema(): Schema;
@@ -330,6 +338,7 @@ interface IDBConnection {
* Migrate the database to the given schema
*
* @param Schema $toSchema
+ * @throws Exception since 21.0.0
* @since 13.0.0
*/
public function migrateToSchema(Schema $toSchema): void;
diff --git a/lib/public/User/Events/UserLoggedInEvent.php b/lib/public/User/Events/UserLoggedInEvent.php
index e2cb37a64dc..7d0c0bf41de 100644
--- a/lib/public/User/Events/UserLoggedInEvent.php
+++ b/lib/public/User/Events/UserLoggedInEvent.php
@@ -43,14 +43,18 @@ class UserLoggedInEvent extends Event {
/** @var bool */
private $isTokenLogin;
+ /** @var string */
+ private $loginName;
+
/**
* @since 18.0.0
*/
- public function __construct(IUser $user, string $password, bool $isTokenLogin) {
+ public function __construct(IUser $user, string $loginName, string $password, bool $isTokenLogin) {
parent::__construct();
$this->user = $user;
$this->password = $password;
$this->isTokenLogin = $isTokenLogin;
+ $this->loginName = $loginName;
}
/**
@@ -61,6 +65,13 @@ class UserLoggedInEvent extends Event {
}
/**
+ * @since 21.0.0
+ */
+ public function getLoginName(): string {
+ return $this->loginName;
+ }
+
+ /**
* @since 18.0.0
*/
public function getPassword(): string {