1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-14 07:10:24 +02:00

Prevent possible dangling pointers to Project from Clipboard

This commit is contained in:
Paul Licameli 2020-07-01 18:16:39 -04:00
parent 8ea07572c1
commit b4ce083185
5 changed files with 16 additions and 12 deletions

View File

@ -34,7 +34,7 @@ void Clipboard::Clear()
{
mT0 = 0.0;
mT1 = 0.0;
mProject = nullptr;
mProject.reset();
mTracks->Clear();
// Emit an event for listeners
@ -42,7 +42,7 @@ void Clipboard::Clear()
}
void Clipboard::Assign( TrackList && newContents,
double t0, double t1, AudacityProject *pProject )
double t0, double t1, const std::weak_ptr<AudacityProject> &pProject )
{
newContents.Swap( *mTracks );
newContents.Clear();

View File

@ -35,20 +35,20 @@ public:
double T1() const { return mT1; }
double Duration() const { return mT1 - mT0; }
AudacityProject *Project() const { return mProject; }
const std::weak_ptr<AudacityProject> &Project() const { return mProject; }
void Clear();
void Assign(
TrackList && newContents, double t0, double t1,
AudacityProject *pProject );
const std::weak_ptr<AudacityProject> &pProject );
private:
Clipboard();
~Clipboard();
std::shared_ptr<TrackList> mTracks;
AudacityProject *mProject{};
std::weak_ptr<AudacityProject> mProject{};
double mT0{ 0 };
double mT1{ 0 };
};

View File

@ -103,6 +103,7 @@ class AUDACITY_DLL_API AudacityProject final
: public wxEvtHandler
, public AttachedObjects
, public AttachedWindows
, public std::enable_shared_from_this<AudacityProject>
{
public:
using AttachedObjects = ::AttachedObjects;

View File

@ -85,6 +85,7 @@ bool DoPasteNothingSelected(AudacityProject &project)
else
{
const auto &clipboard = Clipboard::Get();
auto clipboardProject = clipboard.Project().lock();
auto clipTrackRange = clipboard.GetTracks().Any< const Track >();
if (clipTrackRange.empty())
return true; // nothing to paste
@ -97,7 +98,7 @@ bool DoPasteNothingSelected(AudacityProject &project)
Track *pNewTrack;
pClip->TypeSwitch(
[&](const WaveTrack *wc) {
if ((clipboard.Project() != &project))
if ((clipboardProject.get() != &project))
// Cause duplication of block files on disk, when copy is
// between projects
locker.emplace(wc);
@ -277,7 +278,7 @@ void OnCut(const CommandContext &context)
std::move( newClipboard ),
selectedRegion.t0(),
selectedRegion.t1(),
&project
project.shared_from_this()
);
// Proceed to change the project. If this throws, the project will be
@ -369,7 +370,7 @@ void OnCopy(const CommandContext &context)
// Survived possibility of exceptions. Commit changes to the clipboard now.
clipboard.Assign( std::move( newClipboard ),
selectedRegion.t0(), selectedRegion.t1(), &project );
selectedRegion.t0(), selectedRegion.t1(), project.shared_from_this() );
//Make sure the menus/toolbar states get updated
trackPanel.Refresh(false);
@ -415,6 +416,7 @@ void OnPaste(const CommandContext &context)
auto pC = clipTrackRange.begin();
size_t nnChannels=0, ncChannels=0;
auto clipboardProject = clipboard.Project().lock();
while (*pN && *pC) {
auto n = *pN;
auto c = *pC;
@ -507,7 +509,7 @@ void OnPaste(const CommandContext &context)
n->TypeSwitch(
[&](WaveTrack *wn){
const auto wc = static_cast<const WaveTrack *>(c);
if (clipboard.Project() != &project)
if (clipboardProject.get() != &project)
// Cause duplication of block files on disk, when copy is
// between projects
locker.emplace(wc);
@ -581,7 +583,7 @@ void OnPaste(const CommandContext &context)
const auto wc =
*clipboard.GetTracks().Any< const WaveTrack >().rbegin();
Optional<WaveTrack::Locker> locker;
if (clipboard.Project() != &project && wc)
if (clipboardProject.get() != &project && wc)
// Cause duplication of block files on disk, when copy is
// between projects
locker.emplace(static_cast<const WaveTrack*>(wc));
@ -702,7 +704,7 @@ void OnSplitCut(const CommandContext &context)
// Survived possibility of exceptions. Commit changes to the clipboard now.
clipboard.Assign( std::move( newClipboard ),
selectedRegion.t0(), selectedRegion.t1(), &project );
selectedRegion.t0(), selectedRegion.t1(), project.shared_from_this() );
ProjectHistory::Get( project )
.PushState(XO("Split-cut to the clipboard"), XO("Split Cut"));

View File

@ -4,6 +4,7 @@
#include "../LabelTrack.h"
#include "../Menus.h"
#include "../Prefs.h"
#include "../Project.h"
#include "../ProjectAudioIO.h"
#include "../ProjectHistory.h"
#include "../ProjectWindow.h"
@ -266,7 +267,7 @@ void EditClipboardByLabel( AudacityProject &project,
// Survived possibility of exceptions. Commit changes to the clipboard now.
clipboard.Assign( std::move( newClipboard ),
regions.front().start, regions.back().end, &project );
regions.front().start, regions.back().end, project.shared_from_this() );
}
}