# HG changeset patch # User Jaroslav Hajek # Date 1223445706 -7200 # Node ID 5fd507839b76cab52aaf9771f84e3cf9ec0ce440 # Parent 9a0a66f650b179c6af41998e18dd2362cc6bc419 remove the int->real conversion code vulnerability to compiler optimization diff -r 9a0a66f650b1 -r 5fd507839b76 liboctave/ChangeLog --- a/liboctave/ChangeLog Tue Oct 07 15:49:03 2008 +0200 +++ b/liboctave/ChangeLog Wed Oct 08 08:01:46 2008 +0200 @@ -1,3 +1,10 @@ +2008-10-08 Jaroslav Hajek + + * oct-inttypes.h (octave_base_int::compute_threshold): Return + exclusive bounds rather than inclusive, be resistant to compiler + optimizations. + (octave_base_int::convert_real): Use exclusive bounds. + 2008-10-07 Jaroslav Hajek * oct-inttypes.h (OCTAVE_INT_DOUBLE_BIN_OP): Change octave_int64 to diff -r 9a0a66f650b1 -r 5fd507839b76 liboctave/oct-inttypes.h --- a/liboctave/oct-inttypes.h Tue Oct 07 15:49:03 2008 +0200 +++ b/liboctave/oct-inttypes.h Wed Oct 08 08:01:46 2008 +0200 @@ -267,11 +267,12 @@ static S compute_threshold (S val, T orig_val) { - if (static_cast (val) != orig_val) - return val; - else - // Next number away from zero. - return val * (static_cast (1.0) + std::numeric_limits::epsilon ()); + val = xround (val); // Fool optimizations (maybe redundant) + // If val is even, but orig_val is odd, we're one unit off. + if (orig_val % 2 && val / 2 == xround (val / 2)) + // TODO: is this always correct? + val *= (static_cast(1) - (std::numeric_limits::epsilon () / 2)); + return val; } public: @@ -288,12 +289,12 @@ fnan = true; return static_cast (0); } - else if (value <= thmin) + else if (value < thmin) { - octave_int_base::ftrunc = true; + ftrunc = true; return min_val (); } - else if (value >= thmax) + else if (value > thmax) { ftrunc = true; return max_val ();