Compare commits

...

1 Commits

Author SHA1 Message Date
Claude
c13b0d9ce1 Fix null pointer crash in Listener.getsockname() when called without arguments
When `getsockname()` was called without an out-object argument (e.g.
`Bun.listen(...).getsockname()`), the first argument defaulted to
`undefined`. This was then passed to `JSC__JSValue__putBunString` in
C++, where `getObject()` returned null, causing a null pointer
dereference in `putDirect`.

Fix: when no object argument is provided, create a new empty object to
populate and return it. When an out-object is provided, preserve the
existing behavior of populating it in-place and returning undefined.

https://claude.ai/code/session_01PxYrYFseM3UutPg2C5AKM8
2026-02-20 22:28:16 +00:00
2 changed files with 44 additions and 2 deletions

View File

@@ -850,7 +850,9 @@ pub fn getsockname(this: *Listener, globalThis: *jsc.JSGlobalObject, callFrame:
return .js_undefined;
}
const out = callFrame.argumentsAsArray(1)[0];
const arg = callFrame.argumentsAsArray(1)[0];
const has_out = arg.isObject();
const out = if (has_out) arg else JSValue.createEmptyObject(globalThis, 3);
const socket = this.listener.uws;
var buf: [64]u8 = [_]u8{0} ** 64;
@@ -872,7 +874,7 @@ pub fn getsockname(this: *Listener, globalThis: *jsc.JSGlobalObject, callFrame:
out.put(globalThis, bun.String.static("family"), family_js);
out.put(globalThis, bun.String.static("address"), address_js);
out.put(globalThis, bun.String.static("port"), port_js);
return .js_undefined;
return if (has_out) .js_undefined else out;
}
pub fn jsAddServerName(global: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!JSValue {

View File

@@ -57,6 +57,46 @@ it("remoteAddress works", async () => {
await prom;
});
it("getsockname without arguments should not crash", () => {
using server = Bun.listen({
socket: {
open() {},
close() {},
data() {},
},
port: 0,
hostname: "127.0.0.1",
});
const result = server.getsockname();
expect(result).toEqual({
family: "IPv4",
address: "127.0.0.1",
port: server.port,
});
});
it("getsockname with an out object populates it", () => {
using server = Bun.listen({
socket: {
open() {},
close() {},
data() {},
},
port: 0,
hostname: "127.0.0.1",
});
const out: Record<string, unknown> = {};
const result = server.getsockname(out);
expect(result).toBeUndefined();
expect(out).toEqual({
family: "IPv4",
address: "127.0.0.1",
port: server.port,
});
});
it("should not allow invalid tls option", () => {
[1, "string", Symbol("symbol")].forEach(value => {
expect(() => {