mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
## Summary - Fix regression where `new Bun.FFI.CString(ptr)` throws "function is not a constructor" - Pass the same function as both call and constructor callbacks for CString ## Root Cause PR #24910 replaced `jsc.createCallback` with `jsc.JSFunction.create` for all FFI functions. However, `JSFunction.create` doesn't allow constructor calls by default (it uses `callHostFunctionAsConstructor` which throws). The old `createCallback` used `JSFFIFunction` which allowed the same function to be called with `new`. ## Fix Pass the same function as both the `implementation` and `constructor` option to `JSFunction.create` for CString specifically. This allows `new CString(ptr)` to work while keeping the refactoring from #24910. Additionally, the `bun:ffi` module now replaces `Bun.FFI.CString` with the proper JS CString class after loading, so users get the full class with `.ptr`, `.byteOffset`, etc. properties. ## Test plan - [x] Added regression test `test/regression/issue/25231.test.ts` - [x] Test fails with `USE_SYSTEM_BUN=1` (v1.3.3), passes with fix - [x] Verified reproduction case from issue works Fixes #25231 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>
33 lines
938 B
TypeScript
33 lines
938 B
TypeScript
// https://github.com/oven-sh/bun/issues/25231
|
|
// Bun.FFI.CString should be callable as a constructor (new CString(ptr))
|
|
|
|
import { expect, test } from "bun:test";
|
|
|
|
test("Bun.FFI.CString is callable with new", () => {
|
|
const { CString, ptr } = Bun.FFI;
|
|
|
|
// Create a buffer with a null-terminated string
|
|
const buf = Buffer.from("hello\0");
|
|
const ptrValue = ptr(buf);
|
|
|
|
// CString should be callable with new
|
|
const result = new CString(ptrValue, 0, 5);
|
|
|
|
// The result should be the string "hello"
|
|
expect(String(result)).toBe("hello");
|
|
});
|
|
|
|
test("Bun.FFI.CString can be called without new", () => {
|
|
const { CString, ptr } = Bun.FFI;
|
|
|
|
// Create a buffer with a null-terminated string
|
|
const buf = Buffer.from("hello\0");
|
|
const ptrValue = ptr(buf);
|
|
|
|
// CString should also be callable without new
|
|
const result = CString(ptrValue, 0, 5);
|
|
|
|
// The result should be the string "hello"
|
|
expect(result).toBe("hello");
|
|
});
|