Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorblizzz <blizzz@arthur-schiwon.de>2021-11-26 22:58:36 +0300
committerGitHub <noreply@github.com>2021-11-26 22:58:36 +0300
commit842e22f8829227d54175656408c49729d786e7c8 (patch)
tree4a747a2f5d7011e989e0f420ae0f6eb65ed321a0
parentdf961fa2f3e12e8115ecc755f0af6c384bae421b (diff)
parent09014ec6d1c0106b95df9fc35a0f4d341fbb3730 (diff)
Merge pull request #29928 from nextcloud/backport/29926/stable23
[stable23] obey accounts_data column length when inserting and searching
-rw-r--r--lib/private/Accounts/AccountManager.php9
-rw-r--r--lib/public/Util.php24
-rw-r--r--tests/lib/UtilTest.php7
3 files changed, 39 insertions, 1 deletions
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index cbd51e71c4a..2c7641243fa 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -343,6 +343,10 @@ class AccountManager implements IAccountManager {
}
public function searchUsers(string $property, array $values): array {
+ // the value col is limited to 255 bytes. It is used for searches only.
+ $values = array_map(function (string $value) {
+ return Util::shortenMultibyteString($value, 255);
+ }, $values);
$chunks = array_chunk($values, 500);
$query = $this->connection->getQueryBuilder();
$query->select('*')
@@ -625,8 +629,11 @@ class AccountManager implements IAccountManager {
continue;
}
+ // the value col is limited to 255 bytes. It is used for searches only.
+ $value = $property['value'] ? Util::shortenMultibyteString($property['value'], 255) : '';
+
$query->setParameter('name', $property['name'])
- ->setParameter('value', $property['value'] ?? '');
+ ->setParameter('value', $value);
$query->executeStatement();
}
}
diff --git a/lib/public/Util.php b/lib/public/Util.php
index 5165846707a..103b65fe874 100644
--- a/lib/public/Util.php
+++ b/lib/public/Util.php
@@ -513,4 +513,28 @@ class Util {
}
return self::$needUpgradeCache;
}
+
+ /**
+ * Sometimes a string has to be shortened to fit within a certain maximum
+ * data length in bytes. substr() you may break multibyte characters,
+ * because it operates on single byte level. mb_substr() operates on
+ * characters, so does not ensure that the shortend string satisfies the
+ * max length in bytes.
+ *
+ * For example, json_encode is messing with multibyte characters a lot,
+ * replacing them with something along "\u1234".
+ *
+ * This function shortens the string with by $accurancy (-5) from
+ * $dataLength characters, until it fits within $dataLength bytes.
+ *
+ * @since 23.0.0
+ */
+ public static function shortenMultibyteString(string $subject, int $dataLength, int $accuracy = 5): string {
+ $temp = mb_substr($subject, 0, $dataLength);
+ // json encodes encapsulates the string in double quotes, they need to be substracted
+ while ((strlen(json_encode($temp)) - 2) > $dataLength) {
+ $temp = mb_substr($temp, 0, -$accuracy);
+ }
+ return $temp;
+ }
}
diff --git a/tests/lib/UtilTest.php b/tests/lib/UtilTest.php
index bb328c5998d..ca7a4ad1442 100644
--- a/tests/lib/UtilTest.php
+++ b/tests/lib/UtilTest.php
@@ -310,4 +310,11 @@ class UtilTest extends \Test\TestCase {
'myApp/vendor/myFancyCSSFile2',
], \OC_Util::$styles);
}
+
+ public function testShortenMultibyteString() {
+ $this->assertEquals('Short nuff', \OCP\Util::shortenMultibyteString('Short nuff', 255));
+ $this->assertEquals('ABC', \OCP\Util::shortenMultibyteString('ABCDEF', 3));
+ // each of the characters is 12 bytes
+ $this->assertEquals('🙈', \OCP\Util::shortenMultibyteString('🙈🙊🙉', 16, 2));
+ }
}