From facd02511b30aa27fd1a33d39b9c28109738652e Mon Sep 17 00:00:00 2001 From: usa Date: Fri, 25 Mar 2016 09:29:32 +0000 Subject: merge revision(s) 53949: [Backport #9810] * numeric.c (num_step_scan_args): comparison String with Numeric should raise TypeError. it is an invalid type, but not a mismatch the number of arguments. [ruby-core:62430] [Bug #9810] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@54276 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- numeric.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'numeric.c') diff --git a/numeric.c b/numeric.c index ba2fb49b3b..f9b22302ae 100644 --- a/numeric.c +++ b/numeric.c @@ -253,6 +253,12 @@ coerce_rescue(VALUE *x) return Qnil; /* dummy */ } +static VALUE +coerce_rescue_quiet(VALUE arg, VALUE errinfo) +{ + return Qundef; +} + static int do_coerce(VALUE *x, VALUE *y, int err) { @@ -1864,6 +1870,34 @@ ruby_num_interval_step_size(VALUE from, VALUE to, VALUE step, int excl) } } +static VALUE +num_step_compare_with_zero(VALUE num) +{ + VALUE zero = INT2FIX(0); + return rb_check_funcall(num, '>', 1, &zero); +} + +static int +num_step_negative_p(VALUE num) +{ + const ID mid = '<'; + VALUE r; + + if (FIXNUM_P(num)) { + if (method_basic_p(rb_cFixnum)) + return (SIGNED_VALUE)num < 0; + } + else if (RB_TYPE_P(num, T_BIGNUM)) { + if (method_basic_p(rb_cBignum)) + return RBIGNUM_NEGATIVE_P(num); + } + r = rb_rescue(num_step_compare_with_zero, num, coerce_rescue_quiet, Qnil); + if (r == Qundef) { + coerce_failed(num, INT2FIX(0)); + } + return !RTEST(r); +} + static int num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step) { @@ -1898,7 +1932,7 @@ num_step_scan_args(int argc, const VALUE *argv, VALUE *to, VALUE *step) if (NIL_P(*step)) { *step = INT2FIX(1); } - desc = !positive_int_p(*step); + desc = num_step_negative_p(*step); if (NIL_P(*to)) { *to = desc ? DBL2NUM(-INFINITY) : DBL2NUM(INFINITY); } -- cgit v1.2.3