Refuse a maxOctets below 1 at startup, like the other limits
Test / lint (pull_request) Successful in 49s
Test / test (18) (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 29s
Test / test (22) (pull_request) Successful in 29s
Test / test (24) (pull_request) Successful in 28s
Test / test (26) (pull_request) Successful in 29s
Mirror / push (push) Successful in 3s

This commit is contained in:
2026-09-23 23:48:18 +02:00
parent 228b81aa5e
commit 80f77afa0f
5 changed files with 14 additions and 7 deletions
+2
View File
@@ -35,6 +35,8 @@
- An `alert_notification` or an `outbind` from the peer is logged and left unanswered, as SMPP 3.4
gives neither a response. Each one used to emit `sessionError`, `"alert_notification" has no
response command`.
- `server()` refuses a `maxOctets` below 1 or not a whole number, like its other limits.
`server({ maxOctets: 0 })` used to start and then drop every multipart message.
## 0.5.0
+1 -1
View File
@@ -43,7 +43,7 @@ export type Collected =
whole?: PduObject[] | undefined;
};
const defaultMaxOctets = 64 * 1024 * 1024;
export const defaultMaxOctets = 64 * 1024 * 1024;
type Group = {
octets: number;
+3
View File
@@ -9,6 +9,7 @@ import type { SmsIdFormat } from './sms-id.ts';
import type { Sms } from './sms.ts';
import type { Socket } from 'node:net';
import { backoffDefaults } from './reconnect-loop.ts';
import { defaultMaxOctets } from './reassembly.ts';
import { isSmsIdNotation, smsIdNotations, smsIdPlaces } from './sms-id.ts';
import { namedValue } from './error-from.ts';
@@ -160,6 +161,7 @@ export function checkSessionOptions(options: CheckableOptions): VoidResult {
function limitsOf(options: CheckableOptions): [string, number, number][] {
return [
['idleTimeout', options.idleTimeout ?? 0, 0],
['maxOctets', options.maxOctets ?? defaultMaxOctets, 1],
['maxOutstanding', options.maxOutstanding ?? defaults.maxOutstanding, 1],
['maxReassembly', options.maxReassembly ?? defaults.maxReassembly, 1],
['reassemblyTimeout', options.reassemblyTimeout ?? defaults.reassemblyTimeout, 0],
@@ -268,6 +270,7 @@ export type CheckableOptions = {
/** Not an option: the one spelling is inside reconnect, and this is where the other is refused. */
fromStart?: unknown;
idleTimeout?: number | undefined;
maxOctets?: number | undefined;
maxOutstanding?: number | undefined;
maxReassembly?: number | undefined;
reassemblyTimeout?: number | undefined;
+8
View File
@@ -2688,6 +2688,14 @@ describe('option validation', () => {
assert.match(hookRefused.err?.message ?? '', /onRequest must be a function/);
});
test('refuses a reassembly octet cap below 1 at startup', async () => {
const listening = await server({ maxOctets: 0, port: 0 });
if (listening.server) await listening.server.close();
assert.match(listening.err?.message ?? '', /maxOctets must be 1 or more, got 0/);
});
test('returns an error rather than rejecting on an impossible port', async () => {
const listening = await server({ port: 70_000 });
-6
View File
@@ -189,12 +189,6 @@ and is also what the panel ranked hardest — two methods, one answer.
### Correctness, ahead of everything below
- [ ] **Range-check `maxOctets` with its five siblings.** `limitsOf()` in `session-options.ts`
covers `idleTimeout`, `maxOutstanding`, `maxReassembly`, `reassemblyTimeout`, `responseTimeout`
and `shutdownTimeout`; `maxOctets` is documented, consumed by `Reassembler`, and absent from
both that list and `CheckableOptions`. `server({ maxOctets: 0 })` starts, then refuses every
multipart message and reports each as lost traffic.
- [ ] **Read `multiple` in `parseTlvs()` and `writeTlvs()`, or delete it and `tlvMap`.** Five TLVs
declare `multiple: true` (`callback_num`, `callback_num_atag`, `callback_num_pres_ind`,
`broadcast_area_identifier`, `broadcast_error_status`) and nothing reads it; `parseTlvs()` keys