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>
|
template <typename CastingType>
|
||||||
VECTOR2( const VECTOR2<CastingType>& aVec )
|
VECTOR2( const VECTOR2<CastingType>& aVec )
|
||||||
{
|
{
|
||||||
x = (T) aVec.x;
|
if( std::is_same<T, int>::value )
|
||||||
y = (T) aVec.y;
|
{
|
||||||
|
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
|
/// Copy a vector
|
||||||
|
@ -114,7 +125,18 @@ public:
|
||||||
template <typename CastedType>
|
template <typename CastedType>
|
||||||
VECTOR2<CastedType> operator()() const
|
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 )
|
if( aPt )
|
||||||
{
|
{
|
||||||
*aPt = VECTOR2I( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
|
VECTOR2<ecoord> result( aSeg.A.x + rescale( q, (ecoord) f.x, d ),
|
||||||
aSeg.A.y + rescale( q, (ecoord) f.y, 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;
|
return true;
|
||||||
|
@ -273,10 +281,10 @@ const VECTOR2I SEG::NearestPoint( const VECTOR2I& aP ) const
|
||||||
else if( t > l_squared )
|
else if( t > l_squared )
|
||||||
return B;
|
return B;
|
||||||
|
|
||||||
int xp = rescale( t, (ecoord) d.x, l_squared );
|
ecoord xp = rescale( t, (ecoord) d.x, l_squared );
|
||||||
int yp = rescale( t, (ecoord) d.y, 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 d = B - A;
|
||||||
VECTOR2I::extended_type l_squared = d.Dot( d );
|
VECTOR2I::extended_type l_squared = d.Dot( d );
|
||||||
VECTOR2I::extended_type t = d.Dot( aP - A );
|
VECTOR2I::extended_type t = d.Dot( aP - A );
|
||||||
VECTOR2I c;
|
VECTOR2<ecoord> c;
|
||||||
|
|
||||||
if( !l_squared )
|
if( !l_squared )
|
||||||
|
{
|
||||||
c = aP;
|
c = aP;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.x = A.x + rescale( t, static_cast<VECTOR2I::extended_type>( d.x ), l_squared );
|
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 );
|
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 );
|
ecoord t = d.Dot( aP - A );
|
||||||
|
|
||||||
int xp = rescale( t, ecoord{ d.x }, l_squared );
|
ecoord xp = rescale( t, ecoord{ d.x }, l_squared );
|
||||||
int yp = rescale( t, ecoord{ d.y }, 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