Overflow safety.
Potential fix for some or all of
https://gitlab.com/kicad/code/kicad/-/issues/13969
(cherry picked from commit 2f2a00c307
)
This commit is contained in:
parent
adc7a3ba4a
commit
1bb6b7acdd
|
@ -99,8 +99,19 @@ public:
|
|||
template <typename CastingType>
|
||||
VECTOR2( const VECTOR2<CastingType>& aVec )
|
||||
{
|
||||
x = (T) aVec.x;
|
||||
y = (T) aVec.y;
|
||||
if( std::is_same<T, int>::value )
|
||||
{
|
||||
CastingType minI = static_cast<CastingType>( std::numeric_limits<int>::min() );
|
||||
CastingType maxI = static_cast<CastingType>( std::numeric_limits<int>::max() );
|
||||
|
||||
x = static_cast<int>( std::max( minI, std::min( aVec.x, maxI ) ) );
|
||||
y = static_cast<int>( std::max( minI, std::min( aVec.y, maxI ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
x = static_cast<T>( aVec.x );
|
||||
y = static_cast<T>( aVec.y );
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy a vector
|
||||
|
@ -114,7 +125,18 @@ public:
|
|||
template <typename CastedType>
|
||||
VECTOR2<CastedType> operator()() const
|
||||
{
|
||||
return VECTOR2<CastedType>( (CastedType) x, (CastedType) y );
|
||||
if( std::is_same<CastedType, int>::value )
|
||||
{
|
||||
T minI = static_cast<T>( std::numeric_limits<int>::min() );
|
||||
T maxI = static_cast<T>( std::numeric_limits<int>::max() );
|
||||
|
||||
return VECTOR2<int>( static_cast<int>( std::max( minI, std::min( x, maxI ) ) ),
|
||||
static_cast<int>( std::max( minI, std::min( y, maxI ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return VECTOR2<CastedType>( static_cast<CastedType>( x ), static_cast<CastedType>( y ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -171,8 +171,16 @@ bool SEG::intersects( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines, VECTO
|
|||
|
||||
if( aPt )
|
||||
{
|
||||
*aPt = VECTOR2I( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
|
||||
aSeg.A.y + rescale( q, (ecoord) f.y, d ) );
|
||||
VECTOR2<ecoord> result( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
|
||||
aSeg.A.y + rescale( q, (ecoord) f.y, d ) );
|
||||
|
||||
if( abs( result.x ) >= std::numeric_limits<VECTOR2I::coord_type>::max()
|
||||
|| abs( result.y ) >= std::numeric_limits<VECTOR2I::coord_type>::max() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*aPt = VECTOR2I( (int) result.x, (int) result.y );
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -273,10 +281,10 @@ const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
|||
else if( t > l_squared )
|
||||
return B;
|
||||
|
||||
int xp = rescale( t, (ecoord) d.x, l_squared );
|
||||
int yp = rescale( t, (ecoord) d.y, l_squared );
|
||||
ecoord xp = rescale( t, (ecoord) d.x, l_squared );
|
||||
ecoord yp = rescale( t, (ecoord) d.y, l_squared );
|
||||
|
||||
return A + VECTOR2I( xp, yp );
|
||||
return VECTOR2<ecoord>( A.x + xp, A.y + yp );
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,17 +293,19 @@ const VECTOR2I SEG::ReflectPoint( const VECTOR2I& aP ) const
|
|||
VECTOR2I d = B - A;
|
||||
VECTOR2I::extended_type l_squared = d.Dot( d );
|
||||
VECTOR2I::extended_type t = d.Dot( aP - A );
|
||||
VECTOR2I c;
|
||||
VECTOR2<ecoord> c;
|
||||
|
||||
if( !l_squared )
|
||||
{
|
||||
c = aP;
|
||||
}
|
||||
else
|
||||
{
|
||||
c.x = A.x + rescale( t, static_cast<VECTOR2I::extended_type>( d.x ), l_squared );
|
||||
c.y = A.y + rescale( t, static_cast<VECTOR2I::extended_type>( d.y ), l_squared );
|
||||
}
|
||||
|
||||
return 2 * c - aP;
|
||||
return VECTOR2<ecoord>( 2 * c.x - aP.x, 2 * c.y - aP.y );
|
||||
}
|
||||
|
||||
|
||||
|
@ -309,10 +319,10 @@ VECTOR2I SEG::LineProject( const VECTOR2I& aP ) const
|
|||
|
||||
ecoord t = d.Dot( aP - A );
|
||||
|
||||
int xp = rescale( t, ecoord{ d.x }, l_squared );
|
||||
int yp = rescale( t, ecoord{ d.y }, l_squared );
|
||||
ecoord xp = rescale( t, ecoord{ d.x }, l_squared );
|
||||
ecoord yp = rescale( t, ecoord{ d.y }, l_squared );
|
||||
|
||||
return A + VECTOR2I( xp, yp );
|
||||
return VECTOR2<ecoord>( A.x + xp, A.y + yp );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue