Fix CADSTAR importer memory leaks

We were leaking the xml tree when throwing exceptions
This commit is contained in:
Roberto Fernandez Bautista 2023-02-27 23:55:20 +01:00
parent 766b1a1ca8
commit b03366c9e8
6 changed files with 60 additions and 15 deletions

View File

@ -2428,7 +2428,9 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
const wxString& aFileTypeIdentifier, PROGRESS_REPORTER* aProgressReporter )
{
KEYWORD emptyKeywords[1] = {};
XNODE * iNode = nullptr, *cNode = nullptr;
XNODE* rootNode = nullptr;
XNODE* cNode = nullptr;
XNODE* iNode = nullptr;
int tok;
bool cadstarFileCheckDone = false;
wxString str;
@ -2460,7 +2462,10 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
if( aProgressReporter && ( currentProgress() - previousReportedProgress ) > 0.01 )
{
if( !aProgressReporter->KeepRefreshing() )
{
delete rootNode;
THROW_IO_ERROR( _( "File import cancelled by user." ) );
}
aProgressReporter->SetCurrentProgress( currentProgress() );
previousReportedProgress = currentProgress();
@ -2476,6 +2481,7 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
else
{
//too many closing brackets
delete rootNode;
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
}
}
@ -2485,6 +2491,9 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
str = wxString( lexer.CurText(), *conv );
cNode = new XNODE( wxXML_ELEMENT_NODE, str );
if( !rootNode )
rootNode = cNode;
if( iNode )
{
//we will add it as attribute as well as child node
@ -2494,7 +2503,10 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
else if( !cadstarFileCheckDone )
{
if( cNode->GetName() != aFileTypeIdentifier )
{
delete rootNode;
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
}
cadstarFileCheckDone = true;
}
@ -2510,19 +2522,28 @@ XNODE* CADSTAR_ARCHIVE_PARSER::LoadArchiveFile( const wxString& aFileName,
else
{
//not enough closing brackets
delete rootNode;
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
}
}
// Not enough closing brackets
if( iNode != nullptr )
{
delete rootNode;
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
}
// Throw if no data was parsed
if( cNode )
return cNode;
if( rootNode )
{
return rootNode;
}
else
{
delete rootNode;
THROW_IO_ERROR( _( "The selected file is not valid or might be corrupt!" ) );
}
return nullptr;
}

View File

@ -93,6 +93,8 @@ class CADSTAR_ARCHIVE_PARSER
public:
CADSTAR_ARCHIVE_PARSER() { m_progressReporter = nullptr; }
virtual ~CADSTAR_ARCHIVE_PARSER() {}
typedef wxString LINECODE_ID;
typedef wxString HATCHCODE_ID;

View File

@ -35,7 +35,7 @@ void CADSTAR_SCH_ARCHIVE_PARSER::Parse()
if( m_progressReporter )
m_progressReporter->BeginPhase( 0 ); // Read file
XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARSCM" ), m_progressReporter );
if( m_progressReporter )
{
@ -44,13 +44,13 @@ void CADSTAR_SCH_ARCHIVE_PARSER::Parse()
std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
wxT( "SCHEMATIC" ) };
long numOfSteps = GetNumberOfStepsForReporting( fileRootNode, subNodeChildrenToCount );
long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
m_progressReporter->SetMaxProgress( numOfSteps );
}
m_context.CheckPointCallback = [&](){ checkPoint(); };
XNODE* cNode = fileRootNode->GetChildren();
XNODE* cNode = m_rootNode->GetChildren();
if( !cNode )
THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARSCM" ) );
@ -145,7 +145,8 @@ void CADSTAR_SCH_ARCHIVE_PARSER::Parse()
checkPoint();
}
delete fileRootNode;
delete m_rootNode;
m_rootNode = nullptr;
}

View File

@ -35,11 +35,18 @@
class CADSTAR_SCH_ARCHIVE_PARSER : public CADSTAR_ARCHIVE_PARSER
{
public:
explicit CADSTAR_SCH_ARCHIVE_PARSER( wxString aFilename )
: CADSTAR_ARCHIVE_PARSER(), Filename( aFilename ), Header(), Assignments(), KiCadUnitDivider( 10 )
explicit CADSTAR_SCH_ARCHIVE_PARSER( wxString aFilename ) :
CADSTAR_ARCHIVE_PARSER(), Filename( aFilename ), Header(), Assignments(),
KiCadUnitDivider( 10 ), m_rootNode( nullptr )
{
}
virtual ~CADSTAR_SCH_ARCHIVE_PARSER()
{
if( m_rootNode )
delete m_rootNode;
}
/**
* @brief Parses the file
* @throw IO_ERROR if file could not be opened or there was
@ -454,6 +461,9 @@ public:
int KiCadUnitDivider; ///<Use this value to convert units in this CSA file to KiCad units
private:
XNODE* m_rootNode; // Currently parsed root node
}; //CADSTAR_SCH_ARCHIVE_PARSER
#endif // CADSTAR_SCH_ARCHIVE_PARSER_H_

View File

@ -35,7 +35,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
if( m_progressReporter )
m_progressReporter->BeginPhase( 0 ); // Read file
XNODE* fileRootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ), m_progressReporter );
m_rootNode = LoadArchiveFile( Filename, wxT( "CADSTARPCB" ), m_progressReporter );
if( m_progressReporter )
{
@ -44,13 +44,13 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
std::vector<wxString> subNodeChildrenToCount = { wxT( "LIBRARY" ), wxT( "PARTS" ),
wxT( "LAYOUT" ) };
long numOfSteps = GetNumberOfStepsForReporting( fileRootNode, subNodeChildrenToCount );
long numOfSteps = GetNumberOfStepsForReporting( m_rootNode, subNodeChildrenToCount );
m_progressReporter->SetMaxProgress( numOfSteps );
}
m_context.CheckPointCallback = [&](){ checkPoint(); };
XNODE* cNode = fileRootNode->GetChildren();
XNODE* cNode = m_rootNode->GetChildren();
if( !cNode )
THROW_MISSING_NODE_IO_ERROR( wxT( "HEADER" ), wxT( "CADSTARPCB" ) );
@ -123,7 +123,7 @@ void CADSTAR_PCB_ARCHIVE_PARSER::Parse()
checkPoint();
}
delete fileRootNode;
delete m_rootNode;
}

View File

@ -42,12 +42,20 @@
class CADSTAR_PCB_ARCHIVE_PARSER : public CADSTAR_ARCHIVE_PARSER
{
public:
explicit CADSTAR_PCB_ARCHIVE_PARSER( const wxString& aFilename )
: Filename( aFilename ), Header(), Assignments(), CADSTAR_ARCHIVE_PARSER()
explicit CADSTAR_PCB_ARCHIVE_PARSER( const wxString& aFilename ) :
Filename( aFilename ), Header(), Assignments(),
m_rootNode( nullptr ), CADSTAR_ARCHIVE_PARSER()
{
KiCadUnitMultiplier = 10; // assume hundredth micron
}
virtual ~CADSTAR_PCB_ARCHIVE_PARSER()
{
if( m_rootNode )
delete m_rootNode;
}
/**
* @brief Parses the file
* @throw IO_ERROR if file could not be opened or there was
@ -1215,6 +1223,9 @@ public:
int KiCadUnitMultiplier; ///<Use this value to convert units in this CPA file to KiCad units
private:
XNODE* m_rootNode; // Currently parsed root node
}; //CADSTAR_PCB_ARCHIVE_PARSER
#endif // CADSTAR_PCB_ARCHIVE_PARSER_H_