From 1ca63af53882bc1f335f81be5f0d2bd1acd7c8d6 Mon Sep 17 00:00:00 2001 From: Julian Pscheid Date: Fri, 31 Jul 2026 06:39:23 -0700 Subject: [PATCH] fix: value-initialize NOTIFYICONDATA and clear hIcon after destroy nid and niif were declared without initializers. _ApplyIcon() backs up nid.szTip before zeroing the struct and sets NIF_TIP when the first byte is non-null, so on the first setIcon() call it reads uninitialized memory and can register it as the tooltip. An app that never calls setToolTip() then shows whatever happened to be in that buffer. Destroy() and the WM_DESTROY handler also left nid.hIcon dangling after DestroyIcon(), so the null check in SetIcon() could never fire and a destroy/re-init cycle destroyed the same handle twice. --- .../tray_manager/windows/tray_manager_plugin.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/tray_manager/windows/tray_manager_plugin.cpp b/packages/tray_manager/windows/tray_manager_plugin.cpp index 59e98d6..91a42a7 100644 --- a/packages/tray_manager/windows/tray_manager_plugin.cpp +++ b/packages/tray_manager/windows/tray_manager_plugin.cpp @@ -46,8 +46,8 @@ class TrayManagerPlugin : public flutter::Plugin { std::wstring_convert> g_converter; flutter::PluginRegistrarWindows* registrar; - NOTIFYICONDATA nid; - NOTIFYICONIDENTIFIER niif; + NOTIFYICONDATA nid{}; + NOTIFYICONIDENTIFIER niif{}; // do create pop-up menu only once. HMENU hMenu = CreatePopupMenu(); bool tray_icon_setted = false; @@ -186,7 +186,10 @@ std::optional TrayManagerPlugin::HandleWindowProc(HWND hWnd, if (message == WM_DESTROY) { if (tray_icon_setted) { Shell_NotifyIcon(NIM_DELETE, &nid); - DestroyIcon(nid.hIcon); + if (nid.hIcon != nullptr) { + DestroyIcon(nid.hIcon); + nid.hIcon = nullptr; + } } } else if (message == WM_COMMAND) { flutter::EncodableMap eventData = flutter::EncodableMap(); @@ -241,7 +244,10 @@ void TrayManagerPlugin::Destroy( const flutter::MethodCall& method_call, std::unique_ptr> result) { Shell_NotifyIcon(NIM_DELETE, &nid); - DestroyIcon(nid.hIcon); + if (nid.hIcon != nullptr) { + DestroyIcon(nid.hIcon); + nid.hIcon = nullptr; + } tray_icon_setted = false; result->Success(flutter::EncodableValue(true));