From c84bf48a1caebf4aadc1f6bac81abc4f32d0deac Mon Sep 17 00:00:00 2001 From: atymic Date: Wed, 14 Jul 2021 13:21:33 +1000 Subject: [PATCH] fix: straddle message bug --- src/SmsLength.php | 35 +++++++++++++++++++++++++++++++++-- tests/SmsLengthTest.php | 17 ++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/SmsLength.php b/src/SmsLength.php index b767887..04f71e0 100644 --- a/src/SmsLength.php +++ b/src/SmsLength.php @@ -75,6 +75,11 @@ class SmsLength */ private $size; + /** + * @var int + */ + private $padding; + /** * @var int */ @@ -111,6 +116,16 @@ public function getSize() return $this->size; } + /** + * Get size of message padding used in the determined encoding + * + * @return int + */ + public function getPadding() + { + return $this->padding; + } + /** * Get number of messages that would be used to send the given content size * @@ -175,12 +190,19 @@ private function inspect($messageContent) // Any character outside the 7-bit alphabet switches the entire encoding to UCS-2 $this->encoding = '7-bit'; $this->size = 0; + $this->padding = 0; + $mbLength = mb_strlen($messageContent, 'UTF-8'); for ($i = 0; $i < $mbLength; $i++) { $char = mb_substr($messageContent, $i, 1, 'UTF-8'); if (in_array($char, self::GSM0338_BASIC)) { $this->size++; } elseif (in_array($char, self::GSM0338_EXTENDED)) { + // In cases where a double counted char straddles two messages, add padding to push it to the next part + if (($this->size + 2) % self::MAXIMUM_CHARACTERS_7BIT_CONCATENATED === 1) { + $this->padding++; + } + $this->size += 2; } else { $this->encoding = 'ucs-2'; @@ -195,7 +217,14 @@ private function inspect($messageContent) for ($i = 0; $i < $mbLength; $i++) { $char = mb_substr($messageContent, $i, 1, 'UTF-8'); $utf16Hex = bin2hex(mb_convert_encoding($char, 'UTF-16', 'UTF-8')); - $this->size += strlen($utf16Hex) / 4; + $charSize = strlen($utf16Hex) / 4; + + // In cases where a double counted char straddles two messages, add padding to push it to the next part + if ($charSize > 1 && ($this->size + $charSize) % self::MAXIMUM_CHARACTERS_UCS2_CONCATENATED === 1) { + $this->padding++; + } + + $this->size += $charSize; } } @@ -207,9 +236,11 @@ private function inspect($messageContent) $concatSize = self::MAXIMUM_CHARACTERS_UCS2_CONCATENATED; } + $sizeIncludingPadding = $this->size + $this->padding; + $this->messageCount = 1; if ($this->size > $singleSize) { - $this->messageCount = (int)ceil($this->size / $concatSize); + $this->messageCount = (int)ceil($sizeIncludingPadding / $concatSize); } } } diff --git a/tests/SmsLengthTest.php b/tests/SmsLengthTest.php index c03ebd6..94794da 100644 --- a/tests/SmsLengthTest.php +++ b/tests/SmsLengthTest.php @@ -84,7 +84,22 @@ public function providerSize() [str_repeat("exact•max", 67), 'ucs-2', 603, 9, 603], // empty - ['', '7-bit', 0, 1, 160] + ['', '7-bit', 0, 1, 160], + + [ + 'The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown f[x jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the.', + '7-bit', + 306, + 3, + 459, + ], + [ + str_repeat('🌐', 67), + 'ucs-2', + 134, + 3, + 201 + ], ]; }