Skip to content

Commit 636ed81

Browse files
authored
fix: GSM-7 special character size calculation in UCS-2 encoding
Some GSM-7 characters (e.g. ]) requires 14bits to be encoded (so to characters units). When the SMS is encoded using UCS-2, these special characters requires 16 bits, exactly as the normal GSM-7 characters.
2 parents 66bc9e9 + 98ce8b0 commit 636ed81

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/libs/EncodedChar.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class EncodedChar {
3737
}
3838

3939
sizeInBits(): number {
40+
if (this.encoding === 'UCS-2' && this.isGSM7) {
41+
// GSM characters are always using 16 bits in UCS-2 encoding
42+
return 16;
43+
}
4044
const bitsPerUnits = this.encoding === 'GSM-7' ? 7 : 16;
4145
return bitsPerUnits * this.codeUnits.length;
4246
}

tests/index.test.js

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,48 @@ describe('GSM-7 Escape Characters', () => {
143143
expect(segmentedMessage.totalSize).toBe(1223);
144144
});
145145
});
146-
});
146+
});
147+
148+
describe('One grapheme UCS-2 characters', () => {
149+
const testCharacters = ['Á', 'Ú', 'ú', 'ç', 'í', 'Í', 'ó', 'Ó'];
150+
testCharacters.forEach((character) => {
151+
test(`One segment, 70 characters of "${character}"`, () => {
152+
const testMessage = Array(70).fill(character).join('');
153+
const segmentedMessage = new SegmentedMessage(testMessage);
154+
expect(segmentedMessage.segmentsCount).toBe(1);
155+
segmentedMessage.encodedChars.forEach((encodedChar) => {
156+
expect(encodedChar.isGSM7).toBe(false);
157+
});
158+
});
159+
});
160+
161+
testCharacters.forEach((character) => {
162+
test(`Two segments, 71 characters of "${character}"`, () => {
163+
const testMessage = Array(71).fill(character).join('');
164+
const segmentedMessage = new SegmentedMessage(testMessage);
165+
expect(segmentedMessage.segmentsCount).toBe(2);
166+
segmentedMessage.encodedChars.forEach((encodedChar) => {
167+
expect(encodedChar.isGSM7).toBe(false);
168+
});
169+
});
170+
});
171+
});
172+
173+
describe('Special tests', () => {
174+
test('UCS2 message with special GSM characters in one segment', () => {
175+
// Issue #18: wrong segmnent calculation using GSM special characters
176+
const testMessage = '😀]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
177+
const segmentedMessage = new SegmentedMessage(testMessage);
178+
expect(segmentedMessage.segmentsCount).toBe(1);
179+
})
180+
181+
test('UCS2 message with special GSM characters in two segment', () => {
182+
const testMessage = '😀]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
183+
const segmentedMessage = new SegmentedMessage(testMessage);
184+
expect(segmentedMessage.segmentsCount).toBe(2);
185+
})
186+
187+
188+
189+
""
190+
})

0 commit comments

Comments
 (0)