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 <[email protected]>
Haiku-Format: Haiku-format Bot <[email protected]>
Tested-by: Commit checker robot <[email protected]>
(cherry picked from commit 4c177fdbf7c3fa9c92508f32734bd583c75ab193)
Reviewed-on: https://review.haiku-os.org/c/haiku/+/11547
This commit is contained in:
Máximo Castañeda
2026-08-17 15:32:20 +00:00
committed by waddlesplash
parent f14cafbe87
commit aac110fbc0
2 changed files with 26 additions and 10 deletions
+8
View File
@@ -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
+18 -10
View File
@@ -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<TBarApp*>(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;
}
}