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',
],
});
});