node/test/parallel/test-dns.js
cjihrig b176d30a69 dns: handle array holes in setServers()
This commit adds better handling of exceptional array formats
passed to dns.setServers(). Prior to this commit, the input
array was validated using map(), which preserves holes, allowing
them to be passed to c-ares, crashing Node. This commit replaces
map() with forEach(), which skips holes.

Fixes: https://github.com/nodejs/node/issues/8538
PR-URL: https://github.com/nodejs/node/pull/8567
Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2016-09-20 19:56:13 -04:00

211 lines
4.8 KiB
JavaScript

'use strict';
require('../common');
const assert = require('assert');
const dns = require('dns');
var existing = dns.getServers();
assert(existing.length);
// Verify that setServers() handles arrays with holes and other oddities
assert.doesNotThrow(() => {
const servers = [];
servers[0] = '127.0.0.1';
servers[2] = '0.0.0.0';
dns.setServers(servers);
});
assert.doesNotThrow(() => {
const servers = ['127.0.0.1', '192.168.1.1'];
servers[3] = '127.1.0.1';
servers[4] = '127.1.0.1';
servers[5] = '127.1.1.1';
Object.defineProperty(servers, 2, {
enumerable: true,
get: () => {
servers.length = 3;
return '0.0.0.0';
}
});
dns.setServers(servers);
});
function noop() {}
var goog = [
'8.8.8.8',
'8.8.4.4',
];
assert.doesNotThrow(function() { dns.setServers(goog); });
assert.deepStrictEqual(dns.getServers(), goog);
assert.throws(function() { dns.setServers(['foobar']); });
assert.deepStrictEqual(dns.getServers(), goog);
var goog6 = [
'2001:4860:4860::8888',
'2001:4860:4860::8844',
];
assert.doesNotThrow(function() { dns.setServers(goog6); });
assert.deepStrictEqual(dns.getServers(), goog6);
goog6.push('4.4.4.4');
dns.setServers(goog6);
assert.deepStrictEqual(dns.getServers(), goog6);
var ports = [
'4.4.4.4:53',
'[2001:4860:4860::8888]:53',
];
var portsExpected = [
'4.4.4.4',
'2001:4860:4860::8888',
];
dns.setServers(ports);
assert.deepStrictEqual(dns.getServers(), portsExpected);
assert.doesNotThrow(function() { dns.setServers([]); });
assert.deepStrictEqual(dns.getServers(), []);
assert.throws(function() {
dns.resolve('test.com', [], noop);
}, function(err) {
return !(err instanceof TypeError);
}, 'Unexpected error');
// dns.lookup should accept falsey and string values
assert.throws(function() {
dns.lookup({}, noop);
}, 'invalid arguments: hostname must be a string or falsey');
assert.throws(function() {
dns.lookup([], noop);
}, 'invalid arguments: hostname must be a string or falsey');
assert.throws(function() {
dns.lookup(true, noop);
}, 'invalid arguments: hostname must be a string or falsey');
assert.throws(function() {
dns.lookup(1, noop);
}, 'invalid arguments: hostname must be a string or falsey');
assert.throws(function() {
dns.lookup(noop, noop);
}, 'invalid arguments: hostname must be a string or falsey');
assert.doesNotThrow(function() {
dns.lookup('', noop);
});
assert.doesNotThrow(function() {
dns.lookup(null, noop);
});
assert.doesNotThrow(function() {
dns.lookup(undefined, noop);
});
assert.doesNotThrow(function() {
dns.lookup(0, noop);
});
assert.doesNotThrow(function() {
dns.lookup(NaN, noop);
});
/*
* Make sure that dns.lookup throws if hints does not represent a valid flag.
* (dns.V4MAPPED | dns.ADDRCONFIG) + 1 is invalid because:
* - it's different from dns.V4MAPPED and dns.ADDRCONFIG.
* - it's different from them bitwise ored.
* - it's different from 0.
* - it's an odd number different than 1, and thus is invalid, because
* flags are either === 1 or even.
*/
assert.throws(function() {
dns.lookup('www.google.com', { hints: (dns.V4MAPPED | dns.ADDRCONFIG) + 1 },
noop);
});
assert.throws(function() {
dns.lookup('www.google.com');
}, 'invalid arguments: callback must be passed');
assert.throws(function() {
dns.lookup('www.google.com', 4);
}, 'invalid arguments: callback must be passed');
assert.doesNotThrow(function() {
dns.lookup('www.google.com', 6, noop);
});
assert.doesNotThrow(function() {
dns.lookup('www.google.com', {}, noop);
});
assert.doesNotThrow(function() {
dns.lookup('', {
family: 4,
hints: 0
}, noop);
});
assert.doesNotThrow(function() {
dns.lookup('', {
family: 6,
hints: dns.ADDRCONFIG
}, noop);
});
assert.doesNotThrow(function() {
dns.lookup('', {
hints: dns.V4MAPPED
}, noop);
});
assert.doesNotThrow(function() {
dns.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED
}, noop);
});
assert.throws(function() {
dns.lookupService('0.0.0.0');
}, /Invalid arguments/);
assert.throws(function() {
dns.lookupService('fasdfdsaf', 0, noop);
}, /"host" argument needs to be a valid IP address/);
assert.doesNotThrow(function() {
dns.lookupService('0.0.0.0', '0', noop);
});
assert.doesNotThrow(function() {
dns.lookupService('0.0.0.0', 0, noop);
});
assert.throws(function() {
dns.lookupService('0.0.0.0', null, noop);
}, /"port" should be >= 0 and < 65536, got "null"/);
assert.throws(function() {
dns.lookupService('0.0.0.0', undefined, noop);
}, /"port" should be >= 0 and < 65536, got "undefined"/);
assert.throws(function() {
dns.lookupService('0.0.0.0', 65538, noop);
}, /"port" should be >= 0 and < 65536, got "65538"/);
assert.throws(function() {
dns.lookupService('0.0.0.0', 'test', noop);
}, /"port" should be >= 0 and < 65536, got "test"/);
assert.throws(() => {
dns.lookupService('0.0.0.0', 80, null);
}, /^TypeError: "callback" argument must be a function$/);