Fix crash in Altium schematic importer.

The crash was caused by an unhandled exception. The uncaught exception
caused a cacophony of null configuration setting pointers so guards were
added to prevent crashes should other exceptions occur that do not get
handled correctly.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13046
This commit is contained in:
Wayne Stambaugh 2022-12-05 20:18:05 -05:00
parent d0024bd9f7
commit 5001555f0e
5 changed files with 64 additions and 3 deletions

View File

@ -762,6 +762,8 @@ void EDA_BASE_FRAME::LoadSettings( APP_SETTINGS_BASE* aCfg )
void EDA_BASE_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
{
wxCHECK( config(), /* void */ );
SaveWindowSettings( GetWindowSettings( aCfg ) );
bool fileOpen = m_isClosing && m_isNonUserClose;

View File

@ -354,6 +354,8 @@ void EDA_DRAW_FRAME::UpdateGridSelectBox()
m_gridSelectBox->Clear();
wxArrayString gridsList;
wxCHECK( config(), /* void */ );
GRID_MENU::BuildChoiceList( &gridsList, config(), this );
for( const wxString& grid : gridsList )
@ -373,6 +375,8 @@ void EDA_DRAW_FRAME::OnUpdateSelectGrid( wxUpdateUIEvent& aEvent )
if( m_gridSelectBox == nullptr )
return;
wxCHECK( config(), /* void */ );
int idx = config()->m_Window.grid.last_size_idx;
idx = std::max( 0, std::min( idx, (int) m_gridSelectBox->GetCount() - 1 ) );
@ -390,6 +394,9 @@ void EDA_DRAW_FRAME::OnUpdateSelectZoom( wxUpdateUIEvent& aEvent )
return;
double zoom = GetCanvas()->GetGAL()->GetZoomFactor();
wxCHECK( config(), /* void */ );
const std::vector<double>& zoomList = config()->m_Window.zoom_factors;
int curr_selection = m_zoomSelectBox->GetSelection();
int new_selection = 0; // select zoom auto
@ -471,12 +478,16 @@ void EDA_DRAW_FRAME::OnGridSettings( wxCommandEvent& aEvent )
bool EDA_DRAW_FRAME::IsGridVisible() const
{
wxCHECK( config(), true );
return config()->m_Window.grid.show;
}
void EDA_DRAW_FRAME::SetGridVisibility( bool aVisible )
{
wxCHECK( config(), /* void */ );
config()->m_Window.grid.show = aVisible;
// Update the display with the new grid
@ -506,6 +517,8 @@ void EDA_DRAW_FRAME::UpdateZoomSelectBox()
m_zoomSelectBox->Append( _( "Zoom Auto" ) );
m_zoomSelectBox->SetSelection( 0 );
wxCHECK( config(), /* void */ );
for( unsigned i = 0; i < config()->m_Window.zoom_factors.size(); ++i )
{
double current = config()->m_Window.zoom_factors[i];

View File

@ -1276,6 +1276,20 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
return false;
}
catch( const std::exception& exc )
{
CreateScreens();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
wxString msg = wxString::Format( _( "Unhandled excpetion occurred loading schematic "
"'%s'." ), aFileName );
DisplayErrorMessage( this, msg, exc.what() );
msg.Printf( _( "Failed to load '%s'." ), aFileName );
SetMsgPanel( wxEmptyString, msg );
return false;
}
return true;

View File

@ -342,10 +342,15 @@ void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName )
// Parse "Additional" because sheet is set up during "FileHeader" parsing.
ParseAdditional( altiumSchFile );
}
catch( CFB::CFBException& exception )
catch( const CFB::CFBException& exception )
{
THROW_IO_ERROR( exception.what() );
}
catch( const std::exception& exc )
{
wxLogDebug( wxT( "Unhandled exception in Altium schematic parsers: %s." ), exc.what() );
throw;
}
SCH_SCREEN* currentScreen = getCurrentScreen();
wxCHECK( currentScreen, /* void */ );
@ -362,6 +367,17 @@ void SCH_ALTIUM_PLUGIN::ParseAltiumSch( const wxString& aFileName )
// path as the parent sheet path.
wxFileName loadAltiumFileName( parentFileName.GetPath(), sheet->GetFileName() );
if( loadAltiumFileName.GetFullName().IsEmpty() || !loadAltiumFileName.IsFileReadable() )
{
wxString msg;
msg.Printf( _( "The file name for sheet %s is undefined, this is probably an"
"Altium signal harness that got converted to a sheet." ),
sheet->GetName() );
m_reporter->Report( msg );
continue;
}
m_rootSheet->SearchHierarchy( loadAltiumFileName.GetFullPath(), &loadedScreen );
if( loadedScreen )
@ -1548,7 +1564,7 @@ void SCH_ALTIUM_PLUGIN::ParseRoundRectangle( const std::map<wxString, wxString>&
void SCH_ALTIUM_PLUGIN::ParseArc( const std::map<wxString, wxString>& aProperties )
{
// The Arc can be ALTIUM_SCH_RECORD::ELLIPTICAL_ARC or ALTIUM_SCH_RECORD::ARC
// Elliptical arcs are not handled in kicad. So use an arc instead
// Elliptical arcs are not handled in KiCad. So use an arc instead
// TODO: handle elliptical arc better.
ASCH_ARC elem( aProperties );
@ -1558,7 +1574,7 @@ void SCH_ALTIUM_PLUGIN::ParseArc( const std::map<wxString, wxString>& aPropertie
int arc_radius = elem.m_Radius;
// Try to approxiammate this ellipse by an arc. use the biggest of radius and secondary radius
// Try to approximate this ellipse by an arc. use the biggest of radius and secondary radius
// One can of course use another recipe
if( elem.m_IsElliptical )
arc_radius = std::max( elem.m_Radius, elem.m_SecondaryRadius );
@ -1803,6 +1819,7 @@ void SCH_ALTIUM_PLUGIN::ParseHarnessConnector( int aIndex, const std::map<wxStri
SCH_SHEET* sheet = new SCH_SHEET( getCurrentSheet(), elem.Location + m_sheetOffset,
elem.Size );
sheet->SetScreen( new SCH_SCREEN( m_schematic ) );
sheet->SetBackgroundColor( GetColorFromInt( elem.AreaColor ) );
sheet->SetBorderColor( GetColorFromInt( elem.Color ) );
@ -1901,6 +1918,19 @@ void SCH_ALTIUM_PLUGIN::ParseHarnessType( const std::map<wxString, wxString>& aP
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
sheetNameField.SetTextColor( GetColorFromInt( elem.Color ) );
SCH_FIELD& sheetFileName = sheetIt->second->GetFields()[SHEETFILENAME];
sheetFileName.SetText( elem.Text + wxT( "." ) + KiCadSchematicFileExtension );
wxFileName fn( m_schematic->Prj().GetProjectPath(), elem.Text, KiCadSchematicFileExtension );
wxString fullPath = fn.GetFullPath();
fullPath.Replace( wxT( "\\" ), wxT( "/" ) );
SCH_SCREEN* screen = sheetIt->second->GetScreen();
wxCHECK( screen, /* void */ );
screen->SetFileName( fullPath );
m_reporter->Report( wxString::Format( _( "Altium's harness connector (%s) was imported as a "
"hierarchical sheet. Please review the imported "
"schematic." ),

View File

@ -48,5 +48,7 @@ SELECTION_CONDITION SCH_EDITOR_CONDITIONS::LineMode( LINE_MODE aMode )
bool SCH_EDITOR_CONDITIONS::lineModeFunc( const SELECTION& aSelection, SCH_BASE_FRAME* aFrame,
LINE_MODE aMode )
{
wxCHECK( aFrame && aFrame->eeconfig(), false );
return aFrame->eeconfig()->m_Drawing.line_mode == aMode;
}