dns: move falsy hostname in lookup to end-of-life

It's been deprecated for ~7 years. It's time.

PR-URL: https://github.com/nodejs/node/pull/58619
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
This commit is contained in:
James M Snell 2025-06-13 05:47:23 -07:00 committed by GitHub
parent 431c04d0bd
commit a5f9ca1f77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 115 additions and 107 deletions

View File

@ -2524,17 +2524,18 @@ object can lead to crashing the application.
<!-- YAML <!-- YAML
changes: changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/58619
description: End-of-Life.
- version: v11.0.0 - version: v11.0.0
pr-url: https://github.com/nodejs/node/pull/23173 pr-url: https://github.com/nodejs/node/pull/23173
description: Runtime deprecation. description: Runtime deprecation.
--> -->
Type: Runtime Type: End-of-Life
Previous versions of Node.js supported `dns.lookup()` with a falsy host name Previous versions of Node.js supported `dns.lookup()` with a falsy host name
like `dns.lookup(false)` due to backward compatibility. like `dns.lookup(false)` due to backward compatibility. This has been removed.
This behavior is undocumented and is thought to be unused in real world apps.
It will become an error in future versions of Node.js.
### DEP0119: `process.binding('uv').errname()` private API ### DEP0119: `process.binding('uv').errname()` private API

View File

@ -42,7 +42,6 @@ const {
bindDefaultResolver, bindDefaultResolver,
setDefaultResolver, setDefaultResolver,
validateHints, validateHints,
emitInvalidHostnameWarning,
getDefaultResultOrder, getDefaultResultOrder,
setDefaultResultOrder, setDefaultResultOrder,
errorCodes: dnsErrorCodes, errorCodes: dnsErrorCodes,
@ -199,13 +198,8 @@ function lookup(hostname, options, callback) {
} }
if (!hostname) { if (!hostname) {
emitInvalidHostnameWarning(hostname); throw new ERR_INVALID_ARG_VALUE('hostname', hostname,
if (all) { 'must be a non-empty string');
process.nextTick(callback, null, []);
} else {
process.nextTick(callback, null, null, family === 6 ? 6 : 4);
}
return {};
} }
const matchedFamily = isIP(hostname); const matchedFamily = isIP(hostname);

View File

@ -11,7 +11,6 @@ const {
bindDefaultResolver, bindDefaultResolver,
createResolverClass, createResolverClass,
validateHints, validateHints,
emitInvalidHostnameWarning,
errorCodes: dnsErrorCodes, errorCodes: dnsErrorCodes,
getDefaultResultOrder, getDefaultResultOrder,
setDefaultResultOrder, setDefaultResultOrder,
@ -135,8 +134,8 @@ function onlookupall(err, addresses) {
function createLookupPromise(family, hostname, all, hints, dnsOrder) { function createLookupPromise(family, hostname, all, hints, dnsOrder) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!hostname) { if (!hostname) {
emitInvalidHostnameWarning(hostname); reject(new ERR_INVALID_ARG_VALUE('hostname', hostname,
resolve(all ? [] : { address: null, family: family === 6 ? 6 : 4 }); 'must be a non-empty string'));
return; return;
} }

View File

@ -269,19 +269,6 @@ function validateHints(hints) {
} }
} }
let invalidHostnameWarningEmitted = false;
function emitInvalidHostnameWarning(hostname) {
if (!invalidHostnameWarningEmitted) {
process.emitWarning(
`The provided hostname "${hostname}" is not a valid ` +
'hostname, and is supported in the dns module solely for compatibility.',
'DeprecationWarning',
'DEP0118',
);
invalidHostnameWarningEmitted = true;
}
}
function setDefaultResultOrder(value) { function setDefaultResultOrder(value) {
validateOneOf(value, 'dnsOrder', validDnsOrders); validateOneOf(value, 'dnsOrder', validDnsOrders);
dnsOrder = value; dnsOrder = value;
@ -352,7 +339,6 @@ module.exports = {
validateHints, validateHints,
validateTimeout, validateTimeout,
validateTries, validateTries,
emitInvalidHostnameWarning,
getDefaultResultOrder, getDefaultResultOrder,
setDefaultResultOrder, setDefaultResultOrder,
errorCodes, errorCodes,

View File

@ -629,21 +629,6 @@ TEST(function test_lookup_ip_promise(done) {
}); });
TEST(async function test_lookup_null_all(done) {
assert.deepStrictEqual(await dnsPromises.lookup(null, { all: true }), []);
const req = dns.lookup(null, { all: true }, (err, ips) => {
assert.ifError(err);
assert.ok(Array.isArray(ips));
assert.strictEqual(ips.length, 0);
done();
});
checkWrap(req);
});
TEST(async function test_lookup_all_mixed(done) { TEST(async function test_lookup_all_mixed(done) {
function validateResult(result) { function validateResult(result) {
assert.ok(Array.isArray(result)); assert.ok(Array.isArray(result));

View File

@ -29,9 +29,9 @@ const dnsPromises = dns.promises;
(async function() { (async function() {
let res; let res;
res = await dnsPromises.lookup(null); await assert.rejects(dnsPromises.lookup(null), {
assert.strictEqual(res.address, null); code: 'ERR_INVALID_ARG_VALUE',
assert.strictEqual(res.family, 4); });
res = await dnsPromises.lookup('127.0.0.1'); res = await dnsPromises.lookup('127.0.0.1');
assert.strictEqual(res.address, '127.0.0.1'); assert.strictEqual(res.address, '127.0.0.1');
@ -43,10 +43,9 @@ const dnsPromises = dns.promises;
})().then(common.mustCall()); })().then(common.mustCall());
// Try resolution without hostname. // Try resolution without hostname.
dns.lookup(null, common.mustSucceed((result, addressType) => { assert.throws(() => dns.lookup(null, common.mustNotCall()), {
assert.strictEqual(result, null); code: 'ERR_INVALID_ARG_VALUE',
assert.strictEqual(addressType, 4); });
}));
dns.lookup('127.0.0.1', common.mustSucceed((result, addressType) => { dns.lookup('127.0.0.1', common.mustSucceed((result, addressType) => {
assert.strictEqual(result, '127.0.0.1'); assert.strictEqual(result, '127.0.0.1');

View File

@ -29,11 +29,6 @@ common.expectWarning({
'internal/test/binding': [ 'internal/test/binding': [
'These APIs are for internal testing only. Do not use them.', 'These APIs are for internal testing only. Do not use them.',
], ],
// For calling `dns.lookup` with falsy `hostname`.
'DeprecationWarning': {
DEP0118: 'The provided hostname "false" is not a valid ' +
'hostname, and is supported in the dns module solely for compatibility.'
}
}); });
assert.throws(() => { assert.throws(() => {
@ -145,12 +140,13 @@ assert.throws(() => dnsPromises.lookup(false, () => {}),
(async function() { (async function() {
let res; let res;
res = await dnsPromises.lookup(false, { await assert.rejects(dnsPromises.lookup(false, {
hints: 0, hints: 0,
family: 0, family: 0,
all: true all: true
}), {
code: 'ERR_INVALID_ARG_VALUE',
}); });
assert.deepStrictEqual(res, []);
res = await dnsPromises.lookup('127.0.0.1', { res = await dnsPromises.lookup('127.0.0.1', {
hints: 0, hints: 0,
@ -167,14 +163,13 @@ assert.throws(() => dnsPromises.lookup(false, () => {}),
assert.deepStrictEqual(res, { address: '127.0.0.1', family: 4 }); assert.deepStrictEqual(res, { address: '127.0.0.1', family: 4 });
})().then(common.mustCall()); })().then(common.mustCall());
dns.lookup(false, { assert.throws(() => dns.lookup(false, {
hints: 0, hints: 0,
family: 0, family: 0,
all: true all: true
}, common.mustSucceed((result, addressType) => { }, common.mustNotCall()), {
assert.deepStrictEqual(result, []); code: 'ERR_INVALID_ARG_VALUE',
assert.strictEqual(addressType, undefined); });
}));
dns.lookup('127.0.0.1', { dns.lookup('127.0.0.1', {
hints: 0, hints: 0,

View File

@ -193,16 +193,13 @@ assert.deepStrictEqual(dns.getServers(), []);
// dns.lookup should accept falsey values // dns.lookup should accept falsey values
{ {
const checkCallback = (err, address, family) => {
assert.ifError(err);
assert.strictEqual(address, null);
assert.strictEqual(family, 4);
};
['', null, undefined, 0, NaN].forEach(async (value) => { ['', null, undefined, 0, NaN].forEach(async (value) => {
const res = await dnsPromises.lookup(value); await assert.rejects(dnsPromises.lookup(value), {
assert.deepStrictEqual(res, { address: null, family: 4 }); code: 'ERR_INVALID_ARG_VALUE',
dns.lookup(value, common.mustCall(checkCallback)); });
assert.throws(() => dns.lookup(value, common.mustNotCall()), {
code: 'ERR_INVALID_ARG_VALUE',
});
}); });
} }
@ -247,52 +244,104 @@ assert.throws(() => dns.lookup('', {
name: 'TypeError' name: 'TypeError'
}); });
dns.lookup('', { family: 4, hints: 0 }, common.mustCall()); assert.throws(() => {
dns.lookup('', { family: 4, hints: 0 }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
family: 6, family: 6,
hints: dns.ADDRCONFIG hints: dns.ADDRCONFIG
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { hints: dns.V4MAPPED }, common.mustCall()); assert.throws(() => {
dns.lookup('', { hints: dns.V4MAPPED }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED hints: dns.ADDRCONFIG | dns.V4MAPPED
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.ALL hints: dns.ALL
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.V4MAPPED | dns.ALL hints: dns.V4MAPPED | dns.ALL
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL, hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL,
family: 'IPv4' family: 'IPv4'
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
dns.lookup('', { assert.throws(() => {
dns.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL, hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL,
family: 'IPv6' family: 'IPv6'
}, common.mustCall()); }, common.mustNotCall());
}, {
code: 'ERR_INVALID_ARG_VALUE',
});
(async function() { (async function() {
await dnsPromises.lookup('', { family: 4, hints: 0 }); await assert.rejects(dnsPromises.lookup('', { family: 4, hints: 0 }), {
await dnsPromises.lookup('', { family: 6, hints: dns.ADDRCONFIG }); code: 'ERR_INVALID_ARG_VALUE',
await dnsPromises.lookup('', { hints: dns.V4MAPPED }); });
await dnsPromises.lookup('', { hints: dns.ADDRCONFIG | dns.V4MAPPED }); await assert.rejects(dnsPromises.lookup('', { family: 6, hints: dns.ADDRCONFIG }), {
await dnsPromises.lookup('', { hints: dns.ALL }); code: 'ERR_INVALID_ARG_VALUE',
await dnsPromises.lookup('', { hints: dns.V4MAPPED | dns.ALL }); });
await dnsPromises.lookup('', { await assert.rejects(dnsPromises.lookup('', { hints: dns.V4MAPPED }), {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL code: 'ERR_INVALID_ARG_VALUE',
});
await assert.rejects(dnsPromises.lookup('', { hints: dns.ADDRCONFIG | dns.V4MAPPED }), {
code: 'ERR_INVALID_ARG_VALUE',
});
await assert.rejects(dnsPromises.lookup('', { hints: dns.ALL }), {
code: 'ERR_INVALID_ARG_VALUE',
});
await assert.rejects(dnsPromises.lookup('', { hints: dns.V4MAPPED | dns.ALL }), {
code: 'ERR_INVALID_ARG_VALUE',
});
await assert.rejects(dnsPromises.lookup('', {
hints: dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL
}), {
code: 'ERR_INVALID_ARG_VALUE',
});
await assert.rejects(dnsPromises.lookup('', { order: 'verbatim' }), {
code: 'ERR_INVALID_ARG_VALUE',
}); });
await dnsPromises.lookup('', { order: 'verbatim' });
})().then(common.mustCall()); })().then(common.mustCall());
{ {