Fix crash when a renamed part is saved

The crash happened when during rename operation, when the original part
buffer has been marked as deleted, but its memory was not yet freed. The
renamed part was still using the original SCH_SCREEN object, which was
freed together with the original part buffer.
This commit is contained in:
Maciej Suminski 2018-01-22 17:46:28 +01:00
parent 6322c90c50
commit 6b9a286a85
2 changed files with 25 additions and 9 deletions

View File

@ -378,14 +378,17 @@ bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAli
wxCHECK( partBuf, false );
LIB_PART* original = new LIB_PART( *partBuf->GetOriginal() );
// Save the screen object, so it is transferred to the new buffer
std::unique_ptr<SCH_SCREEN> screen = partBuf->RemoveScreen();
if( !libBuf.DeleteBuffer( partBuf ) )
return false;
if( !UpdatePart( aPart, aLibrary ))
if( !UpdatePart( aPart, aLibrary ) )
return false;
partBuf = libBuf.GetBuffer( aPart->GetName() );
partBuf->SetScreen( std::move( screen ) );
wxCHECK( partBuf, false );
partBuf->SetOriginal( original ); // part buffer takes ownership of pointer
@ -638,8 +641,8 @@ LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary
}
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
: m_screen( aScreen ), m_part( aPart )
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, std::unique_ptr<SCH_SCREEN> aScreen )
: m_screen( std::move( aScreen ) ), m_part( aPart )
{
m_original = new LIB_PART( *aPart );
}
@ -647,7 +650,6 @@ LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
LIB_MANAGER::PART_BUFFER::~PART_BUFFER()
{
delete m_screen;
delete m_part;
delete m_original;
}
@ -692,7 +694,8 @@ bool LIB_MANAGER::LIB_BUFFER::CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen
{
wxASSERT( m_aliases.count( aCopy->GetName() ) == 0 ); // only for new parts
wxASSERT( aCopy->GetLib() == nullptr );
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, aScreen );
std::unique_ptr<SCH_SCREEN> screen( aScreen );
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, std::move( screen ) );
m_parts.push_back( partBuf );
addAliases( partBuf );

View File

@ -32,12 +32,12 @@
#include <memory>
#include <wx/arrstr.h>
#include <lib_manager_adapter.h>
#include <class_sch_screen.h>
class LIB_ALIAS;
class LIB_PART;
class LIB_BUFFER;
class PART_LIB;
class SCH_SCREEN;
class SCH_PLUGIN;
class LIB_EDIT_FRAME;
class SYMBOL_LIB_TABLE;
@ -289,7 +289,7 @@ private:
class PART_BUFFER
{
public:
PART_BUFFER( LIB_PART* aPart = nullptr, SCH_SCREEN* aScreen = nullptr );
PART_BUFFER( LIB_PART* aPart = nullptr, std::unique_ptr<SCH_SCREEN> aScreen = nullptr );
~PART_BUFFER();
LIB_PART* GetPart() const { return m_part; }
@ -299,13 +299,26 @@ private:
void SetOriginal( LIB_PART* aPart );
bool IsModified() const;
SCH_SCREEN* GetScreen() const { return m_screen; }
SCH_SCREEN* GetScreen() const { return m_screen.get(); }
///> Transfer the screen ownership
std::unique_ptr<SCH_SCREEN> RemoveScreen()
{
return std::move( m_screen );
}
bool SetScreen( std::unique_ptr<SCH_SCREEN> aScreen )
{
bool ret = !!m_screen;
m_screen = std::move( aScreen );
return ret;
}
typedef std::shared_ptr<PART_BUFFER> PTR;
typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
private:
SCH_SCREEN* m_screen;
std::unique_ptr<SCH_SCREEN> m_screen;
///> Working copy
LIB_PART* m_part;