mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
fix(watcher): handle unknown file action codes in Windows watcher
Use std.meta.intToEnum instead of @enumFromInt to safely convert FILE_NOTIFY_INFORMATION.Action values. This prevents a panic if the Windows ReadDirectoryChangesW API returns an unexpected action code. Unknown action codes are now logged and skipped rather than causing a runtime panic. Fixes #26496 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,24 +59,31 @@ const EventIterator = struct {
|
||||
hasNext: bool = true,
|
||||
|
||||
pub fn next(this: *EventIterator) ?FileEvent {
|
||||
if (!this.hasNext) return null;
|
||||
const info_size = @sizeOf(w.FILE_NOTIFY_INFORMATION);
|
||||
const info: *w.FILE_NOTIFY_INFORMATION = @ptrCast(@alignCast(this.watcher.buf[this.offset..].ptr));
|
||||
const name_ptr: [*]u16 = @ptrCast(@alignCast(this.watcher.buf[this.offset + info_size ..]));
|
||||
const filename: []u16 = name_ptr[0 .. info.FileNameLength / @sizeOf(u16)];
|
||||
while (this.hasNext) {
|
||||
const info_size = @sizeOf(w.FILE_NOTIFY_INFORMATION);
|
||||
const info: *w.FILE_NOTIFY_INFORMATION = @ptrCast(@alignCast(this.watcher.buf[this.offset..].ptr));
|
||||
const name_ptr: [*]u16 = @ptrCast(@alignCast(this.watcher.buf[this.offset + info_size ..]));
|
||||
const filename: []u16 = name_ptr[0 .. info.FileNameLength / @sizeOf(u16)];
|
||||
|
||||
const action: Action = @enumFromInt(info.Action);
|
||||
if (info.NextEntryOffset == 0) {
|
||||
this.hasNext = false;
|
||||
} else {
|
||||
this.offset += @as(usize, info.NextEntryOffset);
|
||||
}
|
||||
|
||||
if (info.NextEntryOffset == 0) {
|
||||
this.hasNext = false;
|
||||
} else {
|
||||
this.offset += @as(usize, info.NextEntryOffset);
|
||||
// Use intToEnum to safely convert the action value, skipping unknown action types.
|
||||
// The Windows API may return undocumented action codes in some edge cases.
|
||||
const action: Action = std.meta.intToEnum(Action, info.Action) catch {
|
||||
log("skipping unknown file action: {d}", .{info.Action});
|
||||
continue;
|
||||
};
|
||||
|
||||
return FileEvent{
|
||||
.action = action,
|
||||
.filename = filename,
|
||||
};
|
||||
}
|
||||
|
||||
return FileEvent{
|
||||
.action = action,
|
||||
.filename = filename,
|
||||
};
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user