Name the option a refused address came from, and the data a 0.5.0 consumer stored
Mirror / push (push) Successful in 4s
Test / lint (pull_request) Successful in 20s
Test / test (18) (pull_request) Successful in 35s
Test / test (20) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 29s
Test / test (24) (pull_request) Successful in 29s
Test / test (26) (pull_request) Successful in 30s
Mirror / push (push) Successful in 4s
Test / lint (pull_request) Successful in 20s
Test / test (18) (pull_request) Successful in 35s
Test / test (20) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 29s
Test / test (24) (pull_request) Successful in 29s
Test / test (26) (pull_request) Successful in 30s
This commit is contained in:
+13
-7
@@ -480,19 +480,25 @@ rule and an index of the titles below.
|
||||
|
||||
- **Every text field on the wire is latin1, and what the field cannot carry is refused rather than
|
||||
truncated.** Maintainer's call, 2026-09-21, the refusals from the security and stability passes on
|
||||
[#16](https://gitea.larvit.se/larvit/smpp-js/pulls/16). Goal 3 settles the alphabet: 3.4 calls
|
||||
these fields ASCII, and an operator routing an alphanumeric sender through the upper half is
|
||||
traffic to keep, so the read is latin1 and the write is named latin1 to match — which is what
|
||||
makes the round trip idempotent, and is already the octets Node put on the wire, so no peer sees a
|
||||
change. Goal 2 settles the refusals, both of them a `size()` that would have agreed with a
|
||||
[#16](https://gitea.larvit.se/larvit/smpp-js/pulls/16). 3.4 calls these fields ASCII, so goal 3
|
||||
settles the read alone — its generous clause is scoped to reading, and its sender clause is strict.
|
||||
Goal 1 settles the write, being 3.4 as SMSCs actually run it: an operator routing an alphanumeric
|
||||
sender through the upper half is traffic to keep, and Node's `ascii` write already emitted the low
|
||||
octet, so `Kaffeé` went out as `4B 61 66 66 65 E9` before this change and goes out as the same
|
||||
octets after it. Naming the write latin1 is what makes the round trip idempotent, and no peer sees
|
||||
a change. 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 the peer reads as the end of the field, shifting every mandatory
|
||||
field behind it under a `command_length` that counted the whole string. `wantText()` and
|
||||
field behind it under a `command_length` that counted the whole string. Goal 4 settles them twice
|
||||
over, since for `一`, ` ` and most emoji that low octet is `0x00` and the field 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
|
||||
to stay strict to 3.4's ASCII, which would drop exactly the traffic the read keeps. Rejected:
|
||||
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; whether an SMSC wants a non-ASCII sender
|
||||
stays its own call, answered as `ESME_RINVSRCADR`. Rejected:
|
||||
refusing `U+0000` in every text field, which would buy one spelling by taking a legitimate octet
|
||||
away from the length-prefixed Octet String, whose length octet is what ends it.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user