From 9ac7e78a3bbac78b8bf68847035acbd36f20e0cf Mon Sep 17 00:00:00 2001 From: achingbrain Date: Mon, 7 Jul 2025 15:22:03 +0200 Subject: [PATCH] fix: match ip6 zones and ip cidr in ip matchers Support including ip6 zones and cidr blocks in ip6 and ip4/6 addresses --- src/index.ts | 13 ++++++++++--- src/utils.ts | 10 +++++++++- test/index.spec.ts | 14 ++++++++------ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/index.ts b/src/index.ts index 7d65160..f884aff 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,7 +32,7 @@ * ``` */ -import { CODE_P2P, CODE_DNS4, CODE_DNS6, CODE_DNSADDR, CODE_DNS, CODE_IP4, CODE_IP6, CODE_TCP, CODE_UDP, CODE_QUIC, CODE_QUIC_V1, CODE_WS, CODE_WSS, CODE_TLS, CODE_SNI, CODE_WEBRTC_DIRECT, CODE_CERTHASH, CODE_WEBTRANSPORT, CODE_P2P_CIRCUIT, CODE_WEBRTC, CODE_HTTP, CODE_UNIX, CODE_HTTPS, CODE_MEMORY } from '@multiformats/multiaddr' +import { CODE_P2P, CODE_DNS4, CODE_DNS6, CODE_DNSADDR, CODE_DNS, CODE_IP4, CODE_IP6, CODE_TCP, CODE_UDP, CODE_QUIC, CODE_QUIC_V1, CODE_WS, CODE_WSS, CODE_TLS, CODE_SNI, CODE_WEBRTC_DIRECT, CODE_CERTHASH, CODE_WEBTRANSPORT, CODE_P2P_CIRCUIT, CODE_WEBRTC, CODE_HTTP, CODE_UNIX, CODE_HTTPS, CODE_MEMORY, CODE_IP6ZONE, CODE_IPCIDR } from '@multiformats/multiaddr' import { and, or, optional, fmt, code, value } from './utils.js' import type { Multiaddr, Component } from '@multiformats/multiaddr' @@ -159,8 +159,15 @@ export const DNSADDR = fmt(_DNSADDR, optional(value(CODE_P2P))) */ export const DNS = fmt(or(_DNS, _DNSADDR, _DNS4, _DNS6), optional(value(CODE_P2P))) -const _IP4 = value(CODE_IP4) -const _IP6 = value(CODE_IP6) +const _IP4 = and( + value(CODE_IP4), + optional(value(CODE_IPCIDR)) +) +const _IP6 = and( + optional(value(CODE_IP6ZONE)), + value(CODE_IP6), + optional(value(CODE_IPCIDR)) +) const _IP = or(_IP4, _IP6) const _IP_OR_DOMAIN = or(_IP, _DNS, _DNS4, _DNS6, _DNSADDR) diff --git a/src/utils.ts b/src/utils.ts index d0bd3e0..cb3689e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -9,7 +9,15 @@ export const code = (code: number): Matcher => { match: (vals) => { const component = vals[0] - if (component?.code !== code) { + if (component == null) { + return false + } + + if (component.code !== code) { + return false + } + + if (component.value != null) { return false } diff --git a/test/index.spec.ts b/test/index.spec.ts index 646b14e..a1cdee7 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -28,17 +28,19 @@ describe('multiaddr matcher', () => { const exactIP = [ '/ip4/0.0.0.0', '/ip6/fc00::', - '/ip6/fe80::8cb1:25ff:fec5:28e3' - // https://github.com/ChainSafe/is-ip/issues/9 - // '/ip6/fe80::8cb1:25ff:fec5:28e3%llw0' + '/ip6/fe80::8cb1:25ff:fec5:28e3', + '/ip6/fe80::1cc1:a3b8:322f:cf22/ipcidr/24', + '/ip6zone/utun0/ip6/fe80::1cc1:a3b8:322f:cf22', + '/ip6zone/llw0/ip6/fe80::1cc1:a3b8:322f:cf22/ipcidr/24' ] const goodIP = [ ...exactIP, '/ip4/123.123.123.123/tcp/80', - '/ip6/fe80::1cc1:a3b8:322f:cf22/udp/4921/wss' - // https://github.com/ChainSafe/is-ip/issues/9 - // '/ip6/fe80::1cc1:a3b8:322f:cf22%utun0/udp/4921/wss' + '/ip6/fe80::1cc1:a3b8:322f:cf22/udp/4921/wss', + '/ip6/fe80::1cc1:a3b8:322f:cf22/ipcidr/24/tcp/1234/tls/ws', + '/ip6zone/utun0/ip6/fe80::1cc1:a3b8:322f:cf22/udp/4921', + '/ip6zone/llw0/ip6/fe80::1cc1:a3b8:322f:cf22/ipcidr/24/udp/4921' ] const badIP = [