changeset 30855:aaf689533e7b stable

Avoid integer division by zero for int64 ranges with double increment. * libinterp/octave-value/ov.cc (range_numel (T base, double increment, T limit)): Check for wrap around after casting to unsigned integer type. * test/range.tst: Un-comment tests.
author Markus Mützel <markus.muetzel@gmx.de>
date Tue, 22 Mar 2022 18:01:26 +0100
parents fc3bd70cd1be
children 1be26e9c07e3 9b3b0dbb4eba
files libinterp/octave-value/ov.cc test/range.tst
diffstat 2 files changed, 9 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov.cc	Tue Mar 22 00:01:53 2022 -0400
+++ b/libinterp/octave-value/ov.cc	Tue Mar 22 18:01:26 2022 +0100
@@ -3255,6 +3255,11 @@
 
     UT unsigned_increment = range_increment<T> (increment);
 
+    // If the increment wasn't zero before but it is now, the cast to UT
+    // wrapped around. The range can only have one value.
+    if (unsigned_increment == 0)
+      return 1;
+
     return range_numel_aux (base, unsigned_increment, limit);
   }
 
--- a/test/range.tst	Tue Mar 22 00:01:53 2022 -0400
+++ b/test/range.tst	Tue Mar 22 18:01:26 2022 +0100
@@ -613,9 +613,8 @@
 %! for i_type = 1:numel (types)
 %!   assert (intmin (types{i_type}) : -double (intmin (types{i_type})) : intmax (types{i_type}), ...
 %!           [intmin(types{i_type}), 0]);
-%!   ## FIXME: This test leads to a deadlock for "int64".
-%!   ## assert (intmin (types{i_type}) : -2*double (intmin (types{i_type})) : intmax (types{i_type}), ...
-%!   ##         intmin (types{i_type}));
+%!   assert (intmin (types{i_type}) : -2*double (intmin (types{i_type})) : intmax (types{i_type}), ...
+%!           intmin (types{i_type}));
 %!   if (! strcmp (types, "int64"))
 %!     ## The increment cannot be represented in double precision for "int64"
 %!     assert (intmin (types{i_type}) : 2*double (intmax (types{i_type})) : intmin (types{i_type}), ...
@@ -627,9 +626,8 @@
 %! for i_type = 1:numel (types)
 %!   assert (intmax (types{i_type}) : double (intmin (types{i_type})) : intmin (types{i_type}), ...
 %!           [intmax(types{i_type}), -1]);
-%!   ## FIXME: This test leads to a deadlock for "int64".
-%!   ## assert (intmax (types{i_type}) : 2*double (intmin (types{i_type})) : intmin (types{i_type}), ...
-%!   ##         intmax (types{i_type}));
+%!   assert (intmax (types{i_type}) : 2*double (intmin (types{i_type})) : intmin (types{i_type}), ...
+%!           intmax (types{i_type}));
 %!   if (! strcmp (types, "int64"))
 %!     ## The increment cannot be represented in double precision for "int64"
 %!     assert (intmax (types{i_type}) : -2*double (intmax (types{i_type})) : intmin (types{i_type}), ...