changeset 8193:5fd507839b76

remove the int->real conversion code vulnerability to compiler optimization
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 08 Oct 2008 08:01:46 +0200
parents 9a0a66f650b1
children aea271e60434
files liboctave/ChangeLog liboctave/oct-inttypes.h
diffstat 2 files changed, 16 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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  <highegg@gmail.com>
+
+	* oct-inttypes.h (octave_base_int<T>::compute_threshold): Return
+	exclusive bounds rather than inclusive, be resistant to compiler
+	optimizations.
+	(octave_base_int<T>::convert_real): Use exclusive bounds.
+
 2008-10-07  Jaroslav Hajek <highegg@gmail.com>
 
 	* oct-inttypes.h (OCTAVE_INT_DOUBLE_BIN_OP): Change octave_int64 to 
--- 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 <T> (val) != orig_val)
-        return val;
-      else
-        // Next number away from zero.
-        return val * (static_cast<S> (1.0) + std::numeric_limits<S>::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<S>(1) - (std::numeric_limits<S>::epsilon () / 2)); 
+      return val;
     }
   
 public:
@@ -288,12 +289,12 @@
           fnan = true;
           return static_cast<T> (0);
         }
-      else if (value <= thmin)
+      else if (value < thmin)
         {
-          octave_int_base<T>::ftrunc = true;
+          ftrunc = true;
           return min_val ();
         }
-      else if (value >= thmax)
+      else if (value > thmax)
         {
           ftrunc = true;
           return max_val ();