Skip to content

Commit 6ad208b

Browse files
Jarred-SumnerJarred Sumnerclaude
authored
Fix integer cast truncation panic on Windows for buffers > 4GB (#21738)
## Summary This PR fixes a panic that occurs when file operations use buffers larger than 4GB on Windows. ## The Problem When calling `fs.readSync()` or `fs.writeSync()` with buffers larger than 4,294,967,295 bytes (u32::MAX), Bun panics with: ``` panic(main thread): integer cast truncated bits ``` ## Root Cause The Windows APIs `ReadFile()` and `WriteFile()` expect a `DWORD` (u32) for the buffer length parameter. The code was using `@intCast` to convert from `usize` to `u32`, which panics when the value exceeds u32::MAX. ## The Fix Changed `@intCast` to `@truncate` in four locations: 1. `sys.zig:1839` - ReadFile buffer length parameter 2. `sys.zig:1556` - WriteFile buffer length parameter 3. `bun.zig:230` - platformIOVecCreate length field 4. `bun.zig:240` - platformIOVecConstCreate length field With these changes, operations with buffers > 4GB will read/write up to 4GB at a time instead of panicking. ## Test Plan ```js // This previously caused a panic on Windows const fs = require('fs'); const fd = fs.openSync('test.txt', 'r'); const buffer = Buffer.allocUnsafe(4_294_967_296); // 4GB + 1 byte fs.readSync(fd, buffer, 0, buffer.length, 0); ``` Fixes #21699 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Jarred Sumner <jarred@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>
1 parent b0799da commit 6ad208b

File tree

2 files changed

+4
-14
lines changed

2 files changed

+4
-14
lines changed

src/bun.zig

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -221,23 +221,13 @@ else
221221
std.posix.iovec_const;
222222

223223
pub fn platformIOVecCreate(input: []const u8) PlatformIOVec {
224-
if (Environment.allow_assert) {
225-
if (input.len > @as(usize, std.math.maxInt(u32))) {
226-
Output.debugWarn("call to bun.PlatformIOVec.init with length larger than u32, this will overflow on windows", .{});
227-
}
228-
}
229224
// TODO: remove this constCast by making the input mutable
230-
return .{ .len = @intCast(input.len), .base = @constCast(input.ptr) };
225+
return .{ .len = @truncate(input.len), .base = @constCast(input.ptr) };
231226
}
232227

233228
pub fn platformIOVecConstCreate(input: []const u8) PlatformIOVecConst {
234-
if (Environment.allow_assert) {
235-
if (input.len > @as(usize, std.math.maxInt(u32))) {
236-
Output.debugWarn("call to bun.PlatformIOVecConst.init with length larger than u32, this will overflow on windows", .{});
237-
}
238-
}
239229
// TODO: remove this constCast by adding uv_buf_t_const
240-
return .{ .len = @intCast(input.len), .base = @constCast(input.ptr) };
230+
return .{ .len = @truncate(input.len), .base = @constCast(input.ptr) };
241231
}
242232

243233
pub fn platformIOVecToSlice(iovec: PlatformIOVec) []u8 {

src/sys.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ pub fn write(fd: bun.FileDescriptor, bytes: []const u8) Maybe(usize) {
15531553
const rc = kernel32.WriteFile(
15541554
fd.cast(),
15551555
bytes.ptr,
1556-
adjusted_len,
1556+
@as(u32, @truncate(adjusted_len)),
15571557
&bytes_written,
15581558
null,
15591559
);
@@ -1836,7 +1836,7 @@ pub fn read(fd: bun.FileDescriptor, buf: []u8) Maybe(usize) {
18361836
sys_uv.read(fd, buf)
18371837
else {
18381838
var amount_read: u32 = 0;
1839-
const rc = kernel32.ReadFile(fd.native(), buf.ptr, @as(u32, @intCast(adjusted_len)), &amount_read, null);
1839+
const rc = kernel32.ReadFile(fd.native(), buf.ptr, @as(u32, @truncate(adjusted_len)), &amount_read, null);
18401840
if (rc == windows.FALSE) {
18411841
const ret: Maybe(usize) = .{
18421842
.err = sys.Error{

0 commit comments

Comments
 (0)