Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions lib/Push.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,12 @@ protected function encryptAndSign(Key $userKey, array $device, int $id, INotific
'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) {
Expand Down Expand Up @@ -299,6 +297,27 @@ protected function encryptAndSign(Key $userKey, array $device, int $id, INotific
];
}

/**
* 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
Expand Down