From 9bc3028eb73bc473721746ce24ed11db796435dc Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Fri, 7 Aug 2020 13:37:00 -0700 Subject: [PATCH] pcbnew: Prevent use of non-connected item in ratsnest We need to be careful in the connectivity system to always use dyn_cast/dynamic_cast and check the return when dealing with board items. Getting non-connected items will result in null nets when propagated. Fixes https://gitlab.com/kicad/code/kicad/issues/5082 (cherry picked from commit 406de569644c86036e3c0d80bf15c173e890a3d0) --- pcbnew/connectivity/connectivity_algo.cpp | 25 ++++++++++++++--------- pcbnew/connectivity/connectivity_data.cpp | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 9e7135f825..354acce95e 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -39,6 +39,11 @@ bool CN_CONNECTIVITY_ALGO::Remove( BOARD_ITEM* aItem ) { + BOARD_CONNECTED_ITEM* citem = dyn_cast( aItem ); + + if( !citem ) + return false; + markItemNetAsDirty( aItem ); switch( aItem->Type() ) @@ -46,35 +51,35 @@ bool CN_CONNECTIVITY_ALGO::Remove( BOARD_ITEM* aItem ) case PCB_MODULE_T: for( auto pad : static_cast( aItem ) -> Pads() ) { - m_itemMap[ static_cast( pad ) ].MarkItemsAsInvalid(); - m_itemMap.erase( static_cast( pad ) ); + m_itemMap[pad].MarkItemsAsInvalid(); + m_itemMap.erase( pad ); } m_itemList.SetDirty( true ); break; case PCB_PAD_T: - m_itemMap[ static_cast( aItem ) ].MarkItemsAsInvalid(); - m_itemMap.erase( static_cast( aItem ) ); + m_itemMap[citem].MarkItemsAsInvalid(); + m_itemMap.erase( citem ); m_itemList.SetDirty( true ); break; case PCB_TRACE_T: - m_itemMap[ static_cast( aItem ) ].MarkItemsAsInvalid(); - m_itemMap.erase( static_cast( aItem ) ); + m_itemMap[citem].MarkItemsAsInvalid(); + m_itemMap.erase( citem ); m_itemList.SetDirty( true ); break; case PCB_VIA_T: - m_itemMap[ static_cast( aItem ) ].MarkItemsAsInvalid(); - m_itemMap.erase( static_cast( aItem ) ); + m_itemMap[citem].MarkItemsAsInvalid(); + m_itemMap.erase( citem ); m_itemList.SetDirty( true ); break; case PCB_ZONE_AREA_T: { - m_itemMap[ static_cast( aItem ) ].MarkItemsAsInvalid(); - m_itemMap.erase ( static_cast( aItem ) ); + m_itemMap[citem].MarkItemsAsInvalid(); + m_itemMap.erase ( citem ); m_itemList.SetDirty( true ); break; } diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index a262093eee..0f3d8af123 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -206,7 +206,8 @@ void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector& aIte } else { - citems.push_back( static_cast(item) ); + if( auto citem = dynamic_cast( item ) ) + citems.push_back( citem ); } }