Browse Source

Fix crash on net highlighting

When navigating to a sheet without the highlighted net, there was a
chance for an uninitialized pointer deref.  This also gathers the
highlighted nets into the navigator as well as their subsuming buses

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18419
pcb_db
Seth Hillbrand 10 months ago
parent
commit
6e09649a70
  1. 4
      eeschema/connection_graph.cpp
  2. 2
      eeschema/connection_graph.h
  3. 40
      eeschema/net_navigator.cpp
  4. 40
      eeschema/tools/sch_editor_control.cpp

4
eeschema/connection_graph.cpp

@ -3111,10 +3111,10 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem ) con
}
const std::vector<CONNECTION_SUBGRAPH*>
const std::vector<CONNECTION_SUBGRAPH*>&
CONNECTION_GRAPH::GetAllSubgraphs( const wxString& aNetName ) const
{
std::vector<CONNECTION_SUBGRAPH*> subgraphs;
static const std::vector<CONNECTION_SUBGRAPH*> subgraphs;
auto it = m_net_name_to_subgraphs_map.find( aNetName );

2
eeschema/connection_graph.h

@ -441,7 +441,7 @@ public:
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem ) const;
const std::vector<CONNECTION_SUBGRAPH*> GetAllSubgraphs( const wxString& aNetName ) const;
const std::vector<CONNECTION_SUBGRAPH*>& GetAllSubgraphs( const wxString& aNetName ) const;
/**
* Return the fully-resolved netname for a given subgraph.

40
eeschema/net_navigator.cpp

@ -205,8 +205,27 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
wxCHECK( connectionGraph, /* void */ );
wxString sheetPathPrefix;
const std::vector<CONNECTION_SUBGRAPH*> subgraphs =
connectionGraph->GetAllSubgraphs( aNetName );
std::set<CONNECTION_SUBGRAPH*> subgraphs;
{
const std::vector<CONNECTION_SUBGRAPH*>& tmp = connectionGraph->GetAllSubgraphs( aNetName );
subgraphs.insert( tmp.begin(), tmp.end() );
}
for( CONNECTION_SUBGRAPH* sg : subgraphs )
{
for( const auto& [_, bus_sgs] : sg->GetBusParents() )
{
for( const CONNECTION_SUBGRAPH* bus_sg : bus_sgs )
{
const std::vector<CONNECTION_SUBGRAPH*>& tmp =
connectionGraph->GetAllSubgraphs( bus_sg->GetNetName() );
subgraphs.insert( tmp.begin(), tmp.end() );
}
}
}
std::map<wxString, wxTreeItemId> sheetIds;
for( const CONNECTION_SUBGRAPH* subGraph : subgraphs )
{
@ -222,7 +241,18 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
bool stripTrailingSeparator = !sheetPath.Last()->IsRootSheet();
wxString txt = sheetPath.PathHumanReadable( true, stripTrailingSeparator );
wxTreeItemId sheetId = m_netNavigator->AppendItem( aParentId, txt, -1, -1, itemData );
wxTreeItemId sheetId;
if( auto sheetIdIt = sheetIds.find( txt ); sheetIdIt != sheetIds.end() )
{
sheetId = sheetIdIt->second;
}
else
{
sheetIds[txt] = m_netNavigator->AppendItem( aParentId, txt, -1, -1, itemData );
sheetId = sheetIds[txt];
}
if( aSelection && *aSelection == *itemData )
m_netNavigator->SelectItem( sheetId );
@ -252,8 +282,12 @@ void SCH_EDIT_FRAME::MakeNetNavigatorNode( const wxString& aNetName, wxTreeItemI
m_netNavigator->SelectItem( id );
}
}
m_netNavigator->SortChildren( sheetId );
}
// Sort the items in the tree control alphabetically
m_netNavigator->SortChildren( aParentId );
m_netNavigator->Expand( aParentId );
}

40
eeschema/tools/sch_editor_control.cpp

@ -1088,39 +1088,41 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
{
connNames.emplace( selectedName );
CONNECTION_SUBGRAPH* sg = connectionGraph->FindSubgraphByName( selectedName, sheetPath );
if( sg && m_highlightBusMembers )
if( CONNECTION_SUBGRAPH* sg =
connectionGraph->FindSubgraphByName( selectedName, sheetPath ) )
{
for( const SCH_ITEM* item : sg->GetItems() )
if( m_highlightBusMembers )
{
wxCHECK2( item, continue );
if( SCH_CONNECTION* connection = item->Connection() )
for( const SCH_ITEM* item : sg->GetItems() )
{
for( const std::shared_ptr<SCH_CONNECTION>& member : connection->AllMembers() )
wxCHECK2( item, continue );
if( SCH_CONNECTION* connection = item->Connection() )
{
if( member )
connNames.emplace( member->Name() );
for( const std::shared_ptr<SCH_CONNECTION>& member :
connection->AllMembers() )
{
if( member )
connNames.emplace( member->Name() );
}
}
}
}
}
// Highlight the buses that contain the selected net
for( const auto& [_, bus_sgs] : sg->GetBusParents() )
// Place all bus names that are connected to the selected net in the set, regardless of
// their sheet. This ensures that nets that are connected to a bus on a different sheet
// get their buses highlighted as well.
for( CONNECTION_SUBGRAPH* sg : connectionGraph->GetAllSubgraphs( selectedName ) )
{
for( const CONNECTION_SUBGRAPH* bus_sg : bus_sgs )
for( const auto& [_, bus_sgs] : sg->GetBusParents() )
{
for( const SCH_ITEM* item : bus_sg->GetItems() )
for( CONNECTION_SUBGRAPH* bus_sg : bus_sgs )
{
if( !item || !item->IsType( { SCH_ITEM_LOCATE_BUS_T } ) )
continue;
if( SCH_CONNECTION* connection = item->Connection() )
connNames.emplace( connection->Name() );
connNames.emplace( bus_sg->GetNetName() );
}
}
}
}

Loading…
Cancel
Save