From aac110fbc06525748cf3ad687395c2204f01b654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ximo=20Casta=C3=B1eda?= Date: Mon, 17 Aug 2026 14:06:12 +0200 Subject: [PATCH] Deskbar: Defend against applications quitting before finished launching. If an application quits before it has finished handling its launch we may not get its icons, which we try to access later on. Tell the caller and don't add that group, we were going to remove it anyway. If an application quits while we are iterating the team list limited by a previous count, we may access an item outside the list. Protect list accesses with the subscribers lock so that we are locking in Add/RemoveTeam. Fixes #20039, #20250. Change-Id: Ibe9e4f70237f0505bcda1f8aaa7497a532414263 Reviewed-on: https://review.haiku-os.org/c/haiku/+/11546 Reviewed-by: waddlesplash Haiku-Format: Haiku-format Bot Tested-by: Commit checker robot (cherry picked from commit 4c177fdbf7c3fa9c92508f32734bd583c75ab193) Reviewed-on: https://review.haiku-os.org/c/haiku/+/11547 --- src/apps/deskbar/BarApp.cpp | 8 ++++++++ src/apps/deskbar/Switcher.cpp | 28 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/apps/deskbar/BarApp.cpp b/src/apps/deskbar/BarApp.cpp index cb4ef8cbd0..f41545d92e 100644 --- a/src/apps/deskbar/BarApp.cpp +++ b/src/apps/deskbar/BarApp.cpp @@ -806,6 +806,10 @@ TBarApp::Unsubscribe(const BMessenger &subscriber) BBitmap* TBarApp::FetchTeamIcon(team_id team, int32 size) { + BAutolock autolock(sSubscriberLock); + if (!autolock.IsLocked()) + return NULL; + int32 teamCount = sBarTeamInfoList.CountItems(); for (int32 i = 0; i < teamCount; i++) { BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); @@ -979,6 +983,10 @@ TBarApp::RemoveTeam(team_id team) void TBarApp::ResizeTeamIcons() { + BAutolock autolock(sSubscriberLock); + if (!autolock.IsLocked()) + return; + for (int32 i = sBarTeamInfoList.CountItems() - 1; i >= 0; i--) { BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); if ((barInfo->flags & B_BACKGROUND_APP) == 0 diff --git a/src/apps/deskbar/Switcher.cpp b/src/apps/deskbar/Switcher.cpp index 1cdea7a425..ce8957f444 100644 --- a/src/apps/deskbar/Switcher.cpp +++ b/src/apps/deskbar/Switcher.cpp @@ -85,7 +85,7 @@ public: const BBitmap* SmallIcon() const { return fSmallIcon; } const BBitmap* LargeIcon() const { return fLargeIcon; } - void CacheTeamIcons(int32 small, int32 large); + status_t CacheTeamIcons(int32 small, int32 large); private: BList* fTeams; @@ -386,7 +386,7 @@ TTeamGroup::Draw(BView* view, BRect bounds, bool main) } -void +status_t TTeamGroup::CacheTeamIcons(int32 smallIconSize, int32 largeIconSize) { TBarApp* app = static_cast(be_app); @@ -396,6 +396,11 @@ TTeamGroup::CacheTeamIcons(int32 smallIconSize, int32 largeIconSize) fSmallIcon = app->FetchTeamIcon(team, smallIconSize); fLargeIcon = app->FetchTeamIcon(team, largeIconSize); } + + if (fLargeIcon == NULL || fSmallIcon == NULL) + return B_ERROR; + + return B_OK; } @@ -454,8 +459,10 @@ TSwitchManager::TSwitchManager() TTeamGroup* group = new TTeamGroup(barTeamInfo->teams, barTeamInfo->flags, barTeamInfo->name, barTeamInfo->sig); - group->CacheTeamIcons(fSmallIconSize, fLargeIconSize); - fGroupList.AddItem(group); + if (group->CacheTeamIcons(fSmallIconSize, fLargeIconSize) == B_OK) + fGroupList.AddItem(group); + else + delete group; barTeamInfo->teams = NULL; barTeamInfo->name = NULL; @@ -525,9 +532,12 @@ TSwitchManager::MessageReceived(BMessage* message) TTeamGroup* group = new TTeamGroup(teams, flags, strdup(name), signature); - group->CacheTeamIcons(fSmallIconSize, fLargeIconSize); - fGroupList.AddItem(group); - fWindow->Redraw(fGroupList.CountItems() - 1); + if (group->CacheTeamIcons(fSmallIconSize, fLargeIconSize) == B_OK) { + fGroupList.AddItem(group); + fWindow->Redraw(fGroupList.CountItems() - 1); + } else { + delete group; + } break; } @@ -541,10 +551,8 @@ TSwitchManager::MessageReceived(BMessage* message) TTeamGroup* group = (TTeamGroup*)fGroupList.ItemAt(index); ASSERT(group); if (strcasecmp(group->Signature(), signature) == 0) { - if (!group->TeamList()->HasItem((void*)(addr_t)team)) { - group->CacheTeamIcons(fSmallIconSize, fLargeIconSize); + if (!group->TeamList()->HasItem((void*)(addr_t)team)) group->TeamList()->AddItem((void*)(addr_t)team); - } break; } }