changeset 30393:cfee9398503d

maint: merge stable to default.
author Markus Mützel <markus.muetzel@gmx.de>
date Mon, 29 Nov 2021 16:23:14 +0100
parents fe6d1711feea (current diff) 5793f0355bfa (diff)
children 335a96d90ae7
files
diffstat 2 files changed, 44 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/array/Range.h	Sun Nov 28 22:03:07 2021 -0800
+++ b/liboctave/array/Range.h	Mon Nov 29 16:23:14 2021 +0100
@@ -322,11 +322,15 @@
 
     void init (void)
     {
+      // We need an integer division that is truncating decimals instead of
+      // rounding.  So, use underlying C++ types instead of octave_int<T>.
+      // FIXME: The numerator might underflow or overflow. Add checks for that.
       m_numel = ((m_increment == T (0)
                   || (m_limit > m_base && m_increment < T (0))
                   || (m_limit < m_base && m_increment > T (0)))
-                 ? T (0)
-                 : (m_limit - m_base + m_increment) / m_increment);
+                 ? 0
+                 : (m_limit.value () - m_base.value () + m_increment.value ())
+                   / m_increment.value ());
 
       m_final = m_base + (m_numel - 1) * m_increment;
     }
--- a/test/range.tst	Sun Nov 28 22:03:07 2021 -0800
+++ b/test/range.tst	Mon Nov 29 16:23:14 2021 +0100
@@ -511,3 +511,41 @@
 %!   assert (numel (rlo), n+1);
 %!   assert (numel (rhi), n+1);
 %! endfor
+
+## Test that ranges do not exceed limits for integer types
+
+## Ascending ranges, signed
+%!test <*61300>
+%! int_types = {@int8, @int16, @int32, @int64};
+%! for i_type = 1:numel (int_types)
+%!   for i_start = 0:4
+%!     assert ((int_types{i_type} (i_start) : 6 : 100)([1,end]), ...
+%!             [int_types{i_type}(i_start), int_types{i_type}(96+i_start)]);
+%!   endfor
+%!   assert ((int_types{i_type} (5) : 6 : 100)([1,end]), ...
+%!           [int_types{i_type}(5), int_types{i_type}(95)]);
+%! endfor
+
+## Ascending ranges, unsigned
+%!test <*61300>
+%! int_types = {@uint8, @uint16, @uint32, @uint64};
+%! for i_type = 1:numel (int_types)
+%!   for i_start = 0:4
+%!     assert ((int_types{i_type} (i_start) : 6 : 100)([1,end]), ...
+%!             [int_types{i_type}(i_start), int_types{i_type}(96+i_start)]);
+%!   endfor
+%!   assert ((int_types{i_type} (5) : 6 : 100)([1,end]), ...
+%!           [int_types{i_type}(5), int_types{i_type}(95)]);
+%! endfor
+
+## Descending ranges, signed
+%!test <*61300>
+%! int_types = {@int8, @int16, @int32, @int64};
+%! for i_type = 1:numel (int_types)
+%!   for i_start = 0:4
+%!     assert ((int_types{i_type} (100-i_start) : -6 : 0)([1,end]), ...
+%!             [int_types{i_type}(100-i_start), int_types{i_type}(4-i_start)]);
+%!   endfor
+%!   assert ((int_types{i_type} (95) : -6 : 0)([1,end]), ...
+%!           [int_types{i_type}(95), int_types{i_type}(5)]);
+%! endfor