HaikuDepot: Make BitmapView use SharedBitmaps directly.
Instead of extracting a BBitmap out of the SharedBitmap and giving that to BitmapView, set SharedBitmaps directly. When using BBitmaps we circumvent the reference counting of the SharedBitmaps and it would be possible for the SharedBitmap and its BBitmaps to get deleted while one of them was still used in a BitmapView. Fixes use-after-free when icons are updated that are already used in BitmapViews.
This commit is contained in:
parent
3525a370d4
commit
2a36368bda
@ -151,16 +151,15 @@ public:
|
|||||||
fPackageListener->SetPackage(package);
|
fPackageListener->SetPackage(package);
|
||||||
|
|
||||||
if (package->Icon().Get() != NULL) {
|
if (package->Icon().Get() != NULL) {
|
||||||
fIconView->SetBitmap(
|
fIconView->SetBitmap(package->Icon(), SharedBitmap::SIZE_64);
|
||||||
package->Icon()->Bitmap(SharedBitmap::SIZE_64));
|
|
||||||
} else
|
} else
|
||||||
fIconView->SetBitmap(NULL);
|
fIconView->UnsetBitmap();
|
||||||
|
|
||||||
if (package->State() == ACTIVATED) {
|
if (package->State() == ACTIVATED) {
|
||||||
fInstalledIconView->SetBitmap(
|
fInstalledIconView->SetBitmap(sInstalledIcon,
|
||||||
sInstalledIcon->Bitmap(SharedBitmap::SIZE_16));
|
SharedBitmap::SIZE_16);
|
||||||
} else
|
} else
|
||||||
fInstalledIconView->SetBitmap(NULL);
|
fInstalledIconView->UnsetBitmap();
|
||||||
|
|
||||||
fTitleView->SetText(package->Title());
|
fTitleView->SetText(package->Title());
|
||||||
|
|
||||||
@ -199,8 +198,8 @@ public:
|
|||||||
{
|
{
|
||||||
fPackageListener->SetPackage(PackageInfoRef(NULL));
|
fPackageListener->SetPackage(PackageInfoRef(NULL));
|
||||||
|
|
||||||
fIconView->SetBitmap(NULL);
|
fIconView->UnsetBitmap();
|
||||||
fInstalledIconView->SetBitmap(NULL);
|
fInstalledIconView->UnsetBitmap();
|
||||||
fTitleView->SetText("");
|
fTitleView->SetText("");
|
||||||
fPublisherView->SetText("");
|
fPublisherView->SetText("");
|
||||||
fSummaryView->SetText("");
|
fSummaryView->SetText("");
|
||||||
|
@ -391,9 +391,9 @@ public:
|
|||||||
void SetPackage(const PackageInfo& package)
|
void SetPackage(const PackageInfo& package)
|
||||||
{
|
{
|
||||||
if (package.Icon().Get() != NULL)
|
if (package.Icon().Get() != NULL)
|
||||||
fIconView->SetBitmap(package.Icon()->Bitmap(SharedBitmap::SIZE_32));
|
fIconView->SetBitmap(package.Icon(), SharedBitmap::SIZE_32);
|
||||||
else
|
else
|
||||||
fIconView->SetBitmap(NULL);
|
fIconView->UnsetBitmap();
|
||||||
|
|
||||||
fTitleView->SetText(package.Title());
|
fTitleView->SetText(package.Title());
|
||||||
|
|
||||||
@ -431,7 +431,7 @@ public:
|
|||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
fIconView->SetBitmap(NULL);
|
fIconView->UnsetBitmap();
|
||||||
fTitleView->SetText("");
|
fTitleView->SetText("");
|
||||||
fPublisherView->SetText("");
|
fPublisherView->SetText("");
|
||||||
fVersionInfo->SetText("");
|
fVersionInfo->SetText("");
|
||||||
@ -797,31 +797,36 @@ public:
|
|||||||
fDescriptionView->SetText(package.ShortDescription(),
|
fDescriptionView->SetText(package.ShortDescription(),
|
||||||
package.FullDescription());
|
package.FullDescription());
|
||||||
|
|
||||||
fEmailIconView->SetBitmap(fEmailIcon.Bitmap(SharedBitmap::SIZE_16));
|
fEmailIconView->SetBitmap(&fEmailIcon, SharedBitmap::SIZE_16);
|
||||||
_SetContactInfo(fEmailLinkView, package.Publisher().Email());
|
_SetContactInfo(fEmailLinkView, package.Publisher().Email());
|
||||||
fWebsiteIconView->SetBitmap(fWebsiteIcon.Bitmap(SharedBitmap::SIZE_16));
|
fWebsiteIconView->SetBitmap(&fWebsiteIcon, SharedBitmap::SIZE_16);
|
||||||
_SetContactInfo(fWebsiteLinkView, package.Publisher().Website());
|
_SetContactInfo(fWebsiteLinkView, package.Publisher().Website());
|
||||||
|
|
||||||
const BBitmap* screenshot = NULL;
|
bool hasScreenshot = false;
|
||||||
const BitmapList& screenShots = package.Screenshots();
|
const BitmapList& screenShots = package.Screenshots();
|
||||||
if (screenShots.CountItems() > 0) {
|
if (screenShots.CountItems() > 0) {
|
||||||
const BitmapRef& bitmapRef = screenShots.ItemAtFast(0);
|
const BitmapRef& bitmapRef = screenShots.ItemAtFast(0);
|
||||||
if (bitmapRef.Get() != NULL)
|
if (bitmapRef.Get() != NULL) {
|
||||||
screenshot = bitmapRef->Bitmap(SharedBitmap::SIZE_ANY);
|
hasScreenshot = true;
|
||||||
|
fScreenshotView->SetBitmap(bitmapRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fScreenshotView->SetBitmap(screenshot);
|
|
||||||
fScreenshotView->SetEnabled(screenshot != NULL);
|
if (!hasScreenshot)
|
||||||
|
fScreenshotView->UnsetBitmap();
|
||||||
|
|
||||||
|
fScreenshotView->SetEnabled(hasScreenshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
fDescriptionView->SetText("");
|
fDescriptionView->SetText("");
|
||||||
fEmailIconView->SetBitmap(NULL);
|
fEmailIconView->UnsetBitmap();
|
||||||
fEmailLinkView->SetText("");
|
fEmailLinkView->SetText("");
|
||||||
fWebsiteIconView->SetBitmap(NULL);
|
fWebsiteIconView->UnsetBitmap();
|
||||||
fWebsiteLinkView->SetText("");
|
fWebsiteLinkView->SetText("");
|
||||||
|
|
||||||
fScreenshotView->SetBitmap(NULL);
|
fScreenshotView->UnsetBitmap();
|
||||||
fScreenshotView->SetEnabled(false);
|
fScreenshotView->SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,8 +872,8 @@ public:
|
|||||||
|
|
||||||
fAvatarView = new BitmapView("avatar view");
|
fAvatarView = new BitmapView("avatar view");
|
||||||
if (rating.User().Avatar().Get() != NULL) {
|
if (rating.User().Avatar().Get() != NULL) {
|
||||||
fAvatarView->SetBitmap(
|
fAvatarView->SetBitmap(rating.User().Avatar(),
|
||||||
rating.User().Avatar()->Bitmap(SharedBitmap::SIZE_16));
|
SharedBitmap::SIZE_16);
|
||||||
}
|
}
|
||||||
fAvatarView->SetExplicitMinSize(BSize(16.0f, 16.0f));
|
fAvatarView->SetExplicitMinSize(BSize(16.0f, 16.0f));
|
||||||
|
|
||||||
@ -908,10 +913,8 @@ public:
|
|||||||
// fVoteDownIconView = new BitmapButton("vote down icon", voteDownMessage);
|
// fVoteDownIconView = new BitmapButton("vote down icon", voteDownMessage);
|
||||||
// fDownVoteCountView = new BStringView("up vote count", "");
|
// fDownVoteCountView = new BStringView("up vote count", "");
|
||||||
//
|
//
|
||||||
// fVoteUpIconView->SetBitmap(
|
// fVoteUpIconView->SetBitmap(voteUpIcon, SharedBitmap::SIZE_16);
|
||||||
// voteUpIcon->Bitmap(SharedBitmap::SIZE_16));
|
// fVoteDownIconView->SetBitmap(voteDownIcon, SharedBitmap::SIZE_16);
|
||||||
// fVoteDownIconView->SetBitmap(
|
|
||||||
// voteDownIcon->Bitmap(SharedBitmap::SIZE_16));
|
|
||||||
//
|
//
|
||||||
// fUpVoteCountView->SetFont(&versionFont);
|
// fUpVoteCountView->SetFont(&versionFont);
|
||||||
// fUpVoteCountView->SetHighColor(kLightBlack);
|
// fUpVoteCountView->SetHighColor(kLightBlack);
|
||||||
|
@ -175,8 +175,8 @@ ScreenshotWindow::_DownloadThread()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fScreenshotView->SetBitmap(NULL);
|
fScreenshotView->UnsetBitmap();
|
||||||
|
|
||||||
ScreenshotInfoList screenshotInfos;
|
ScreenshotInfoList screenshotInfos;
|
||||||
if (fPackage.Get() != NULL)
|
if (fPackage.Get() != NULL)
|
||||||
screenshotInfos = fPackage->ScreenshotInfos();
|
screenshotInfos = fPackage->ScreenshotInfos();
|
||||||
@ -202,7 +202,7 @@ ScreenshotWindow::_DownloadThread()
|
|||||||
if (status == B_OK && Lock()) {
|
if (status == B_OK && Lock()) {
|
||||||
printf("got screenshot");
|
printf("got screenshot");
|
||||||
fScreenshot = BitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
fScreenshot = BitmapRef(new(std::nothrow)SharedBitmap(buffer), true);
|
||||||
fScreenshotView->SetBitmap(fScreenshot->Bitmap(SharedBitmap::SIZE_ANY));
|
fScreenshotView->SetBitmap(fScreenshot);
|
||||||
_ResizeToFitAndCenter();
|
_ResizeToFitAndCenter();
|
||||||
Unlock();
|
Unlock();
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,10 +235,9 @@ UserLoginWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case MSG_CAPTCHA_OBTAINED:
|
case MSG_CAPTCHA_OBTAINED:
|
||||||
if (fCaptchaImage.Get() != NULL) {
|
if (fCaptchaImage.Get() != NULL) {
|
||||||
fCaptchaView->SetBitmap(
|
fCaptchaView->SetBitmap(fCaptchaImage);
|
||||||
fCaptchaImage->Bitmap(SharedBitmap::SIZE_ANY));
|
|
||||||
} else {
|
} else {
|
||||||
fCaptchaView->SetBitmap(NULL);
|
fCaptchaView->UnsetBitmap();
|
||||||
}
|
}
|
||||||
fCaptchaResultField->SetText("");
|
fCaptchaResultField->SetText("");
|
||||||
break;
|
break;
|
||||||
@ -442,7 +441,7 @@ UserLoginWindow::_RequestCaptcha()
|
|||||||
{
|
{
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
fCaptchaToken = "";
|
fCaptchaToken = "";
|
||||||
fCaptchaView->SetBitmap(NULL);
|
fCaptchaView->UnsetBitmap();
|
||||||
fCaptchaImage.Unset();
|
fCaptchaImage.Unset();
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
@ -131,14 +131,16 @@ BitmapView::MaxSize()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BitmapView::SetBitmap(const BBitmap* bitmap)
|
BitmapView::SetBitmap(SharedBitmap* bitmap, SharedBitmap::Size bitmapSize)
|
||||||
{
|
{
|
||||||
if (bitmap == fBitmap)
|
if (bitmap == fReference && bitmapSize == fBitmapSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BSize size = MinSize();
|
BSize size = MinSize();
|
||||||
|
|
||||||
fBitmap = bitmap;
|
fReference.SetTo(bitmap);
|
||||||
|
fBitmapSize = bitmapSize;
|
||||||
|
fBitmap = bitmap->Bitmap(bitmapSize);
|
||||||
|
|
||||||
BSize newSize = MinSize();
|
BSize newSize = MinSize();
|
||||||
if (size != newSize)
|
if (size != newSize)
|
||||||
@ -148,6 +150,20 @@ BitmapView::SetBitmap(const BBitmap* bitmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BitmapView::UnsetBitmap()
|
||||||
|
{
|
||||||
|
if (fReference.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fBitmap = NULL;
|
||||||
|
fReference.Unset();
|
||||||
|
|
||||||
|
InvalidateLayout();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BitmapView::SetScaleBitmap(bool scaleBitmap)
|
BitmapView::SetScaleBitmap(bool scaleBitmap)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#define BITMAP_VIEW_H
|
#define BITMAP_VIEW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "SharedBitmap.h"
|
||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
@ -22,7 +24,10 @@ public:
|
|||||||
virtual BSize PreferredSize();
|
virtual BSize PreferredSize();
|
||||||
virtual BSize MaxSize();
|
virtual BSize MaxSize();
|
||||||
|
|
||||||
void SetBitmap(const BBitmap* bitmap);
|
void SetBitmap(SharedBitmap* bitmap,
|
||||||
|
SharedBitmap::Size bitmapSize
|
||||||
|
= SharedBitmap::SIZE_ANY);
|
||||||
|
void UnsetBitmap();
|
||||||
void SetScaleBitmap(bool scaleBitmap);
|
void SetScaleBitmap(bool scaleBitmap);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -30,6 +35,8 @@ protected:
|
|||||||
BRect updateRect);
|
BRect updateRect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BitmapRef fReference;
|
||||||
|
SharedBitmap::Size fBitmapSize;
|
||||||
const BBitmap* fBitmap;
|
const BBitmap* fBitmap;
|
||||||
bool fScaleBitmap;
|
bool fScaleBitmap;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user