diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ecf03a..8d78acf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,17 +10,14 @@ `source_addr` of `Kaffeé` previously reached the application as `Kaffei`, because the codec wrote the octet and then masked bit 7 reading it back; `destination_addr`, `system_id`, `message_id`, `service_type` and the C-Octet String TLVs were affected the same way. A character past `U+00FF` - in one of those fields is now refused, where it used to go out as its low octet — which for `一`, - ` ` and most emoji is `0x00`, ending the field there. + in one of those fields is now refused, where it used to go out as its low octet. **Check what you stored before you roll this out.** Values your application persisted under 0.5.0 were read with bit 7 masked, so an address or a `message_id` carrying an octet above `0x7F` is spelled differently now: a stored id will not match the receipt it belongs to, and a stored address will not match the sender it came from. Ids most SMSCs issue are digits or hex and are unaffected. - A `U+0000` inside a C-Octet String — `source_addr`, `message_id`, `system_id` and the rest — is - refused. The peer reads such a field to its first NULL, so one sent inside the value shifted every - mandatory field behind it while `command_length` still counted the whole string. An Octet String - carries a NULL as before; its length octet is what ends it. + refused. An Octet String carries a NULL as before. ## 0.5.0 diff --git a/README.md b/README.md index 5305de7..59d280b 100644 --- a/README.md +++ b/README.md @@ -288,11 +288,11 @@ await session.sendSms({ ``` **Addresses.** `sourceAddrTon` and `destinationAddrTon` default to 5 for an alphanumeric address -and 1 for a numeric one; the NPI fields default to 0. An address is latin1: `Kaffeé` goes out as -the six octets that spell it, `4B 61 66 66 65 E9`, and an address you received always sends back. -One outside `/^[\u0001-\u00FF]*$/` is refused, naming the character and its index — strip or -transliterate it first. An SMSC may still refuse a non-ASCII sender of its own accord, which -reaches you as a refusal such as `ESME_RINVSRCADR`. +and 1 for a numeric one; the NPI fields default to 0. An address is latin1, so `é` is one octet on +the wire and an address you received always sends back. One outside `/^[\u0001-\u00FF]*$/` is +refused, naming the character and its index — strip or transliterate it first. An SMSC may still +refuse a non-ASCII sender of its own accord, which reaches you as a refusal such as +`ESME_RINVSRCADR`. **Encoding.** @@ -614,8 +614,7 @@ if (isCommand(pduObj, 'submit_sm')) { names, detected from the text where you name none. One that alphabet cannot carry is refused, naming the character, its code point and where it is. - Every text field is latin1: addresses, `system_id`, `message_id`, `service_type` and the C-Octet - String TLVs. A character past `U+00FF` is refused, as is a `U+0000` in a C-Octet String, which the - peer reads as the end of the field. + String TLVs. A character past `U+00FF` is refused, as is a `U+0000` in a C-Octet String. - A `Buffer` goes out exactly as given under any `data_coding`: binary payloads, hand-built user data headers, deliberately malformed bodies. - `session.send()` and `session.sendReturn()` build through the same codec and refuse the same bodies. diff --git a/docs/decisions.md b/docs/decisions.md index 061277d..118e9a7 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -488,12 +488,10 @@ rule and an index of the titles below. Goal 2 settles the refusals, both of them a `size()` that would have agreed with a `write()` that put something else on the wire: a character past `U+00FF` written as its low octet, and a caller's own `U+0000`, which a mandatory field's reader takes as the end of the field. Goal 4 settles them - twice over: for a great many characters that low octet is `0x00`, and the PDU went out malformed + twice over: for one character in every 256 that low octet is `0x00`, and the PDU went out malformed on the operator's parser. `wantText()` and `wantCstringText()` are the only two places that decide - it, which is why the `dest_address` and - `unsuccess_sme` structures write their embedded addresses through `cstring.write()` rather than - reaching past it into `writeCstring()`. Rejected: reading latin1 and leaving the write spelled - ASCII, which leaves two halves agreeing only by accident. Rejected: refusing the upper half on send + it. Rejected: reading latin1 and leaving the write spelled ASCII, which leaves two halves agreeing + only by accident. Rejected: refusing the upper half on send to stay strict to 3.4's ASCII, which would be a new restriction taking away traffic this library already sends and operators already accept, on no defect. Rejected: refusing `U+0000` in every text field, which would buy one spelling by taking a legitimate octet away from the diff --git a/test/unsendable.test.ts b/test/unsendable.test.ts index 3c8c7e3..f01aef4 100644 --- a/test/unsendable.test.ts +++ b/test/unsendable.test.ts @@ -366,7 +366,7 @@ describe('an address the field cannot carry', () => { assert.deepEqual(sent.smsIds, [], address); } - assert.deepEqual(smsc.octets, [], 'an address the field cannot carry never reaches the socket'); + assert.deepEqual(smsc.octets, []); }); });