From 0751a3ae7f2a78f0331f94146c0bbf496a9d1f6a Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 26 Nov 2023 16:43:06 -0500 Subject: [PATCH] Prevent some issues with recursion on repeat-last-item Fixes https://gitlab.com/kicad/code/kicad/-/issues/16168 (cherry picked from commit 90a61b8d3687154b9ac1277f92d936463958d41b) --- eeschema/sch_sheet_path.cpp | 5 +++++ eeschema/tools/sch_edit_tool.cpp | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/eeschema/sch_sheet_path.cpp b/eeschema/sch_sheet_path.cpp index bf60ee3c10..0a99f22085 100644 --- a/eeschema/sch_sheet_path.cpp +++ b/eeschema/sch_sheet_path.cpp @@ -698,6 +698,11 @@ void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet, bool aCheckIntegrity ) } else { + // If we are not performing a full recursion test, at least check if we are in + // a simple recursion scenario to prevent stack overflow crashes + wxCHECK2_MSG( sheet->GetFileName() != aSheet->GetFileName(), continue, + wxT( "Recursion prevented in SCH_SHEET_LIST::BuildSheetList" ) ); + BuildSheetList( sheet, false ); } } diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index 5bc2fd8898..eb33787aa2 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -1119,7 +1119,28 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent ) schIUScale.MilsToIU( cfg->m_Drawing.default_repeat_offset_y ) ) ); } + // If cloning a sheet, check that we aren't going to create recursion + if( newItem->Type() == SCH_SHEET_T ) + { + SCH_SHEET_PATH* currentSheet = &m_frame->GetCurrentSheet(); + SCH_SHEET* sheet = static_cast( newItem ); + + if( m_frame->CheckSheetForRecursion( sheet, currentSheet ) ) + { + // Clear out the filename so that the user can pick a new one + sheet->SetFileName( wxEmptyString ); + + if( !m_frame->EditSheetProperties( sheet, currentSheet, nullptr ) ) + { + // User canceled renaming the sheet; skip it + delete newItem; + continue; + } + } + } + m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem ); + newItem->SetFlags( IS_NEW ); m_frame->AddToScreen( newItem, m_frame->GetScreen() ); m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, appendUndo );