Patch for #377; fixes a dangling-pointer bug in _ReleaseCelData
This is triggered by having one thread lock a graphics resource (usually through a StarShipPtr) and then have another thread release it. The Frame data is gone, but pointers to that data (as well as the Drawable itself, of course) remain. If the 'locking' thread then tries to use its Frame data, it will have end up accessing garbage. (The nulling of the DrawablePtr->Frame pointer doesn't help because the Frame itself has been cached.) git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@946 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -497,7 +497,7 @@ _ReleaseCelData (MEM_HANDLE handle)
|
||||
{
|
||||
DRAWABLEPTR DrawablePtr;
|
||||
int cel_ct;
|
||||
FRAMEPTR FramePtr;
|
||||
FRAMEPTR FramePtr = NULL;
|
||||
|
||||
if ((DrawablePtr = LockDrawable (handle)) == 0)
|
||||
return (FALSE);
|
||||
@@ -506,25 +506,28 @@ _ReleaseCelData (MEM_HANDLE handle)
|
||||
|
||||
if (DrawablePtr->Frame)
|
||||
{
|
||||
FramePtr = &DrawablePtr->Frame[cel_ct];
|
||||
if (TYPE_GET ((FramePtr-1)->TypeIndexAndFlags) != SCREEN_DRAWABLE)
|
||||
FramePtr = DrawablePtr->Frame;
|
||||
if (TYPE_GET (FramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE)
|
||||
{
|
||||
while (--FramePtr, cel_ct--)
|
||||
{
|
||||
TFB_Image *img = FramePtr->image;
|
||||
if (img)
|
||||
{
|
||||
FramePtr->image = NULL;
|
||||
TFB_DrawScreen_DeleteImage (img);
|
||||
}
|
||||
}
|
||||
FramePtr = NULL;
|
||||
}
|
||||
HFree (DrawablePtr->Frame);
|
||||
DrawablePtr->Frame = NULL;
|
||||
}
|
||||
|
||||
UnlockDrawable (handle);
|
||||
mem_release (handle);
|
||||
if (mem_release (handle) && FramePtr)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cel_ct; i++)
|
||||
{
|
||||
TFB_Image *img = FramePtr[i].image;
|
||||
if (img)
|
||||
{
|
||||
FramePtr[i].image = NULL;
|
||||
TFB_DrawScreen_DeleteImage (img);
|
||||
}
|
||||
}
|
||||
HFree (FramePtr);
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user