diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2020-03-07 17:28:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-07 17:28:20 +0300 |
commit | b14f0949eaf67371dfe5264cb17f8cac4ecbe963 (patch) | |
tree | 92336bb79a497db470d0131d69b9f3e4d68fa353 | |
parent | 63222af185b0eda065b872a8fd6b3f0477bdc0c7 (diff) | |
parent | eb45b70ee5550a6a45623547408aa04ff9a48ce7 (diff) |
Merge pull request #586 from nextcloud/backport/575/stable16
[stable16] Fix push notifications for multibyte notifications
-rw-r--r-- | lib/Push.php | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/lib/Push.php b/lib/Push.php index f381d20..46456d2 100644 --- a/lib/Push.php +++ b/lib/Push.php @@ -192,14 +192,12 @@ class Push { 'id' => $notification->getObjectId(), ]; - // Max length of encryption is 255, so we need to shorten the subject to be shorter - $subject = $notification->getParsedSubject(); - // Half the length for multibyte characters like Russian, Chinese, Japanese, Emojis, … - $dataLength = floor((245 - strlen(json_encode($data))) / 2) - 1; - if (strlen($subject) > $dataLength) { - $data['subject'] = mb_substr($subject, 0, $dataLength) . '…'; - } else { - $data['subject'] = $subject; + // Max length of encryption is 255, so we need to make sure the subject is shorter. + // We also substract a buffer of 10 bytes. + $maxDataLength = 255 - strlen(json_encode($data)) - 10; + $data['subject'] = $this->shortenJsonEncodedMultibyte($notification->getParsedSubject(), $maxDataLength); + if ($notification->getParsedSubject() !== $data['subject']) { + $data['subject'] .= '…'; } if ($isTalkNotification) { @@ -227,6 +225,27 @@ class Push { } /** + * json_encode is messing with multibyte characters a lot, + * replacing them with something along "\u1234". + * The data length in our encryption is a hard limit, but we don't want to + * make non-utf8 subjects unnecessary short. So this function tries to cut + * it off first. + * If that is not enough it always cuts off 5 characters in multibyte-safe + * fashion until the json_encode-d string is shorter then the given limit. + * + * @param string $subject + * @param int $dataLength + * @return string + */ + protected function shortenJsonEncodedMultibyte(string $subject, int $dataLength): string { + $temp = mb_substr($subject, 0, $dataLength); + while (strlen(json_encode($temp)) > $dataLength) { + $temp = mb_substr($temp, 0, -5); + } + return $temp; + } + + /** * @param string $uid * @return array[] */ |