From 08c161daa159fd4cdfa520ad099eaf65aaec36be Mon Sep 17 00:00:00 2001 From: RissRIce Date: Mon, 10 Aug 2026 13:00:46 -0600 Subject: [PATCH] fix(config): validate TCP port settings --- lib/config.ts | 7 +++++-- tests/config.test.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 tests/config.test.ts diff --git a/lib/config.ts b/lib/config.ts index 4d00167..f2ca6fc 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -67,8 +67,11 @@ function loadOverrides(path: string): Record { } function intOr(value: string | undefined, fallback: number): number { - const parsed = Number.parseInt(value ?? "", 10); - return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback; + const text = value?.trim() ?? ""; + if (!/^\d+$/.test(text)) return fallback; + + const parsed = Number(text); + return Number.isSafeInteger(parsed) && parsed > 0 && parsed <= 65_535 ? parsed : fallback; } function truthy(value: string | undefined): boolean { diff --git a/tests/config.test.ts b/tests/config.test.ts new file mode 100644 index 0000000..4540cca --- /dev/null +++ b/tests/config.test.ts @@ -0,0 +1,29 @@ +import { describe, test } from "node:test"; +import assert from "node:assert/strict"; +import { loadConfig } from "../lib/config.ts"; + +describe("config", () => { + test("rejects malformed and out-of-range port values", () => { + for (const value of ["443junk", "1.5", "0", "-1", "65536", "Infinity"]) { + const config = loadConfig({ + MOSHPIT_PROXY_DIR: "unused", + MOSHPIT_PROXY_PORT: value, + MOSHPIT_GATEWAY_PORT: value, + }); + + assert.equal(config.listenPort, 8443, `listen port should reject ${value}`); + assert.equal(config.gatewayPort, 443, `gateway port should reject ${value}`); + } + }); + + test("accepts trimmed ports across the full valid range", () => { + const config = loadConfig({ + MOSHPIT_PROXY_DIR: "unused", + MOSHPIT_PROXY_PORT: " 1 ", + MOSHPIT_GATEWAY_PORT: "65535", + }); + + assert.equal(config.listenPort, 1); + assert.equal(config.gatewayPort, 65_535); + }); +});