1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Fix possible memory corruption in video player

Fixes two bugs, one was definitely happening, and 2nd one that is causing
undefined behavior and may work only in some std implementations

- VideoPlayer would attempt to access subtitles widget after VideoPlayer
itself was destroyed in onPlaybackFinished call
- std::function was destroyed from a function that is being called by
it. Replaced with 1-method interface to avoid usage of std::function in
this scenario
This commit is contained in:
Ivan Savenko
2024-12-07 15:37:03 +00:00
parent 3115894307
commit 9fbeacb688
10 changed files with 66 additions and 25 deletions

View File

@@ -10,6 +10,7 @@
#include "StdInc.h"
#include "VideoWidget.h"
#include "TextControls.h"
#include "IVideoHolder.h"
#include "../CGameInfo.h"
#include "../gui/CGuiHandler.h"
@@ -172,15 +173,17 @@ void VideoWidgetBase::tick(uint32_t msPassed)
{
videoInstance->tick(msPassed);
if(subTitle)
subTitle->setText(getSubTitleLine(videoInstance->timeStamp()));
if(videoInstance->videoEnded())
{
videoInstance.reset();
stopAudio();
onPlaybackFinished();
// WARNING: onPlaybackFinished call may destoy `this`. Make sure that this is the very last operation in this method!
}
}
if(subTitle && videoInstance)
subTitle->setText(getSubTitleLine(videoInstance->timeStamp()));
}
VideoWidget::VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped, bool playAudio)
@@ -200,19 +203,19 @@ void VideoWidget::onPlaybackFinished()
playVideo(loopedVideo);
}
VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, const std::function<void()> & callback)
VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, IVideoHolder * owner)
: VideoWidgetBase(position, video, playAudio)
, callback(callback)
, owner(owner)
{
}
VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor, const std::function<void()> & callback)
VideoWidgetOnce::VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor, IVideoHolder * owner)
: VideoWidgetBase(position, video, playAudio, scaleFactor)
, callback(callback)
, owner(owner)
{
}
void VideoWidgetOnce::onPlaybackFinished()
{
callback();
owner->onVideoPlaybackFinished();
}