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:
Claude Bot
2026-01-27 09:19:25 +00:00
parent bfe40e8760
commit 47789cbeb3

View File

@@ -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;
}
};