Refuse a non-finite number where a text field coerces one #18

Merged
lilleman merged 9 commits from worktree-non-finite-text into main 2026-09-21 10:46:52 +02:00
2 changed files with 20 additions and 10 deletions
Showing only changes of commit 0c4e6000b0 - Show all commits
+7 -4
View File
@@ -25,10 +25,13 @@
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. An Octet String carries a NULL as before. refused. An Octet String carries a NULL as before.
- A non-finite number — `NaN`, `Infinity`, `-Infinity` — is refused where a text field takes one. - A non-finite number — `NaN`, `Infinity`, `-Infinity` — is refused where a text field on the wire
`sendSms({ from: NaN })` put the literal sender `NaN` on the wire and reported the send as takes one. `sendSms({ from: NaN })` put the literal sender `NaN` on the wire and resolved as a
successful; `message_id`, `source_addr` and every other text field took such a number the same way. successful send; `message_id`, `source_addr` and the string TLVs took such a number the same way.
Any other number goes out as `String()` spells it, so `message_id: 123` is unchanged. The call now resolves with `err` naming the field — `from: Expected a finite number, got NaN` — so
a caller that reads only `smsIds` meets a failure it has not met before. A whole number in an
address or an id still spells its digits, so `message_id: 123` is unchanged. The integer fields
name a refused `NaN` too, where the refusal used to read `null`.
## 0.5.0 ## 0.5.0
+13 -6
View File
@@ -231,12 +231,19 @@ and is also what the panel ranked hardest — two methods, one answer.
built, as "TLV 12594 runs past the end of the PDU". Goals 1 and 2. From the stability review built, as "TLV 12594 runs past the end of the PDU". Goals 1 and 2. From the stability review
of #18. of #18.
- [ ] **Settle which numbers may spell a text field, and refuse the rest.** `wantText()` takes every - [ ] **Settle which numbers may spell a text field, refuse the rest, and say so where a consumer
finite number through `String()`, so `message_id: 1e21` writes `1e+21` and `from: 0.1 + 0.2` reads it.** `wantText()` takes every finite number through `String()`, so `message_id: 1e21`
writes `0.30000000000000004` — neither is the id or the address the caller meant, and both are writes `1e+21`, `from: 0.1 + 0.2` writes `0.30000000000000004` and `source_addr: -5` writes
reported as sent. The numeric branch exists for a digit sequence (`message_id: 123`): either `-5` — none of them is the id or the address the caller meant, and all three are reported as
narrow it to one, or record why exponential notation may go on the wire. Goal 3, and the open sent. The numeric branch exists for a digit sequence (`message_id: 123`); the product-owner
half of the non-finite guard #18 shipped. From the stability review of #18. review of #18 recommends `Number.isSafeInteger(value) && value >= 0` with the refusal naming
the fix, since a 64-bit SMSC id loses digits to a JS number before this library ever sees it.
Goal 3. That a number is accepted at all reaches a consumer in no sentence either: only the
type comment at `defs/commands.ts:239`, and one CHANGELOG line that stops being visible when
0.7.0 is cut, while README's Building bullet reads as the whole rule for a text field. Whether
this is a supported spelling or 0.4.0 tolerance decides whether that sentence lands in
README.md or in MIGRATION.md — write it in the same change as the rule, so it is worded once.
From the stability and product-owner reviews of #18.
### Throughput — goal 6, and the default window is where we are slowest ### Throughput — goal 6, and the default window is where we are slowest