Skip to content

Commit e2c8e7c

Browse files
hclclawsweeper[bot]Takhoffman
authored
fix(cli): reject out-of-range port numbers in parsePort (#83900) (#84008)
Summary: - The PR adds a 65,535 upper-bound check to the shared CLI `parsePort` helper, a colocated regression test, and a changelog entry for the linked port-range bug. - Reproducibility: yes. Source inspection on current main shows `parsePort('99999')` delegates to `parseStrict ... sitive safe integer, so the return would be `99999`; I did not execute it because this review is read-only. Automerge notes: - PR branch already contained follow-up commit before automerge: fix(cli): reject out-of-range port numbers in parsePort (#83900) Validation: - ClawSweeper review passed for head 9ad0705. - Required merge gates passed before the squash merge. Prepared head SHA: 9ad0705 Review: #84008 (comment) Co-authored-by: HCL <chenglunhu@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com> Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com> Approved-by: takhoffman Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>
1 parent d7083ba commit e2c8e7c

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Docs: https://docs.openclaw.ai
7070

7171
### Fixes
7272

73+
- CLI: reject explicit port numbers above 65535 before they reach Gateway or Node bind paths. Fixes #83900. (#84008) Thanks @hclsys.
7374
- Codex app-server: preserve plugin tool auth profiles when Codex owns model transport so OpenClaw dynamic tools can resolve their provider credentials. (#83603) Thanks @rubencu.
7475
- Memory/search: scan the JS-side fallback vector path (used when the sqlite-vec index is unavailable or has a mismatched dimension) in bounded rowid batches and yield to the event loop between batches so large chunk tables can no longer pin the Node.js main thread for multi-second windows. Also keeps the SQL prepared statement rooted in a local so node:sqlite cannot finalize it mid-scan under heap pressure. Fixes #81172. Thanks @dev23xyz-oss.
7576
- Memory Wiki: preserve fs-safe diagnostics when bridge source page writes fail for non-symlink filesystem safety reasons, so directory collisions are reported with the underlying error code. (#83776) Thanks @TurboTheTurtle.

src/cli/shared/parse-port.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { describe, expect, it } from "vitest";
2+
import { parsePort } from "./parse-port.js";
3+
4+
describe("parsePort (#83900)", () => {
5+
it("returns null for nullish inputs", () => {
6+
expect(parsePort(undefined)).toBeNull();
7+
expect(parsePort(null)).toBeNull();
8+
});
9+
10+
it("returns null for zero and negative values (already enforced)", () => {
11+
expect(parsePort(0)).toBeNull();
12+
expect(parsePort(-1)).toBeNull();
13+
expect(parsePort("0")).toBeNull();
14+
});
15+
16+
it("accepts valid TCP port values", () => {
17+
expect(parsePort(1)).toBe(1);
18+
expect(parsePort(8080)).toBe(8080);
19+
expect(parsePort("3000")).toBe(3000);
20+
expect(parsePort(65535)).toBe(65535);
21+
});
22+
23+
it("rejects port numbers above 65535 (regression for #83900)", () => {
24+
expect(parsePort(65536)).toBeNull();
25+
expect(parsePort(99999)).toBeNull();
26+
expect(parsePort("100000")).toBeNull();
27+
// Largest 16-bit value is the inclusive boundary.
28+
expect(parsePort(65535)).toBe(65535);
29+
});
30+
31+
it("rejects non-integer and non-finite inputs", () => {
32+
expect(parsePort(1.5)).toBeNull();
33+
expect(parsePort(Number.NaN)).toBeNull();
34+
expect(parsePort(Number.POSITIVE_INFINITY)).toBeNull();
35+
expect(parsePort("abc")).toBeNull();
36+
});
37+
});

src/cli/shared/parse-port.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
11
import { parseStrictPositiveInteger } from "../../infra/parse-finite-number.js";
22

3+
// TCP/UDP ports are 16-bit, so 65535 is the max. `parseStrictPositiveInteger`
4+
// only enforces positivity, so values like 99999 were returned as-is and
5+
// reached gateway-cli / node-cli bind paths; the OS then surfaced the error
6+
// instead of the CLI rejecting it cleanly at parse time. See #83900.
7+
const MAX_TCP_PORT = 65_535;
8+
39
export function parsePort(raw: unknown): number | null {
410
if (raw === undefined || raw === null) {
511
return null;
612
}
7-
return parseStrictPositiveInteger(raw) ?? null;
13+
const parsed = parseStrictPositiveInteger(raw);
14+
if (parsed === undefined || parsed > MAX_TCP_PORT) {
15+
return null;
16+
}
17+
return parsed;
818
}

0 commit comments

Comments
 (0)