From 259e5e6803f17c6bbbeb1f15b30a318fb1a0a380 Mon Sep 17 00:00:00 2001 From: nivokvo Date: Fri, 21 Aug 2026 04:48:00 +0300 Subject: [PATCH] fix: refuse both-numeric names to match the registry's policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parseRegistryName accepted '1.420' as a Moshpit name while the registry (moshpit-name) refuses it — several parsers read a two-part dotted number as an abbreviated IPv4 literal. The file's own header promises the same semantics as the reference implementation, and the comment on the label rule says matching the registry matters more than the rule itself; this branch diverged from both. Effect before the fix: with clearnet silent, '1.420' resolved to a parking page for a name the registry can never register. --- lib/index.mjs | 5 +++++ test/resolve.test.mjs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/lib/index.mjs b/lib/index.mjs index d276e77..6c21560 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -119,6 +119,11 @@ export function parseRegistryName(hostname) { // registry rejects sends a tab to a page saying it does not exist. const LABEL = /^[a-z0-9]{1,63}$/; if (!LABEL.test(label) || !LABEL.test(tld)) return null; + // Both halves numeric is refused by the registry — several parsers read a + // two-part dotted number as an abbreviated IPv4 literal, so `1.420` is + // genuinely ambiguous where `blue.420` is not. Accepting it here would send + // a tab to a parking page for a name the registry can never register. + if (/^\d+$/.test(label) && /^\d+$/.test(tld)) return null; return { label, tld }; } diff --git a/test/resolve.test.mjs b/test/resolve.test.mjs index 2afade7..83c906e 100644 --- a/test/resolve.test.mjs +++ b/test/resolve.test.mjs @@ -241,4 +241,9 @@ test("dashes are not part of a Moshpit name", () => { } assert.deepEqual(parseRegistryName("california.oranges"), { label: "california", tld: "oranges" }); assert.deepEqual(parseRegistryName("blue.420"), { label: "blue", tld: "420" }); + // Both halves numeric is refused by the registry (reads as an abbreviated + // IPv4 literal), so the port refuses it too — otherwise a tab lands on a + // parking page for a name the registry can never register. + assert.equal(parseRegistryName("1.420"), null, "1.420"); + assert.equal(parseRegistryName("420.187"), null, "420.187"); });