From 12fcc8361da971e1a3918f36460bc7afce7aa4e8 Mon Sep 17 00:00:00 2001 From: Fumiya Tokumasu Date: Thu, 27 Nov 2025 20:31:02 +0900 Subject: [PATCH] Add IPv4 CIDR four-part decimal validator --- README.md | 1 + lib/ipaddr.js | 11 +++++++++++ lib/ipaddr.js.d.ts | 1 + test/ipaddr.test.js | 8 ++++++++ 4 files changed, 21 insertions(+) diff --git a/README.md b/README.md index c17a459..a8ceff6 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ The `ipaddr.IPv4` and `ipaddr.IPv6` objects have some methods defined, too. All `ipaddr.IPvX.isValid(string)` can be used to check if the string is a valid address for particular protocol, and `ipaddr.IPvX.parse(string)` is the error-throwing parser. `ipaddr.IPvX.isValid(string)` uses the same format for parsing as the POSIX `inet_ntoa` function, which accepts unusual formats like `0xc0.168.1.1` or `0x10000000`. The function `ipaddr.IPv4.isValidFourPartDecimal(string)` validates the IPv4 address and also ensures that it is written in four-part decimal format. +`ipaddr.IPv4.isValidCIDRFourPartDecimal(string)` validates an IPv4 address in CIDR notation and also ensures that its address portion is written in four-part decimal format. [IPv6 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/lib/ipaddr.js#L530 [IPv4 ranges]: https://github.com/whitequark/ipaddr.js/blob/master/lib/ipaddr.js#L182 diff --git a/lib/ipaddr.js b/lib/ipaddr.js index da1ba92..af1e25e 100644 --- a/lib/ipaddr.js +++ b/lib/ipaddr.js @@ -365,6 +365,17 @@ } }; + // Checks if a given string is a full four-part IPv4 Address with CIDR prefix. + ipaddr.IPv4.isValidCIDRFourPartDecimal = function (string) { + const match = string.match(/^(.+)\/(\d+)$/); + + if (!ipaddr.IPv4.isValidCIDR(string) || !match) { + return false; + } + + return ipaddr.IPv4.isValidFourPartDecimal(match[1]); + }; + // A utility function to return network address given the IPv4 interface and prefix length in CIDR notation ipaddr.IPv4.networkAddressFromCIDR = function (string) { let cidr, i, ipInterfaceOctets, octets, subnetMaskOctets; diff --git a/lib/ipaddr.js.d.ts b/lib/ipaddr.js.d.ts index 62afab3..ee02c02 100644 --- a/lib/ipaddr.js.d.ts +++ b/lib/ipaddr.js.d.ts @@ -30,6 +30,7 @@ declare module "ipaddr.js" { static isValid(addr: string): boolean; static isValidCIDR(addr: string): boolean; static isValidFourPartDecimal(addr: string): boolean; + static isValidCIDRFourPartDecimal(addr: string): boolean; static networkAddressFromCIDR(addr: string): IPv4; static parse(addr: string): IPv4; static parseCIDR(addr: string): [IPv4, number]; diff --git a/test/ipaddr.test.js b/test/ipaddr.test.js index 5877588..e83f7a7 100644 --- a/test/ipaddr.test.js +++ b/test/ipaddr.test.js @@ -160,6 +160,14 @@ describe('ipaddr', () => { assert.equal(ipaddr.IPv4.isValidFourPartDecimal('0xc0.168.1.1'), false); }) + it('checks the conventional IPv4 CIDR format', () => { + assert.equal(ipaddr.IPv4.isValidCIDRFourPartDecimal('192.168.1.1/24'), true); + assert.equal(ipaddr.IPv4.isValidCIDRFourPartDecimal('0.0.0.0/0'), true); + assert.equal(ipaddr.IPv4.isValidCIDRFourPartDecimal('0xc0.168.1.1/24'), false); + assert.equal(ipaddr.IPv4.isValidCIDRFourPartDecimal('192.168.1.1/33'), false); + assert.equal(ipaddr.IPv4.isValidCIDRFourPartDecimal('192.168.1/24'), false); + }) + it('refuses to construct IPv4 address with trailing and leading zeros', () => { assert.equal(ipaddr.IPv4.isValidFourPartDecimal('000000192.168.100.2'), false); assert.equal(ipaddr.IPv4.isValidFourPartDecimal('192.0000168.100.2'), false);