From c1fc20124c269eab6a863e48c6647884b883de88 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 27 Feb 2014 03:10:12 +0000 Subject: [PATCH] numeric.c: check signs before division * numeric.c (ruby_num_interval_step_size): check signs and get rid of implementation dependent behavior of negative division. [ruby-core:61106] [Bug #9570] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45187 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 ++++++ numeric.c | 11 +++++++++++ test/ruby/test_numeric.rb | 2 ++ 3 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9740541e62..e6f0bc0f6b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Thu Feb 27 12:10:09 2014 Nobuyoshi Nakada + + * numeric.c (ruby_num_interval_step_size): check signs and get rid + of implementation dependent behavior of negative division. + [ruby-core:61106] [Bug #9570] + Thu Feb 27 03:55:45 2014 Zachary Scott * thread.c: [DOC] Typo in comment for _FORTIFY_SOURCE [Fixes GH-548] diff --git a/numeric.c b/numeric.c index 838ec43c29..99a1c7d60e 100644 --- a/numeric.c +++ b/numeric.c @@ -1808,10 +1808,21 @@ ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl) long delta, diff, result; diff = FIX2LONG(step); + if (!diff) rb_num_zerodiv(); delta = FIX2LONG(to) - FIX2LONG(from); if (excl) { delta += (diff > 0 ? -1 : +1); } + if (delta) { + if (diff < 0) { + if (delta > 0) return INT2FIX(0); + diff = -diff; + delta = -delta; + } + else { + if (delta < 0) return INT2FIX(0); + } + } result = delta / diff; return LONG2FIX(result >= 0 ? result + 1 : 0); } diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb index 44c12ede9c..25351163b7 100644 --- a/test/ruby/test_numeric.rb +++ b/test/ruby/test_numeric.rb @@ -279,6 +279,8 @@ class TestNumeric < Test::Unit::TestCase assert_step [1], [1, 10, 2**32] assert_step [1], [1, to: 10, by: 2**32] + assert_step [], [2, 1, 3] + assert_step [], [-2, -1, -3] assert_step [3, 3, 3, 3], [3, by: 0], inf: true assert_step [10], [10, 1, -(2**32)]