Fix crash/hang in DRC zone-zone clearance check
SEG::operator< delegates to VECTOR2I::operator< which compares by squared magnitude. When SEG::operator< mixes this magnitude comparison with VECTOR2I::operator== (exact coordinate equality) for tie-breaking, it violates strict weak ordering: two points at the same magnitude but different coordinates are "incomparable" under operator< but "unequal" under operator==, breaking transitivity of incomparability. Replace the default SEG::operator< sort with a lexicographic comparator on x/y coordinates, which provides a proper strict weak ordering and matches the sweep-line optimization that follows (breaking the inner loop when refSegment.B.x < testSegment.A.x). Also add null checks for polyA/polyB from GetFill() before dereferencing. Fixes https://gitlab.com/kicad/code/kicad/-/issues/23112
This commit is contained in:
@@ -1376,7 +1376,24 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
zone_layer_poly_segs.push_back( seg );
|
||||
}
|
||||
|
||||
std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end() );
|
||||
// Sort by x-coordinates for the sweep-line optimization in the inner
|
||||
// loop. SEG::operator< must not be used here because it delegates to
|
||||
// VECTOR2I::operator< which compares by magnitude, violating strict
|
||||
// weak ordering when mixed with VECTOR2I::operator== for tie-breaking.
|
||||
std::sort( zone_layer_poly_segs.begin(), zone_layer_poly_segs.end(),
|
||||
[]( const SEG& a, const SEG& b ) -> bool
|
||||
{
|
||||
if( a.A.x != b.A.x )
|
||||
return a.A.x < b.A.x;
|
||||
|
||||
if( a.A.y != b.A.y )
|
||||
return a.A.y < b.A.y;
|
||||
|
||||
if( a.B.x != b.B.x )
|
||||
return a.B.x < b.B.x;
|
||||
|
||||
return a.B.y < b.B.y;
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1420,7 +1437,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
polyB = zoneB->GetFill( layer );
|
||||
}
|
||||
|
||||
if( !polyA->BBoxFromCaches().Intersects( polyB->BBoxFromCaches() ) )
|
||||
if( !polyA || !polyB
|
||||
|| !polyA->BBoxFromCaches().Intersects( polyB->BBoxFromCaches() ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
Reference in New Issue
Block a user