From fee28ca66fe732596fb8525218ddffee819a0190 Mon Sep 17 00:00:00 2001 From: robobun Date: Wed, 24 Sep 2025 18:29:15 -0700 Subject: [PATCH] Fix dns.resolve callback parameters to match Node.js behavior (#22814) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Fixed `dns.resolve()` callback to pass 2 parameters instead of 3, matching Node.js - Fixed `dns.promises.resolve()` to return array of strings for A/AAAA records instead of objects - Added comprehensive regression tests ## What was wrong? The `dns.resolve()` callback was incorrectly passing 3 parameters `(error, hostname, results)` instead of Node.js's 2 parameters `(error, results)`. Additionally, `dns.promises.resolve()` was returning objects with `{address, family}` instead of plain string arrays for A/AAAA records. ## How this fixes it 1. Removed the extra `hostname` parameter from the callback in `dns.resolve()` for A/AAAA records 2. Changed promise version to use `promisifyResolveX(false)` instead of `promisifyLookup()` to return string arrays 3. Applied same fixes to the `Resolver` class methods ## Test plan - Added regression test `test/regression/issue/22712.test.ts` with 6 test cases - All tests pass with the fix - Verified existing DNS tests still pass Fixes #22712 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude Bot Co-authored-by: Claude Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/js/node/dns.ts | 6 ++-- test/regression/issue/22712.test.ts | 52 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 test/regression/issue/22712.test.ts diff --git a/src/js/node/dns.ts b/src/js/node/dns.ts index fff39fc352..c6640b6cba 100644 --- a/src/js/node/dns.ts +++ b/src/js/node/dns.ts @@ -407,7 +407,7 @@ var InternalResolver = class Resolver { switch (rrtype?.toLowerCase()) { case "a": case "aaaa": - callback(null, hostname, results.map(mapResolveX)); + callback(null, results.map(mapResolveX)); break; default: callback(null, results); @@ -792,7 +792,7 @@ const promises = { switch (rrtype?.toLowerCase()) { case "a": case "aaaa": - return translateErrorCode(dns.resolve(hostname, rrtype).then(promisifyLookup(defaultResultOrder()))); + return translateErrorCode(dns.resolve(hostname, rrtype).then(promisifyResolveX(false))); default: return translateErrorCode(dns.resolve(hostname, rrtype)); } @@ -870,7 +870,7 @@ const promises = { case "a": case "aaaa": return translateErrorCode( - Resolver.#getResolver(this).resolve(hostname, rrtype).then(promisifyLookup(defaultResultOrder())), + Resolver.#getResolver(this).resolve(hostname, rrtype).then(promisifyResolveX(false)), ); default: return translateErrorCode(Resolver.#getResolver(this).resolve(hostname, rrtype)); diff --git a/test/regression/issue/22712.test.ts b/test/regression/issue/22712.test.ts new file mode 100644 index 0000000000..695b35b952 --- /dev/null +++ b/test/regression/issue/22712.test.ts @@ -0,0 +1,52 @@ +import { expect, test } from "bun:test"; +import dns from "node:dns"; + +test("dns.resolve callback parameters match Node.js", done => { + dns.resolve("dns.google", (...args) => { + // Should receive exactly 2 parameters: error and addresses array + expect(args.length).toBe(2); + expect(args[0]).toBe(null); // no error + expect(Array.isArray(args[1])).toBe(true); // addresses should be array + expect(args[1].every((addr: any) => typeof addr === "string")).toBe(true); // each address should be string + done(); + }); +}); + +test("dns.resolve with A record type callback parameters", done => { + dns.resolve("dns.google", "A", (...args) => { + expect(args.length).toBe(2); + expect(args[0]).toBe(null); + expect(Array.isArray(args[1])).toBe(true); + expect(args[1].every((addr: any) => typeof addr === "string")).toBe(true); + done(); + }); +}); + +test("dns.resolve with AAAA record type callback parameters", done => { + // Use a hostname that has AAAA records + dns.resolve("google.com", "AAAA", (...args) => { + expect(args.length).toBe(2); + expect(args[0]).toBe(null); + expect(Array.isArray(args[1])).toBe(true); + expect(args[1].every((addr: any) => typeof addr === "string")).toBe(true); + done(); + }); +}); + +test("dns.promises.resolve returns array of strings", async () => { + const result = await dns.promises.resolve("dns.google"); + expect(Array.isArray(result)).toBe(true); + expect(result.every((addr: any) => typeof addr === "string")).toBe(true); +}); + +test("dns.promises.resolve with A record returns array of strings", async () => { + const result = await dns.promises.resolve("dns.google", "A"); + expect(Array.isArray(result)).toBe(true); + expect(result.every((addr: any) => typeof addr === "string")).toBe(true); +}); + +test("dns.promises.resolve with AAAA record returns array of strings", async () => { + const result = await dns.promises.resolve("google.com", "AAAA"); + expect(Array.isArray(result)).toBe(true); + expect(result.every((addr: any) => typeof addr === "string")).toBe(true); +});