Skip to content

Fix assertion failure in Bun.dns.setServers with non-int32 values - #28926

Merged
Jarred-Sumner merged 2 commits into
mainfrom
farm/0ca59360/dns-setservers-int32-assert
Apr 8, 2026
Merged

Jarred-Sumner merged 2 commits into
mainfrom
farm/0ca59360/dns-setservers-int32-assert

Conversation

@robobun

@robobun robobun commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator

Bun.dns.setServers called toInt32() on the family and port elements of each server triple. The internal toInt32() helper falls through to JSC__JSValue__toInt32, which calls JSValue::asInt32() and asserts isInt32(). Passing a double (e.g. -9007199254740991) or leaving the port out (so the index returns undefined) tripped the assertion:

ASSERTION FAILED: isInt32()
JavaScriptCore/JSCJSValue.h(994) : int32_t JSC::JSValue::asInt32() const

Repro:

Bun.dns.setServers([[-9007199254740991, 15473]]);

Switch to coerceToInt32, which uses JSC's full numeric coercion. The existing family != 4 and family != 6 check still rejects invalid families with a proper TypeError.

Found by Fuzzilli.

@github-actions github-actions Bot added the claude label Apr 6, 2026
@robobun

robobun commented Apr 6, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 3:35 PM PT - Apr 6th, 2026

❌ @robobun, your commit a3b774b has 4 failures in Build #44071 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 28926

That installs a local version of the PR into your bun-28926 executable, so you can run:

bun-28926 --bun

@coderabbitai

coderabbitai Bot commented Apr 6, 2026 •

Copy link
Copy Markdown
Contributor

Walkthrough

Replaces direct integer conversion with coerceToInt32(globalThis) when parsing DNS server triple fields and adds tests validating sync throwing behavior for invalid or missing triple elements and a passing triple case.

Changes

Cohort / File(s) Summary
DNS Server Parsing
src/bun.js/api/bun/dns.zig
In Resolver.setChannelServers, changed parsing of family and port from toInt32() to coerceToInt32(globalThis), preserving family validation (only 4 or 6) and now propagating coercion errors.
DNS Server Parsing Tests
test/js/bun/dns/resolve-dns.test.ts
Added describe("setServers") tests (4 cases) asserting synchronous TypeError for non-int32 family, no throw when port is undefined, TypeError when family is undefined, and acceptance of a valid triple.
🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description provides clear explanation of the problem, reproduction steps, and the solution, but does not follow the required template structure with 'What does this PR do?' and 'How did you verify your code works?' sections. Restructure the description to follow the template: add explicit 'What does this PR do?' and 'How did you verify your code works?' sections with the existing content organized under these headings.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: fixing an assertion failure in Bun.dns.setServers when non-int32 values are passed, which is the core issue addressed in the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/js/bun/dns/resolve-dns.test.ts`:
- Around line 126-140: Update the two tests that expect throws to assert
TypeError specifically: in the tests "triple with non-int32 family (double)
should not crash" and "triple with missing family (undefined) should not crash",
replace the generic expect(...).toThrow() with expect(...).toThrow(TypeError)
when invoking dns.setServers, and consider renaming the "missing family" test
title to reflect that it should throw a TypeError; keep the "missing port" test
unchanged (dns.setServers referenced in all three tests).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b5faadcd-5331-478c-ab8d-a83f6ce6d4d3

📥 Commits

Reviewing files that changed from the base of the PR and between f4258a4 and 39aa993.

📒 Files selected for processing (2)
  • src/bun.js/api/bun/dns.zig
  • test/js/bun/dns/resolve-dns.test.ts

Comment thread test/js/bun/dns/resolve-dns.test.ts Outdated

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — minimal, correct fix for the Fuzzilli-found assertion crash.

Extended reasoning...

Overview\nThis PR modifies two files: (2 lines changed) and (22 lines added). The fix replaces with for reading the and fields out of each DNS server triple, preventing an assertion crash when non-int32 JS values (doubles, undefined) are passed.\n\n### Security risks\nNone. The change narrows the crash surface and does not affect any auth, permission, or data exposure path. Invalid families still get rejected with a TypeError.\n\n### Level of scrutiny\nLow. This is a two-line targeted fix in a DNS utility function, found by Fuzzilli and directly addressing the described assertion failure. The existing guard remains unchanged and still enforces valid input. The tests clearly exercise the repro case and the surrounding edge cases.\n\n### Other factors\nTwo nit-level issues were flagged: (1) test global state is mutated without cleanup — low practical risk since test files run in isolated processes and the mutating tests are last in the file; (2) port is coerced before family is validated, meaning a doubly-invalid call (bad family + throwing port) gets the wrong error — this requires two simultaneous bad inputs and the call still fails either way. Neither issue affects correctness of the crash fix. The PR is narrow, well-tested, and follows established patterns.

Comment on lines +132 to +145
// undefined port coerces to 0, which is a valid int32
// @ts-expect-error
expect(() => dns.setServers([[4, "8.8.8.8"]])).not.toThrow();
});

test("triple with missing family (undefined) throws TypeError", () => {
// @ts-expect-error
expect(() => dns.setServers([["8.8.8.8"]])).toThrow(TypeError);
});

test("valid triple should succeed", () => {
expect(() => dns.setServers([[4, "8.8.8.8", 53]])).not.toThrow();
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Two tests in the new setServers describe block call dns.setServers() successfully and permanently mutate global DNS resolver state without any cleanup. A simple beforeAll/afterAll to save and restore the original servers would prevent future tests added after this block from silently using 8.8.8.8 instead of the system resolver.

Extended reasoning...

What the bug is and how it manifests

Two tests in the setServers describe block actually change the global DNS resolver configuration without restoring it:

  • 'triple with missing port (undefined) should not crash' calls dns.setServers([[4, '8.8.8.8']]) — sets the resolver to 8.8.8.8 with port 0
  • 'valid triple should succeed' calls dns.setServers([[4, '8.8.8.8', 53]]) — sets the resolver to 8.8.8.8:53

Neither test restores the original servers, and there is no afterAll/afterEach hook in the setServers describe block.

The specific code path that triggers it

At test/js/bun/dns/resolve-dns.test.ts lines 134–135 and 143, the calls to dns.setServers() succeed (the tests assert .not.toThrow()), which internally calls the Zig setServers function that writes to the global Resolver singleton. There is no corresponding call to restore the original state.

Why existing code doesn't prevent it

dns.getServers() exists (dns.zig:3198) and could be used to capture the original state before the block runs. The test file simply does not use it. The two tests that call setServers without throwing were designed to verify the crash fix, but the side effect on global state was not addressed.

What the impact would be

Currently the impact is minimal: Bun's test runner isolates each test file in its own process, and the setServers describe block is placed last in the file — after all the DNS lookup tests. So neither cross-file contamination nor within-file contamination occurs today.

However, any test added after line 144 (or inside the setServers describe block after the mutating tests) would silently use 8.8.8.8 as the DNS resolver instead of the system resolver, potentially causing flaky or incorrect results in environments where 8.8.8.8 is unreachable or returns different answers.

How to fix it

Add a beforeAll/afterAll pair inside the setServers describe block:

describe('setServers', () => {
  let originalServers: string[];
  beforeAll(() => { originalServers = dns.getServers(); });
  afterAll(() => { dns.setServers(originalServers); });
  // ... tests ...
});

Step-by-step proof

  1. Test runner starts the file in a fresh process; system DNS resolver is active (e.g. 192.168.1.1).
  2. All lookup() tests (lines 12–123) run successfully against the system resolver.
  3. 'triple with missing port' runs — dns.setServers([[4, '8.8.8.8']]) succeeds; global resolver is now 8.8.8.8:0.
  4. 'valid triple should succeed' runs — dns.setServers([[4, '8.8.8.8', 53]]) succeeds; global resolver is now 8.8.8.8:53.
  5. No cleanup runs. If a developer later adds a test('resolves example.com') after line 144, it will query 8.8.8.8 instead of the system resolver, with no indication in the test output of why.

Comment on lines +3293 to 3297
const family = try (try triple.getIndex(globalThis, 0)).coerceToInt32(globalThis);
const port = try (try triple.getIndex(globalThis, 2)).coerceToInt32(globalThis);

if (family != 4 and family != 6) {
return globalThis.throwInvalidArguments("Invalid address family", .{});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Port is coerced at line 3294 before family is validated at lines 3296–3298; if an invalid family is passed alongside a port value that throws during coerceToInt32 (e.g., a BigInt like 53n or an object with a throwing valueOf), the port exception fires instead of the expected 'Invalid address family' TypeError. The fix is to validate family immediately after coercing it, before touching the port. Separately (pre-existing, unrelated to this PR): no port range check exists, so values like -1 or 70000 silently reach c-ares and get cast to uint16_t.

Extended reasoning...

Ordering issue (new, nit)

The PR changed both family and port from toInt32() to coerceToInt32(). The key difference is that coerceToInt32 can propagate JavaScript exceptions (e.g., if the value is a BigInt or an object whose valueOf getter throws), whereas the old toInt32() only worked on values already confirmed to be isInt32.

In the updated code, the reads are:

const family = try (try triple.getIndex(globalThis, 0)).coerceToInt32(globalThis); // line 3293
const port   = try (try triple.getIndex(globalThis, 2)).coerceToInt32(globalThis); // line 3294  ← port coerced HERE
// ... then:
if (family != 4 and family != 6) {                                                 // line 3296
    return globalThis.throwInvalidArguments("Invalid address family", .{});        // line 3297
}

Step-by-step proof of incorrect error:

  1. Caller invokes dns.setServers([[999, 'addr', 53n]]) — family 999 is invalid, port is a BigInt.
  2. Line 3293 coerces family 999 → 999 (succeeds, no exception).
  3. Line 3294 coerces port 53n (BigInt) → coerceToInt32 throws a TypeError: Cannot convert a BigInt value to a number.
  4. The error propagates; lines 3296-3298 are never reached.
  5. The caller receives a BigInt coercion error instead of 'Invalid address family'.

Why existing code doesn't prevent it: Before the PR, toInt32() would assert/crash on non-int32 port values, so the ordering was irrelevant—both invalid inputs caused an abort. Now that coerceToInt32 can throw cleanly, the ordering matters for which error the caller sees.

Impact: Low. Requires two simultaneous invalid inputs (bad family + exotic port), and the call still fails with an error either way. Normal usage (integer ports) is unaffected. This is a nit-level ordering issue.

Fix: Move the family validation block to immediately after line 3293 (family coercion), before port coercion:

const family = try (try triple.getIndex(globalThis, 0)).coerceToInt32(globalThis);
if (family != 4 and family != 6) {
    return globalThis.throwInvalidArguments("Invalid address family", .{});
}
const port = try (try triple.getIndex(globalThis, 2)).coerceToInt32(globalThis);

Addressing the refutation

One verifier noted the scenario is contrived (bad family + throwing port simultaneously). This is correct and is why the severity is nit rather than normal. In all realistic DNS configuration, port is a plain integer. However, the ordering issue is now externally observable (the old crash is gone), so it's worth a one-line fix.

Port range validation (pre-existing, unrelated)

The struct fields udp_port/tcp_port in struct_ares_addr_port_node are c_int, so values like -1 or 70000 pass through to c-ares without validation. c-ares then casts them to uint16_t internally, silently wrapping -1 to 65535. This lack of range validation existed before this PR (the old toInt32() also had no range check). The PR's change from toInt32() to coerceToInt32() marginally expands the set of values that reach this path (e.g., large doubles now coerce instead of crashing), but the root issue is pre-existing. Port range validation (0 <= port <= 65535) would be a separate improvement.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/js/bun/dns/resolve-dns.test.ts`:
- Around line 131-135: Rename the test title to accurately reflect the assertion
behavior and avoid misleading wording: change the test description for the case
that calls dns.setServers([[4, "8.8.8.8"]]) from "triple with missing port
(undefined) should not crash" to "triple with missing port (undefined) should
not throw"; keep the existing assertion (.not.toThrow()) and the test body using
dns.setServers, and if port-range validation is desired later, open a follow-up
to add explicit checks (e.g., reject port 0) in the DNS parsing code rather than
modifying this test now.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3f51b4bd-af84-495e-a06d-e93affe81b95

📥 Commits

Reviewing files that changed from the base of the PR and between 39aa993 and a3b774b.

📒 Files selected for processing (1)
  • test/js/bun/dns/resolve-dns.test.ts

Comment on lines +131 to +135
test("triple with missing port (undefined) should not crash", () => {
// undefined port coerces to 0, which is a valid int32
// @ts-expect-error
expect(() => dns.setServers([[4, "8.8.8.8"]])).not.toThrow();
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Test title and validation gap: distinguish "crash" from "throw" and consider port validation.

Two concerns:

  1. Minor: Title inconsistency. The test title says "should not crash" but the assertion is .not.toThrow(). A crash (assertion failure/process abort) is different from a controlled exception. Consider renaming to "triple with missing port (undefined) should not throw" or similar to match the assertion.

  2. Major: Port 0 is silently accepted. The comment notes that undefined coerces to 0, which is a valid int32—but port 0 is not a valid DNS server port. From the context snippets in dns.zig, the coerced port value is stored directly in udp_port/tcp_port without range validation, unlike family which has explicit 4/6 checks. This test correctly documents current behavior, but that behavior itself is questionable: accepting port 0 could lead to runtime issues downstream.

Suggested fix for title
-    test("triple with missing port (undefined) should not crash", () => {
+    test("triple with missing port (undefined) should not throw", () => {

Note: The PR scope is fixing the assertion crash, not adding port validation. If port validation is intended, consider opening a follow-up issue to validate port ranges (e.g., 1-65535) and reject port 0.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/js/bun/dns/resolve-dns.test.ts` around lines 131 - 135, Rename the test
title to accurately reflect the assertion behavior and avoid misleading wording:
change the test description for the case that calls dns.setServers([[4,
"8.8.8.8"]]) from "triple with missing port (undefined) should not crash" to
"triple with missing port (undefined) should not throw"; keep the existing
assertion (.not.toThrow()) and the test body using dns.setServers, and if
port-range validation is desired later, open a follow-up to add explicit checks
(e.g., reject port 0) in the DNS parsing code rather than modifying this test
now.

Comment on lines +142 to +144
test("valid triple should succeed", () => {
expect(() => dns.setServers([[4, "8.8.8.8", 53]])).not.toThrow();
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The 'valid triple should succeed' test at line 143 calls dns.setServers([[4, "8.8.8.8", 53]]) without a // @ts-expect-error directive, but setServers is not declared in the Bun DNS namespace TypeScript types. The other three tests in the same describe("setServers") block all have // @ts-expect-error, making this test inconsistent and causing tsc --noEmit to fail with TS2339. Add // @ts-expect-error on the line immediately before the expect(...) call to match the surrounding pattern.

Extended reasoning...

What the bug is

The test at line 143 calls dns.setServers([[4, "8.8.8.8", 53]]) directly, but setServers is absent from the Bun DNS namespace TypeScript types (packages/bun-types/bun.d.ts only declares lookup, prefetch, getCacheStats, and the ADDRCONFIG/ALL/V4MAPPED constants). TypeScript resolves dns as typeof Bun.dns, which does not include setServers, so the call produces TS2339: Property 'setServers' does not exist on type 'typeof dns'.

The specific code path that triggers it

The test file imports { dns } from "bun" and the test tsconfig.json uses "types": ["../packages/bun-types"]. When tsc --noEmit is run on the test suite (via the typecheck script in both root and test/package.json), the compiler resolves dns against the bun-types declarations. Because setServers has no declaration there, line 143 is flagged as a type error.

Why existing code doesn't prevent it

The three other tests in the same block — for the non-int32 family, the missing port, and the missing family cases — all correctly suppress the error with // @ts-expect-error. The fourth test, added to verify that a valid triple succeeds, was simply written without the directive. There is no lint rule or other mechanism that would automatically enforce the directive's presence.

What the impact would be

Running bun run typecheck (or tsc --noEmit) on the test directory will exit with a non-zero status, failing any CI job that performs a type-check pass. Runtime test execution is unaffected because Bun strips types without checking them.

How to fix it

Add // @ts-expect-error on the line immediately before expect(() => dns.setServers(...)) in the 'valid triple should succeed' test, exactly as done in the three preceding tests.

Step-by-step proof

  1. dns is typed as typeof Bun.dns from packages/bun-types/bun.d.ts.
  2. bun.d.ts namespace dns declares only lookup, prefetch, getCacheStats, and the flag constants — no setServers.
  3. tsc sees dns.setServers(...) at line 143 and emits: error TS2339: Property 'setServers' does not exist on type 'typeof dns'.
  4. The three tests at lines 127, 133, 138 each have // @ts-expect-error directly above the dns.setServers call, suppressing TS2339 for those lines.
  5. Line 143 has no such directive, so the type error is unhandled and tsc --noEmit fails.

Comment on lines +137 to +140
test("triple with missing family (undefined) throws TypeError", () => {
// @ts-expect-error
expect(() => dns.setServers([["8.8.8.8"]])).toThrow(TypeError);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The test named "triple with missing family (undefined) throws TypeError" (line 137) is misnamed: the triple passed is ["8.8.8.8"], so index 0 (the family slot) holds the string "8.8.8.8", not undefined. The test exercises the "string in family position" path, not the "missing/undefined family" path. Rename the test and/or add a separate test with [[undefined, "8.8.8.8", 53]] to actually cover the undefined-family case.

Extended reasoning...

The test at line 137 is:

test("triple with missing family (undefined) throws TypeError", () => {
  // @ts-expect-error
  expect(() => dns.setServers([["8.8.8.8"]])).toThrow(TypeError);
});

What the bug is. The triple format for setServers is [family, address, port]. The call dns.setServers([["8.8.8.8"]]) creates the array ["8.8.8.8"]. At index 0 (the family slot), getIndex returns the string "8.8.8.8" — not undefined and not missing. The test name incorrectly claims the family is "missing (undefined)".

The specific code path that triggers it. coerceToInt32("8.8.8.8") converts the string through JS ToNumber("8.8.8.8") → NaN, then NaN|0 → 0. The family value 0 is then rejected by the family != 4 and family != 6 check in dns.zig, throwing TypeError: Invalid address family. So the test passes — but for the wrong documented reason.

Why the name matters. A developer reading the test suite would conclude that the "undefined family" edge case is covered. It is not. A truly missing/undefined family would require a triple like [[undefined, "8.8.8.8", 53]] — where index 0 is explicitly undefined. That case goes through coerceToInt32(undefined) → ToNumber(undefined) → NaN → 0, which is also rejected. The behavior is the same, but the test does not prove that path is exercised.

What the impact would be. The test gives a false sense of coverage. If a future refactor handled undefined specially (e.g., returning an early error before the int32 coercion), the "string in family" path would still pass but the "undefined family" path would have no coverage, and no one would notice because the test name implies it is covered.

How to fix it. Rename the test to something like "triple with string in family slot throws TypeError" to accurately describe what is being tested. Optionally add a separate test with [[undefined, "8.8.8.8", 53]] to genuinely cover the undefined-family path.

Step-by-step proof:

  1. dns.setServers([["8.8.8.8"]]) is called.
  2. The outer array has one element: ["8.8.8.8"] — this is triple.
  3. triple.getIndex(globalThis, 0) returns the string "8.8.8.8".
  4. coerceToInt32("8.8.8.8") → NaN|0 → 0.
  5. family = 0, which is neither 4 nor 6 → throwInvalidArguments("Invalid address family").
  6. The test passes, but triple[0] was "8.8.8.8", not undefined. The test name is factually wrong.

@robobun

robobun commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator Author

CI failures are unrelated flakes on linux-x64-asan:

  • test/js/third_party/@azure/service-bus/azure-service-bus.test.ts — JSC pushInline/getIfPropertyExists exception-check validation assert
  • test/regression/issue/26225.test.ts — ThreadLock assertion (node-fetch + form-data stream)

Neither test touches Bun.dns, setServers, or int32 coercion. The DNS test file passes locally (71/71). Needs a retry.

@robobun

robobun commented Apr 6, 2026

Copy link
Copy Markdown
Collaborator Author

All 4 CI failures are pre-existing flakes. Same pattern (azure-service-bus + webview + webview-chrome) appears on unrelated builds 44070, 44067, 44064. None touch DNS. Needs a retry, no code change on my end.

@Jarred-Sumner
Jarred-Sumner merged commit fd75aa4 into main Apr 8, 2026
59 of 64 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the farm/0ca59360/dns-setservers-int32-assert branch April 8, 2026 22:42
structwafel pushed a commit to structwafel/bun that referenced this pull request Apr 25, 2026
…en-sh#28926)

`Bun.dns.setServers` called `toInt32()` on the family and port elements
of each server triple. The internal `toInt32()` helper falls through to
`JSC__JSValue__toInt32`, which calls `JSValue::asInt32()` and asserts
`isInt32()`. Passing a double (e.g. `-9007199254740991`) or leaving the
port out (so the index returns `undefined`) tripped the assertion:

```
ASSERTION FAILED: isInt32()
JavaScriptCore/JSCJSValue.h(994) : int32_t JSC::JSValue::asInt32() const
```

Repro:

```js
Bun.dns.setServers([[-9007199254740991, 15473]]);
```

Switch to `coerceToInt32`, which uses JSC's full numeric coercion. The
existing `family != 4 and family != 6` check still rejects invalid
families with a proper `TypeError`.

Found by Fuzzilli.
xhjkl pushed a commit to xhjkl/bun that referenced this pull request May 14, 2026
…en-sh#28926)

`Bun.dns.setServers` called `toInt32()` on the family and port elements
of each server triple. The internal `toInt32()` helper falls through to
`JSC__JSValue__toInt32`, which calls `JSValue::asInt32()` and asserts
`isInt32()`. Passing a double (e.g. `-9007199254740991`) or leaving the
port out (so the index returns `undefined`) tripped the assertion:

```
ASSERTION FAILED: isInt32()
JavaScriptCore/JSCJSValue.h(994) : int32_t JSC::JSValue::asInt32() const
```

Repro:

```js
Bun.dns.setServers([[-9007199254740991, 15473]]);
```

Switch to `coerceToInt32`, which uses JSC's full numeric coercion. The
existing `family != 4 and family != 6` check still rejects invalid
families with a proper `TypeError`.

Found by Fuzzilli.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants