From 4e8c03707ab904308a2c59a9577bc764573e3b78 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 16 Sep 2016 14:08:56 -0400 Subject: [PATCH] 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 Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- lib/dns.js | 9 +++++---- test/parallel/test-dns.js | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/lib/dns.js b/lib/dns.js index 7c76aebb97..55351bb774 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -286,25 +286,26 @@ exports.setServers = function(servers) { // cache the original servers because in the event of an error setting the // servers cares won't have any servers available for resolution const orig = cares.getServers(); + const newSet = []; - const newSet = servers.map((serv) => { + servers.forEach((serv) => { var ipVersion = isIP(serv); if (ipVersion !== 0) - return [ipVersion, serv]; + return newSet.push([ipVersion, serv]); const match = serv.match(/\[(.*)\](:\d+)?/); // we have an IPv6 in brackets if (match) { ipVersion = isIP(match[1]); if (ipVersion !== 0) - return [ipVersion, match[1]]; + return newSet.push([ipVersion, match[1]]); } const s = serv.split(/:\d+$/)[0]; ipVersion = isIP(s); if (ipVersion !== 0) - return [ipVersion, s]; + return newSet.push([ipVersion, s]); throw new Error(`IP address is not properly formatted: ${serv}`); }); diff --git a/test/parallel/test-dns.js b/test/parallel/test-dns.js index 6a73371b02..cf3b76c71e 100644 --- a/test/parallel/test-dns.js +++ b/test/parallel/test-dns.js @@ -7,6 +7,33 @@ 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 = [