Defer template list refresh after duplication to prevent use-after-free
Duplicating a template copies files that trigger OnFileSystemEvent, which starts a 500ms refresh timer. The subsequent DisplayInfoMessage runs a modal event loop during which the timer fires, calling RefreshTemplateList which destroys all TEMPLATE_WIDGETs including the one whose onDuplicateTemplate is still on the call stack. When the modal dialog closes, any further member access is undefined behavior. Defer both the info message and the refresh via CallAfter so they execute after the event handler has returned and the call stack is clean. Fixes https://gitlab.com/kicad/code/kicad/-/issues/22931
This commit is contained in:
@@ -480,10 +480,20 @@ void TEMPLATE_WIDGET::onDuplicateTemplate( wxCommandEvent& event )
|
||||
}
|
||||
}
|
||||
|
||||
DisplayInfoMessage( m_dialog, wxString::Format( _( "Template duplicated successfully to '%s'." ),
|
||||
newTemplatePath ) );
|
||||
// The file copy triggers OnFileSystemEvent which starts a refresh timer. If we show a
|
||||
// modal info dialog here, the timer fires during the modal event loop and destroys this
|
||||
// TEMPLATE_WIDGET while we're still on its call stack. Defer both the message and the
|
||||
// refresh to run after the current event handler returns.
|
||||
DIALOG_TEMPLATE_SELECTOR* dlg = m_dialog;
|
||||
|
||||
m_dialog->RefreshTemplateList();
|
||||
dlg->CallAfter(
|
||||
[dlg, newTemplatePath]()
|
||||
{
|
||||
DisplayInfoMessage( dlg, wxString::Format( _( "Template duplicated successfully"
|
||||
" to '%s'." ),
|
||||
newTemplatePath ) );
|
||||
dlg->RefreshTemplateList();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user