Mercurial > octave
changeset 30392:5793f0355bfa stable
Ensure integer ranges do not exceed limits (bug #61300).
* liboctave/array/Range.h (range::init): Use C++ types instead of octave_int<T>
to get truncating behavior for division.
* test/range.tst: Add tests for integer ranges.
author | Arun Giridhar <arungiridhar@gmail.com> |
---|---|
date | Sun, 28 Nov 2021 16:31:21 -0500 |
parents | a61e1a0f6024 |
children | cfee9398503d f3f3e3793fb5 |
files | liboctave/array/Range.h test/range.tst |
diffstat | 2 files changed, 44 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/liboctave/array/Range.h Sun Nov 28 21:52:08 2021 -0800 +++ b/liboctave/array/Range.h Sun Nov 28 16:31:21 2021 -0500 @@ -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 21:52:08 2021 -0800 +++ b/test/range.tst Sun Nov 28 16:31:21 2021 -0500 @@ -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