Symbol and footprint library table parser fixes.

Fix potential memory leak in both footprint and symbol library table
parsers when a duplicate library nickname entry exists.

Parse entire symbol library table before raising duplicate nickname
exception.

Improve the duplicate library table nickname error message to make
life easier for users to fix broken tables.
This commit is contained in:
Wayne Stambaugh 2017-07-13 10:04:16 -04:00
parent d5095252a0
commit e01eb29758
2 changed files with 29 additions and 10 deletions

View File

@ -67,7 +67,7 @@ FP_LIB_TABLE::FP_LIB_TABLE( FP_LIB_TABLE* aFallBackTable ) :
void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in ) void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
{ {
T tok; T tok;
wxString errMsg; // to collect error messages wxString errMsg; // to collect error messages
// This table may be nested within a larger s-expression, or not. // This table may be nested within a larger s-expression, or not.
@ -90,6 +90,9 @@ void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
if( tok != T_LEFT ) if( tok != T_LEFT )
in->Expecting( T_LEFT ); in->Expecting( T_LEFT );
// in case there is a "row integrity" error, tell where later.
int lineNum = in->CurLineNumber();
if( ( tok = in->NextTok() ) != T_lib ) if( ( tok = in->NextTok() ) != T_lib )
in->Expecting( T_lib ); in->Expecting( T_lib );
@ -175,11 +178,16 @@ void FP_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
// FindLib() we search this table before any fall back.) // FindLib() we search this table before any fall back.)
wxString nickname = row->GetNickName(); // store it to be able to used it wxString nickname = row->GetNickName(); // store it to be able to used it
// after row deletion if an error occurs // after row deletion if an error occurs
if( !InsertRow( row.release() ) ) LIB_TABLE_ROW* tmp = row.release();
if( !InsertRow( tmp ) )
{ {
delete tmp; // The table did not take ownership of the row.
wxString msg = wxString::Format( wxString msg = wxString::Format(
_( "'%s' is a duplicate footprint library nickName" ), _( "Duplicate library nickname '%s' found in footprint library "
GetChars( nickname ) ); "table file line %d" ), GetChars( nickname ), lineNum );
if( !errMsg.IsEmpty() ) if( !errMsg.IsEmpty() )
errMsg << '\n'; errMsg << '\n';

View File

@ -77,7 +77,8 @@ SYMBOL_LIB_TABLE& SYMBOL_LIB_TABLE::GetGlobalLibTable()
void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in ) void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
{ {
T tok; T tok;
wxString errMsg; // to collect error messages
// This table may be nested within a larger s-expression, or not. // This table may be nested within a larger s-expression, or not.
// Allow for parser of that optional containing s-epression to have looked ahead. // Allow for parser of that optional containing s-epression to have looked ahead.
@ -100,7 +101,6 @@ void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
// in case there is a "row integrity" error, tell where later. // in case there is a "row integrity" error, tell where later.
int lineNum = in->CurLineNumber(); int lineNum = in->CurLineNumber();
int offset = in->CurOffset();
if( ( tok = in->NextTok() ) != T_lib ) if( ( tok = in->NextTok() ) != T_lib )
in->Expecting( T_lib ); in->Expecting( T_lib );
@ -187,14 +187,25 @@ void SYMBOL_LIB_TABLE::Parse( LIB_TABLE_LEXER* in )
// FindLib() we search this table before any fall back.) // FindLib() we search this table before any fall back.)
wxString nickname = row->GetNickName(); // store it to be able to used it wxString nickname = row->GetNickName(); // store it to be able to used it
// after row deletion if an error occurs // after row deletion if an error occurs
if( !InsertRow( row.release() ) ) LIB_TABLE_ROW* tmp = row.release();
if( !InsertRow( tmp ) )
{ {
delete tmp; // The table did not take ownership of the row.
wxString msg = wxString::Format( wxString msg = wxString::Format(
_( "'%s' is a duplicate symbol library nickname" ), _( "Duplicate library nickname '%s' found in symbol library "
GetChars( nickname ) ); "table file line %d" ), GetChars( nickname ), lineNum );
THROW_PARSE_ERROR( msg, in->CurSource(), in->CurLine(), lineNum, offset );
if( !errMsg.IsEmpty() )
errMsg << '\n';
errMsg << msg;
} }
} }
if( !errMsg.IsEmpty() )
THROW_IO_ERROR( errMsg );
} }