Skip to content

Commit 8b7afe6

Browse files
committed
Support regular expressions in host whitelist/backlist, closes #562
1 parent 2bf79a5 commit 8b7afe6

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
([#564](https://github.com/chriso/validator.js/issues/564))
55
- Added support for urls without a host (e.g. `file:///foo.txt`) in `isURL()`
66
([#563](https://github.com/chriso/validator.js/issues/563))
7+
- Added support for regular expressions in the `isURL()` host whitelist and blacklist
8+
([#562](https://github.com/chriso/validator.js/issues/562))
79
- Added support for MasterCard 2-Series BIN
810
([#576](https://github.com/chriso/validator.js/pull/576))
911
- New locales

lib/isURL.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ var default_url_options = {
3636

3737
var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
3838

39+
function isRegExp(obj) {
40+
return Object.prototype.toString.call(obj) === '[object RegExp]';
41+
}
42+
43+
function checkHost(host, matches) {
44+
for (var i = 0; i < matches.length; i++) {
45+
var match = matches[i];
46+
if (host === match || isRegExp(match) && match.test(host)) {
47+
return true;
48+
}
49+
}
50+
return false;
51+
}
52+
3953
function isURL(url, options) {
4054
(0, _assertString2.default)(url);
4155
if (!url || url.length >= 2083 || /\s/.test(url)) {
@@ -113,12 +127,16 @@ function isURL(url, options) {
113127
if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6)) && host !== 'localhost') {
114128
return false;
115129
}
116-
if (options.host_whitelist && options.host_whitelist.indexOf(host) === -1) {
130+
131+
host = host || ipv6;
132+
133+
if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
117134
return false;
118135
}
119-
if (options.host_blacklist && options.host_blacklist.indexOf(host) !== -1) {
136+
if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
120137
return false;
121138
}
139+
122140
return true;
123141
}
124142
module.exports = exports['default'];

src/lib/isURL.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ const default_url_options = {
1717

1818
const wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
1919

20+
function isRegExp(obj) {
21+
return Object.prototype.toString.call(obj) === '[object RegExp]';
22+
}
23+
24+
function checkHost(host, matches) {
25+
for (let i = 0; i < matches.length; i++) {
26+
let match = matches[i];
27+
if (host === match || (isRegExp(match) && match.test(host))) {
28+
return true;
29+
}
30+
}
31+
return false;
32+
}
33+
2034
export default function isURL(url, options) {
2135
assertString(url);
2236
if (!url || url.length >= 2083 || /\s/.test(url)) {
@@ -88,11 +102,15 @@ export default function isURL(url, options) {
88102
host !== 'localhost') {
89103
return false;
90104
}
91-
if (options.host_whitelist && options.host_whitelist.indexOf(host) === -1) {
105+
106+
host = host || ipv6;
107+
108+
if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
92109
return false;
93110
}
94-
if (options.host_blacklist && options.host_blacklist.indexOf(host) !== -1) {
111+
if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
95112
return false;
96113
}
114+
97115
return true;
98116
}

test/validators.js

+42
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,27 @@ describe('Validators', function () {
402402
});
403403
});
404404

405+
it('should allow regular expressions in the host whitelist', function () {
406+
test({
407+
validator: 'isURL',
408+
args: [{
409+
host_whitelist: ['bar.com', 'foo.com', /\.foo\.com$/],
410+
}],
411+
valid: [
412+
'http://bar.com/',
413+
'http://foo.com/',
414+
'http://images.foo.com/',
415+
'http://cdn.foo.com/',
416+
'http://a.b.c.foo.com/',
417+
],
418+
invalid: [
419+
'http://foobar.com',
420+
'http://foo.bar.com/',
421+
'http://qux.com',
422+
],
423+
});
424+
});
425+
405426
it('should let users specify a host blacklist', function () {
406427
test({
407428
validator: 'isURL',
@@ -420,6 +441,27 @@ describe('Validators', function () {
420441
});
421442
});
422443

444+
it('should allow regular expressions in the host blacklist', function () {
445+
test({
446+
validator: 'isURL',
447+
args: [{
448+
host_blacklist: ['bar.com', 'foo.com', /\.foo\.com$/],
449+
}],
450+
valid: [
451+
'http://foobar.com',
452+
'http://foo.bar.com/',
453+
'http://qux.com',
454+
],
455+
invalid: [
456+
'http://bar.com/',
457+
'http://foo.com/',
458+
'http://images.foo.com/',
459+
'http://cdn.foo.com/',
460+
'http://a.b.c.foo.com/',
461+
],
462+
});
463+
});
464+
423465
it('should validate MAC addresses', function () {
424466
test({
425467
validator: 'isMACAddress',

validator.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,20 @@
304304

305305
var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/;
306306

307+
function isRegExp(obj) {
308+
return Object.prototype.toString.call(obj) === '[object RegExp]';
309+
}
310+
311+
function checkHost(host, matches) {
312+
for (var i = 0; i < matches.length; i++) {
313+
var match = matches[i];
314+
if (host === match || isRegExp(match) && match.test(host)) {
315+
return true;
316+
}
317+
}
318+
return false;
319+
}
320+
307321
function isURL(url, options) {
308322
assertString(url);
309323
if (!url || url.length >= 2083 || /\s/.test(url)) {
@@ -381,12 +395,16 @@
381395
if (!isIP(host) && !isFDQN(host, options) && (!ipv6 || !isIP(ipv6, 6)) && host !== 'localhost') {
382396
return false;
383397
}
384-
if (options.host_whitelist && options.host_whitelist.indexOf(host) === -1) {
398+
399+
host = host || ipv6;
400+
401+
if (options.host_whitelist && !checkHost(host, options.host_whitelist)) {
385402
return false;
386403
}
387-
if (options.host_blacklist && options.host_blacklist.indexOf(host) !== -1) {
404+
if (options.host_blacklist && checkHost(host, options.host_blacklist)) {
388405
return false;
389406
}
407+
390408
return true;
391409
}
392410

0 commit comments

Comments
 (0)