From fde027dccec3f3e0ddd651675753a9e7453e2bd8 Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Sun, 28 Jun 2026 00:06:46 +0900 Subject: [PATCH] lib: reject string "0" in validatePort when allowZero is false The allowZero guard compared the raw value with `port === 0`, but validatePort accepts strings and coerces them with `+port` in every other clause. Since `'0' === 0` is false, string forms of zero ('0', ' 0 ', '00', '0x0', ...) slipped past the guard when allowZero was false, while the numeric 0 was correctly rejected. This is reachable via dgram's send(), connect(), and bind(), which call validatePort(port, 'Port', false): passing '0' was silently accepted instead of throwing ERR_SOCKET_BAD_PORT. Coerce the value with `+port` so the zero check matches the rest of the validation. Signed-off-by: Daijiro Wachi --- lib/internal/validators.js | 2 +- .../test-internal-validators-validateport.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 668e17c13daaef..f8f1b9383d1704 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -438,7 +438,7 @@ const validatePort = hideStackFrames((port, name = 'Port', allowZero = true) => (typeof port === 'string' && StringPrototypeTrim(port).length === 0) || +port !== (+port >>> 0) || port > 0xFFFF || - (port === 0 && !allowZero)) { + (+port === 0 && !allowZero)) { throw new ERR_SOCKET_BAD_PORT(name, port, allowZero); } return port | 0; diff --git a/test/parallel/test-internal-validators-validateport.js b/test/parallel/test-internal-validators-validateport.js index a4c92b8dbca929..b125d0a93f71ab 100644 --- a/test/parallel/test-internal-validators-validateport.js +++ b/test/parallel/test-internal-validators-validateport.js @@ -21,3 +21,17 @@ for (let n = 0; n <= 0xFFFF; n++) { ].forEach((i) => assert.throws(() => validatePort(i), { code: 'ERR_SOCKET_BAD_PORT' })); + +// When allowZero is false, every form of zero must be rejected, including +// the string forms that coerce to 0. Refs: the zero check must coerce the +// value the same way the rest of the validation does (`+port`). +[ + 0, '0', ' 0 ', '00', '0x0', '0o0', '0b0', +].forEach((i) => assert.throws(() => validatePort(i, 'Port', false), { + code: 'ERR_SOCKET_BAD_PORT' +})); + +// With allowZero left at its default (true), those same values are accepted. +[ + 0, '0', ' 0 ', '00', '0x0', '0o0', '0b0', +].forEach((i) => assert.strictEqual(validatePort(i), 0));