router: fixed use-after-free error occuring when a newly routed segment covered exactly an older one

Fixes: lp:1747973
* https://bugs.launchpad.net/kicad/+bug/1747973
This commit is contained in:
Tomasz Włostowski 2018-02-08 11:32:13 +01:00
parent 835fc22892
commit c0b61c19b7
3 changed files with 15 additions and 9 deletions

View File

@ -1006,22 +1006,25 @@ bool LINE_PLACER::FixRoute( const VECTOR2I& aP, ITEM* aEndItem )
else else
lastV = std::max( 1, l.SegmentCount() - 1 ); lastV = std::max( 1, l.SegmentCount() - 1 );
SEGMENT* lastSeg = NULL; SEGMENT* lastSeg = nullptr;
for( int i = 0; i < lastV; i++ ) for( int i = 0; i < lastV; i++ )
{ {
const SEG& s = pl.CSegment( i ); const SEG& s = pl.CSegment( i );
std::unique_ptr< SEGMENT > seg( new SEGMENT( s, m_currentNet ) ); lastSeg = new SEGMENT( s, m_currentNet );
std::unique_ptr< SEGMENT > seg( lastSeg );
seg->SetWidth( pl.Width() ); seg->SetWidth( pl.Width() );
seg->SetLayer( m_currentLayer ); seg->SetLayer( m_currentLayer );
lastSeg = seg.get(); if( ! m_lastNode->Add( std::move( seg ) ) )
m_lastNode->Add( std::move( seg ) ); {
lastSeg = nullptr;
}
} }
if( pl.EndsWithVia() ) if( pl.EndsWithVia() )
m_lastNode->Add( Clone( pl.Via() ) ); m_lastNode->Add( Clone( pl.Via() ) );
if( realEnd ) if( realEnd && lastSeg )
simplifyNewLine( m_lastNode, lastSeg ); simplifyNewLine( m_lastNode, lastSeg );
Router()->CommitRouting( m_lastNode ); Router()->CommitRouting( m_lastNode );

View File

@ -591,19 +591,21 @@ void NODE::addSegment( SEGMENT* aSeg )
m_index->Add( aSeg ); m_index->Add( aSeg );
} }
void NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant ) bool NODE::Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant )
{ {
if( aSegment->Seg().A == aSegment->Seg().B ) if( aSegment->Seg().A == aSegment->Seg().B )
{ {
wxLogTrace( "PNS", "attempting to add a segment with same end coordinates, ignoring." ); wxLogTrace( "PNS", "attempting to add a segment with same end coordinates, ignoring." );
return; return false;
} }
if( !aAllowRedundant && findRedundantSegment( aSegment.get() ) ) if( !aAllowRedundant && findRedundantSegment( aSegment.get() ) )
return; return false;
aSegment->SetOwner( this ); aSegment->SetOwner( this );
addSegment( aSegment.release() ); addSegment( aSegment.release() );
return true;
} }
void NODE::Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant ) void NODE::Add( std::unique_ptr< ITEM > aItem, bool aAllowRedundant )

View File

@ -272,9 +272,10 @@ public:
* Adds an item to the current node. * Adds an item to the current node.
* @param aSegment item to add * @param aSegment item to add
* @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via * @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via
* @return true if added
* at the same coordinates as an existing one) * at the same coordinates as an existing one)
*/ */
void Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant = false ); bool Add( std::unique_ptr< SEGMENT > aSegment, bool aAllowRedundant = false );
void Add( std::unique_ptr< SOLID > aSolid ); void Add( std::unique_ptr< SOLID > aSolid );
void Add( std::unique_ptr< VIA > aVia ); void Add( std::unique_ptr< VIA > aVia );