From 063a5a9775eae7d50fc059de759eb19902ee584e Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Sun, 2 Nov 2025 12:40:41 +0000 Subject: [PATCH] Add safety improvements and encapsulation 1. Explicitly zero out bit 63 when unpacking pointer to avoid any UB - Added mask: ptr_bits & 0x7FFFFFFFFFFFFFFF before ptrFromInt 2. Add ConcurrentTask.auto_delete() getter to hide implementation detail - The fact that auto_delete is packed into next field is now internal - Updated event_loop.zig to use the public getter - Makes the API cleaner and easier to maintain --- src/bun.js/event_loop.zig | 2 +- src/bun.js/event_loop/ConcurrentTask.zig | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index a04e7e53c2..a5ff5764cd 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -321,7 +321,7 @@ pub fn tickConcurrentWithCount(this: *EventLoop) usize { dest.deinit(); } - if (task.next.autoDelete()) { + if (task.auto_delete()) { to_destroy = task; } diff --git a/src/bun.js/event_loop/ConcurrentTask.zig b/src/bun.js/event_loop/ConcurrentTask.zig index 071df3143f..d6398bdb8f 100644 --- a/src/bun.js/event_loop/ConcurrentTask.zig +++ b/src/bun.js/event_loop/ConcurrentTask.zig @@ -44,7 +44,8 @@ pub const PackedNext = packed struct(u64) { pub fn get(self: PackedNext) ?*ConcurrentTask { if (self.ptr_bits == 0) return null; - const ptr: u64 = @as(u64, self.ptr_bits); + // Explicitly zero out bit 63 to avoid any UB + const ptr: u64 = @as(u64, self.ptr_bits) & 0x7FFFFFFFFFFFFFFF; return @as(?*ConcurrentTask, @ptrFromInt(ptr)); } @@ -69,6 +70,12 @@ pub const Queue = bun.threading.UnboundedQueuePacked(ConcurrentTask, .next, .@"p pub const new = bun.TrivialNew(@This()); pub const deinit = bun.TrivialDeinit(@This()); +/// Returns whether this task should be automatically deleted after completion. +/// The auto_delete flag being stored in the next field is an implementation detail. +pub inline fn auto_delete(this: *const ConcurrentTask) bool { + return this.next.autoDelete(); +} + pub const AutoDeinit = enum { manual_deinit, auto_deinit,