pcbnew: Prevent invalid values from loading

Items that are located at the edge of or outside of integer limits will
not be shown on screen as they don't fit in the VIEW RTree.  This
prevents them from being edited and can corrupt data output.  Instead,
we place them at the largest value that is representable on the RTree
(INT_MAX/SQRT(2)).  This allows the user to correctly utilize DRC as
well as interact with and remove the offending items.

Fixes: lp:1815642
* https://bugs.launchpad.net/kicad/+bug/1815642
This commit is contained in:
Seth Hillbrand 2019-02-13 20:27:57 -08:00
parent e6a200b09e
commit 2c61b7d7d6
1 changed files with 16 additions and 2 deletions

View File

@ -233,15 +233,29 @@ class PCB_PARSER : public PCB_LEXER
// to confirm or experiment. Use a similar strategy in both places, here
// and in the test program. Make that program with:
// $ make test-nm-biu-to-ascii-mm-round-tripping
return KiROUND( parseDouble() * IU_PER_MM );
auto retval = parseDouble() * IU_PER_MM;
// N.B. we currently represent board units as integers. Any values that are
// larger or smaller than those board units represent undefined behavior for
// the system. We limit values to the largest that is visible on the screen
// This is the diagonal distance of the full screen ~1.5m
double int_limit = std::numeric_limits<int>::max() * M_SQRT1_2f64;
return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
}
inline int parseBoardUnits( const char* aExpected )
{
auto retval = parseDouble( aExpected ) * IU_PER_MM;
// N.B. we currently represent board units as integers. Any values that are
// larger or smaller than those board units represent undefined behavior for
// the system. We limit values to the largest that is visible on the screen
double int_limit = std::numeric_limits<int>::max() * M_SQRT1_2f64;
// Use here KiROUND, not KIROUND (see comments about them)
// when having a function as argument, because it will be called twice
// with KIROUND
return KiROUND( parseDouble( aExpected ) * IU_PER_MM );
return KiROUND( Clamp<double>( -int_limit, retval, int_limit ) );
}
inline int parseBoardUnits( PCB_KEYS_T::T aToken )