diff --git a/README.md b/README.md index ab5609ae0..b76bada04 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ Validator | Description **isIn(str, values)** | check if the string is in a array of allowed values. **isInt(str [, options])** | check if the string is an integer.

`options` is an object which can contain the keys `min` and/or `max` to check the integer is within boundaries (e.g. `{ min: 10, max: 99 }`). `options` can also contain the key `allow_leading_zeroes`, which when set to false will disallow integer values with leading zeroes (e.g. `{ allow_leading_zeroes: false }`). Finally, `options` can contain the keys `gt` and/or `lt` which will enforce integers being greater than or less than, respectively, the value provided (e.g. `{gt: 1, lt: 4}` for a number between 1 and 4). **isIP(str [, version])** | check if the string is an IP (version 4 or 6). -**isIPRange(str)** | check if the string is an IP Range(version 4 only). +**isIPRange(str [, version])** | check if the string is an IP Range (version 4 or 6). **isISBN(str [, version])** | check if the string is an ISBN (version 10 or 13). **isISIN(str)** | check if the string is an [ISIN][ISIN] (stock/security identifier). **isISO8601(str)** | check if the string is a valid [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date.
`options` is an object which defaults to `{ strict: false, strictSeparator: false }`. If `strict` is true, date strings with invalid dates like `2009-02-29` will be invalid. If `strictSeparator` is true, date strings with date and time separated by anything other than a T will be invalid. diff --git a/src/lib/isIPRange.js b/src/lib/isIPRange.js index ffb4e1afa..5bb6916c5 100644 --- a/src/lib/isIPRange.js +++ b/src/lib/isIPRange.js @@ -1,9 +1,11 @@ import assertString from './util/assertString'; import isIP from './isIP'; -const subnetMaybe = /^\d{1,2}$/; +const subnetMaybe = /^\d{1,3}$/; +const v4Subnet = 32; +const v6Subnet = 128; -export default function isIPRange(str) { +export default function isIPRange(str, version = '') { assertString(str); const parts = str.split('/'); @@ -21,5 +23,25 @@ export default function isIPRange(str) { return false; } - return isIP(parts[0], 4) && parts[1] <= 32 && parts[1] >= 0; + const isValidIP = isIP(parts[0], version); + if (!isValidIP) { + return false; + } + + // Define valid subnet according to IP's version + let expectedSubnet = null; + switch (String(version)) { + case '4': + expectedSubnet = v4Subnet; + break; + + case '6': + expectedSubnet = v6Subnet; + break; + + default: + expectedSubnet = isIP(parts[0], '6') ? v6Subnet : v4Subnet; + } + + return parts[1] <= expectedSubnet && parts[1] >= 0; } diff --git a/test/validators.js b/test/validators.js index 34b6474e8..1e5aa1547 100644 --- a/test/validators.js +++ b/test/validators.js @@ -872,18 +872,88 @@ describe('Validators', () => { '127.0.0.1/24', '0.0.0.0/0', '255.255.255.0/32', + '::/0', + '::/128', + '2001::/128', + '2001:800::/128', + '::ffff:127.0.0.1/128', ], invalid: [ + 'abc', '127.200.230.1/35', '127.200.230.1/-1', '1.1.1.1/011', - '::1/64', '1.1.1/24.1', '1.1.1.1/01', '1.1.1.1/1.1', '1.1.1.1/1.', '1.1.1.1/1/1', '1.1.1.1', + '::1', + '::1/164', + '2001::/240', + '2001::/-1', + '2001::/001', + '2001::/24.1', + '2001:db8:0000:1:1:1:1:1', + '::ffff:127.0.0.1', + ], + }); + test({ + validator: 'isIPRange', + args: [4], + valid: [ + '127.0.0.1/1', + '0.0.0.0/1', + '255.255.255.255/1', + '1.2.3.4/1', + '255.0.0.1/1', + '0.0.1.1/1', + ], + invalid: [ + 'abc', + '::1', + '2001:db8:0000:1:1:1:1:1', + '::ffff:127.0.0.1', + '137.132.10.01', + '0.256.0.256', + '255.256.255.256', + ], + }); + test({ + validator: 'isIPRange', + args: [6], + valid: [ + '::1/1', + '2001:db8:0000:1:1:1:1:1/1', + '::ffff:127.0.0.1/1', + ], + invalid: [ + 'abc', + '127.0.0.1', + '0.0.0.0', + '255.255.255.255', + '1.2.3.4', + '::ffff:287.0.0.1', + '::ffff:287.0.0.1/254', + '%', + 'fe80::1234%', + 'fe80::1234%1%3%4', + 'fe80%fe80%', + ], + }); + test({ + validator: 'isIPRange', + args: [10], + valid: [], + invalid: [ + 'abc', + '127.0.0.1/1', + '0.0.0.0/1', + '255.255.255.255/1', + '1.2.3.4/1', + '::1/1', + '2001:db8:0000:1:1:1:1:1/1', ], }); });