router: prevent a very unlikely infinite loop in PNS::LINE::Walkaround() causing an OOM&segfault

Fixes: lp:1767587
* https://bugs.launchpad.net/kicad/+bug/1767587
This commit is contained in:
Tomasz Włostowski 2018-05-02 15:05:39 -07:00
parent af739f5b00
commit 2eddf1d8db
4 changed files with 26 additions and 11 deletions

View File

@ -166,7 +166,7 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) ) if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) )
return false; return false;
SHAPE_LINE_CHAIN::INTERSECTIONS ips, ips2; SHAPE_LINE_CHAIN::INTERSECTIONS ips;
line.Intersect( aObstacle, ips ); line.Intersect( aObstacle, ips );
@ -226,6 +226,9 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
int i = i_first; int i = i_first;
if( i_first < 0 || i_last < 0 )
return false;
while( i != i_last ) while( i != i_last )
{ {
aWalk.Append( aObstacle.CPoint( i ) ); aWalk.Append( aObstacle.CPoint( i ) );
@ -249,14 +252,18 @@ bool LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
} }
void LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, SHAPE_LINE_CHAIN& aPath, bool aCw ) const bool LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, SHAPE_LINE_CHAIN& aPath, bool aCw ) const
{ {
SHAPE_LINE_CHAIN walk, post; SHAPE_LINE_CHAIN walk, post;
Walkaround( aObstacle, aPath, walk, post, aCw ); if( ! Walkaround( aObstacle, aPath, walk, post, aCw ) )
return false;
aPath.Append( walk ); aPath.Append( walk );
aPath.Append( post ); aPath.Append( post );
aPath.Simplify(); aPath.Simplify();
return true;
} }

View File

@ -236,7 +236,7 @@ public:
SHAPE_LINE_CHAIN& aPost, SHAPE_LINE_CHAIN& aPost,
bool aCw ) const; bool aCw ) const;
void Walkaround( const SHAPE_LINE_CHAIN& aObstacle, bool Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
SHAPE_LINE_CHAIN& aPath, SHAPE_LINE_CHAIN& aPath,
bool aCw ) const; bool aCw ) const;

View File

@ -135,8 +135,11 @@ SHOVE::SHOVE_STATUS SHOVE::walkaroundLoneVia( LINE& aCurrent, LINE& aObstacle,
const SHAPE_LINE_CHAIN hull = aCurrent.Via().Hull( clearance, aObstacle.Width() ); const SHAPE_LINE_CHAIN hull = aCurrent.Via().Hull( clearance, aObstacle.Width() );
SHAPE_LINE_CHAIN path_cw, path_ccw; SHAPE_LINE_CHAIN path_cw, path_ccw;
aObstacle.Walkaround( hull, path_cw, true ); if( ! aObstacle.Walkaround( hull, path_cw, true ) )
aObstacle.Walkaround( hull, path_ccw, false ); return SH_INCOMPLETE;
if( ! aObstacle.Walkaround( hull, path_ccw, false ) )
return SH_INCOMPLETE;
const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw; const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw;
@ -178,7 +181,9 @@ SHOVE::SHOVE_STATUS SHOVE::processHullSet( LINE& aCurrent, LINE& aObstacle,
{ {
const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i]; const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
l.Walkaround( hull, path, clockwise ); if( ! l.Walkaround( hull, path, clockwise ) )
return SH_INCOMPLETE;
path.Simplify(); path.Simplify();
l.SetShape( path ); l.SetShape( path );
} }

View File

@ -79,10 +79,13 @@ WALKAROUND::WALKAROUND_STATUS WALKAROUND::singleStep( LINE& aPath,
} }
} }
aPath.Walkaround( current_obs->m_hull, path_pre[0], path_walk[0], if( ! aPath.Walkaround( current_obs->m_hull, path_pre[0], path_walk[0],
path_post[0], aWindingDirection ); path_post[0], aWindingDirection ) )
aPath.Walkaround( current_obs->m_hull, path_pre[1], path_walk[1], return STUCK;
path_post[1], !aWindingDirection );
if( ! aPath.Walkaround( current_obs->m_hull, path_pre[1], path_walk[1],
path_post[1], !aWindingDirection ) )
return STUCK;
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration ); m_logger.NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );