Cut the prose the code, the error and the record already carry
Test / lint (pull_request) Successful in 21s
Test / test (18) (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 29s
Test / test (22) (pull_request) Successful in 30s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 29s
Mirror / push (push) Successful in 5s

This commit was merged in pull request #16.
This commit is contained in:
2026-09-21 08:25:39 +02:00
parent a7eb4923f5
commit 36a1c6ea7b
4 changed files with 12 additions and 18 deletions
+2 -5
View File
@@ -10,17 +10,14 @@
`source_addr` of `Kaffeé` previously reached the application as `Kaffei`, because the codec wrote `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`, 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` `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 `一`, in one of those fields is now refused, where it used to go out as its low octet.
` ` and most emoji is `0x00`, ending the field there.
**Check what you stored before you roll this out.** Values your application persisted under 0.5.0 **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 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 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. 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 - 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 refused. An Octet String carries a NULL as before.
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.
## 0.5.0 ## 0.5.0
+6 -7
View File
@@ -288,11 +288,11 @@ await session.sendSms({
``` ```
**Addresses.** `sourceAddrTon` and `destinationAddrTon` default to 5 for an alphanumeric address **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 and 1 for a numeric one; the NPI fields default to 0. An address is latin1, so `é` is one octet on
the six octets that spell it, `4B 61 66 66 65 E9`, and an address you received always sends back. the wire and an address you received always sends back. One outside `/^[\u0001-\u00FF]*$/` is
One outside `/^[\u0001-\u00FF]*$/` is refused, naming the character and its index — strip or refused, naming the character and its index — strip or transliterate it first. An SMSC may still
transliterate it first. An SMSC may still refuse a non-ASCII sender of its own accord, which refuse a non-ASCII sender of its own accord, which reaches you as a refusal such as
reaches you as a refusal such as `ESME_RINVSRCADR`. `ESME_RINVSRCADR`.
**Encoding.** **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, 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. 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 - 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 String TLVs. A character past `U+00FF` is refused, as is a `U+0000` in a C-Octet String.
peer reads as the end of the field.
- A `Buffer` goes out exactly as given under any `data_coding`: binary payloads, hand-built user - A `Buffer` goes out exactly as given under any `data_coding`: binary payloads, hand-built user
data headers, deliberately malformed bodies. data headers, deliberately malformed bodies.
- `session.send()` and `session.sendReturn()` build through the same codec and refuse the same bodies. - `session.send()` and `session.sendReturn()` build through the same codec and refuse the same bodies.
+3 -5
View File
@@ -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 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 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 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 on the operator's parser. `wantText()` and `wantCstringText()` are the only two places that decide
it, which is why the `dest_address` and it. Rejected: reading latin1 and leaving the write spelled ASCII, which leaves two halves agreeing
`unsuccess_sme` structures write their embedded addresses through `cstring.write()` rather than only by accident. Rejected: refusing the upper half on send
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
to stay strict to 3.4's ASCII, which would be a new restriction taking away traffic this library 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 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 text field, which would buy one spelling by taking a legitimate octet away from the
+1 -1
View File
@@ -366,7 +366,7 @@ describe('an address the field cannot carry', () => {
assert.deepEqual(sent.smsIds, [], address); assert.deepEqual(sent.smsIds, [], address);
} }
assert.deepEqual(smsc.octets, [], 'an address the field cannot carry never reaches the socket'); assert.deepEqual(smsc.octets, []);
}); });
}); });