Fix possible/low chance to happen memory leak

Reported in PR #2782
This commit is contained in:
David Capello 2021-06-23 08:39:24 -03:00
parent 8ee8bd0ec7
commit 89f8e6f275
3 changed files with 20 additions and 4 deletions

View File

@ -80,6 +80,14 @@ namespace app {
// executing new Cmds again.
void rollbackAndStartAgain();
// Executes the given command and tries to add it to the container
// of executed commands (m_cmds).
//
// If some of these operations fails, the given "cmd" will be
// deleted anyway.
//
// TODO In the future we should refactor this using unique
// pointers-like structure only
void execute(Cmd* cmd);
private:

View File

@ -65,6 +65,7 @@ namespace app {
m_transaction->rollbackAndStartAgain();
}
// If the command cannot be executed, it will be deleted anyway.
void operator()(Cmd* cmd) {
m_transaction->execute(cmd);
}

View File

@ -75,6 +75,7 @@
#include <cstring>
#include <limits>
#include <memory>
namespace app {
@ -1169,7 +1170,8 @@ void ColorBar::updateCurrentSpritePalette(const char* operationName)
if (from >= 0 && to >= from) {
DocUndo* undo = document->undoHistory();
Cmd* cmd = new cmd::SetPalette(sprite, frame, newPalette);
std::unique_ptr<cmd::SetPalette> cmd(
new cmd::SetPalette(sprite, frame, newPalette));
// Add undo information to save the range of pal entries that will be modified.
if (m_implantChange &&
@ -1178,12 +1180,17 @@ void ColorBar::updateCurrentSpritePalette(const char* operationName)
// Implant the cmd in the last CmdSequence if it's
// related about color palette modifications
ASSERT(dynamic_cast<CmdSequence*>(undo->lastExecutedCmd()));
static_cast<CmdSequence*>(undo->lastExecutedCmd())->add(cmd);
cmd->execute(UIContext::instance());
static_cast<CmdSequence*>(undo->lastExecutedCmd())->add(cmd.get());
// Release the unique pointer because it's already in the
// last executed command CmdSequence::m_cmds container, and
// execute it.
cmd.release()->execute(UIContext::instance());
}
else {
Tx tx(writer.context(), operationName, ModifyDocument);
tx(cmd);
// If tx() fails it will delete the cmd anyway, so we can
// release the unique pointer here.
tx(cmd.release());
tx.commit();
}
}