From 7cc6bec14ac2244b956ff0049303891356bde05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Fri, 17 Nov 2017 18:35:48 +0100 Subject: [PATCH] Fix a possible range error when a win32 file watcher gets destroyed while waiting. This is not a final solution, but avoids the fatal error and replaces it with, at worst, bogus change events being reported. --- source/eventcore/drivers/winapi/watchers.d | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/eventcore/drivers/winapi/watchers.d b/source/eventcore/drivers/winapi/watchers.d index 4e26d12..dcf60e0 100644 --- a/source/eventcore/drivers/winapi/watchers.d +++ b/source/eventcore/drivers/winapi/watchers.d @@ -77,16 +77,24 @@ final class WinAPIEventDriverWatchers : EventDriverWatchers { { import std.conv : to; - auto handle = overlapped.hEvent; // *file* handle - auto id = WatcherID(cast(int)handle); - auto slot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle].watcher(); } (); - if (dwError != 0) { // FIXME: this must be propagated to the caller //logWarn("Failed to read directory changes: %s", dwError); return; } + auto handle = overlapped.hEvent; // *file* handle + auto id = WatcherID(cast(int)handle); + + /* HACK: this avoids a range voilation in case an already destroyed + watcher still fires a completed event. It does not avoid problems + that may arise from reused file handles. + */ + if (handle !in WinAPIEventDriver.threadInstance.core.m_handles) + return; + + auto slot = () @trusted { return &WinAPIEventDriver.threadInstance.core.m_handles[handle].watcher(); } (); + ubyte[] result = slot.buffer[0 .. cbTransferred]; do { assert(result.length >= FILE_NOTIFY_INFORMATION.sizeof);