diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2020-03-02 12:53:19 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-02 12:53:19 +0300 |
commit | 1bc59bce6628da1514077ae75e76f746490be0f8 (patch) | |
tree | ff87fe5bc9638a342d5dd521dc9b5da3bb467bf2 | |
parent | 608cd7d8202fa1e21c2a29e446391723b5455e53 (diff) | |
parent | 114cdf2c73668e1c81f92006d449357e37f39cfe (diff) |
Merge pull request #577 from nextcloud/backport/575/stable17
[stable17] 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 441746f..46ae378 100644 --- a/lib/Push.php +++ b/lib/Push.php @@ -262,14 +262,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) { @@ -300,6 +298,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 Key $userKey * @param array $device * @param int $id |