From a5b676fa0ecd7dcfc2d9ecc15d2e2d1dd5d2ca7a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 24 Jul 2022 19:42:50 +0200 Subject: [PATCH] Avoid crashes when, for some reason, a dll cannot be loaded. In this case a null pointer was returned by the internal code. This pointer is now tested against nullptr to avoid the application crashing. Fixes #12080 https://gitlab.com/kicad/code/kicad/issues/12080 --- eeschema/sch_edit_frame.cpp | 18 ++++++++++++++++++ pcbnew/pcb_edit_frame.cpp | 23 ++++++++++++++++++----- pcbnew/pcb_edit_frame.h | 6 ++++-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/eeschema/sch_edit_frame.cpp b/eeschema/sch_edit_frame.cpp index 5c3670cfb1..dc69bba3f7 100644 --- a/eeschema/sch_edit_frame.cpp +++ b/eeschema/sch_edit_frame.cpp @@ -869,6 +869,12 @@ void SCH_EDIT_FRAME::OnUpdatePCB( wxCommandEvent& event ) fn.SetExt( PcbFileExtension ); frame = Kiway().Player( FRAME_PCB_EDITOR, true ); + + // If Kiway() cannot create the Pcbnew frame, it shows a error message, and + // frame is null + if( !frame ) + return; + frame->OpenProjectFiles( std::vector( 1, fn.GetFullPath() ) ); } @@ -1043,6 +1049,12 @@ void SCH_EDIT_FRAME::OnOpenPcbnew( wxCommandEvent& event ) if( !frame ) { frame = Kiway().Player( FRAME_PCB_EDITOR, true ); + + // frame can be null if Cvpcb cannot be run. No need to show a warning + // Kiway() generates the error messages + if( !frame ) + return; + frame->OpenProjectFiles( std::vector( 1, boardfn.GetFullPath() ) ); } @@ -1080,6 +1092,12 @@ void SCH_EDIT_FRAME::OnOpenCvpcb( wxCommandEvent& event ) if( !player ) { player = Kiway().Player( FRAME_CVPCB, true ); + + // player can be null if Cvpcb cannot be run. No need to show a warning + // Kiway() generates the error messages + if( !player ) + return; + player->Show( true ); } diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index 857284de02..7aa98d2553 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -1463,15 +1463,20 @@ void PCB_EDIT_FRAME::ToPlotter( int aID ) } -bool PCB_EDIT_FRAME::TestStandalone() +int PCB_EDIT_FRAME::TestStandalone() { if( Kiface().IsSingle() ) - return false; + return 0; // Update PCB requires a netlist. Therefore the schematic editor must be running // If this is not the case, open the schematic editor KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH, true ); + // If Kiway() cannot create the eeschema frame, it shows a error message, and + // frame is null + if( !frame ) + return -1; + if( !frame->IsShown() ) { wxFileName fn( Prj().GetProjectPath(), Prj().GetProjectName(), @@ -1486,7 +1491,7 @@ bool PCB_EDIT_FRAME::TestStandalone() if( !fn.FileExists() ) { DisplayError( this, _( "The schematic for this board cannot be found." ) ); - return false; + return -2; } } @@ -1500,14 +1505,14 @@ bool PCB_EDIT_FRAME::TestStandalone() Raise(); } - return true; //Success! + return 1; //Success! } bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, const wxString& aAnnotateMessage ) { - if( !TestStandalone() ) + if( TestStandalone() == 0 ) { DisplayErrorMessage( this, _( "Cannot update the PCB because PCB editor is opened in " "stand-alone mode. In order to create or update PCBs from " @@ -1516,6 +1521,9 @@ bool PCB_EDIT_FRAME::FetchNetlistFromSchematic( NETLIST& aNetlist, return false; // Not in standalone mode } + if( TestStandalone() < 0 ) // Problem with Eeschema or the schematic + return false; + Raise(); // Show std::string payload( aAnnotateMessage ); @@ -1605,6 +1613,11 @@ void PCB_EDIT_FRAME::RunEeschema() } } + // If Kiway() cannot create the eeschema frame, it shows a error message, and + // frame is null + if( !frame ) + return; + if( !frame->IsShown() ) // the frame exists, (created by the dialog field editor) // but no project loaded. { diff --git a/pcbnew/pcb_edit_frame.h b/pcbnew/pcb_edit_frame.h index 3ac8e11e0c..08df3a4448 100644 --- a/pcbnew/pcb_edit_frame.h +++ b/pcbnew/pcb_edit_frame.h @@ -592,9 +592,11 @@ public: /** * Test if standalone mode. * - * @return true if in standalone, opens Eeschema, and opens the schematic for this project + * @return 0 if in standalone, -1 if Eeschema cannot be opened, + * -2 if the schematic cannot be opened and 1 if OK. + * If OK, opens Eeschema, and opens the schematic for this project */ - bool TestStandalone( void ); + int TestStandalone( void ); /** * Read a netlist from a file into a #NETLIST object.