ruby-changes:50455
From: mrkn <ko1@a...>
Date: Mon, 26 Feb 2018 16:31:16 +0900 (JST)
Subject: [ruby-changes:50455] mrkn:r62581 (trunk): Check the result of to_int in Kernel#Integer
mrkn 2018-02-26 16:31:10 +0900 (Mon, 26 Feb 2018) New Revision: 62581 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62581 Log: Check the result of to_int in Kernel#Integer [ruby-core:85813] [Bug #14552] * object.c (rb_convert_to_integer): Check the result of to_int in Kernel#Integer * test/ruby/test_integer.rb: add tests. * spec/ruby/core/kernel/Integer_spec.rb: fix examples. Modified files: trunk/object.c trunk/spec/ruby/core/kernel/Integer_spec.rb trunk/test/ruby/test_integer.rb Index: spec/ruby/core/kernel/Integer_spec.rb =================================================================== --- spec/ruby/core/kernel/Integer_spec.rb (revision 62580) +++ spec/ruby/core/kernel/Integer_spec.rb (revision 62581) @@ -10,11 +10,18 @@ describe :kernel_integer, shared: true d https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/kernel/Integer_spec.rb#L10 Integer(100).should == 100 end - it "uncritically return the value of to_int even if it is not an Integer" do + it "raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" do obj = mock("object") obj.should_receive(:to_int).and_return("1") - obj.should_not_receive(:to_i) - Integer(obj).should == "1" + obj.should_receive(:to_i).and_return(nil) + lambda { Integer(obj) }.should raise_error(TypeError) + end + + it "return a result of to_i when to_int does not return an Integer" do + obj = mock("object") + obj.should_receive(:to_int).and_return("1") + obj.should_receive(:to_i).and_return(42) + Integer(obj).should == 42 end it "raises a TypeError when passed nil" do @@ -45,9 +52,9 @@ describe :kernel_integer, shared: true d https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/kernel/Integer_spec.rb#L52 it "returns the value of to_int if the result is a Bignum" do obj = mock("object") - obj.should_receive(:to_int).and_return(2e100) + obj.should_receive(:to_int).and_return(2 * 10**100) obj.should_not_receive(:to_i) - Integer(obj).should == 2e100 + Integer(obj).should == 2 * 10**100 end it "calls to_i on an object whose to_int returns nil" do Index: object.c =================================================================== --- object.c (revision 62580) +++ object.c (revision 62581) @@ -3132,7 +3132,7 @@ rb_convert_to_integer(VALUE val, int bas https://github.com/ruby/ruby/blob/trunk/object.c#L3132 rb_raise(rb_eArgError, "base specified for non string value"); } tmp = convert_type(val, "Integer", "to_int", FALSE); - if (NIL_P(tmp)) { + if (!RB_INTEGER_TYPE_P(tmp)) { return rb_to_integer(val, "to_i"); } return tmp; Index: test/ruby/test_integer.rb =================================================================== --- test/ruby/test_integer.rb (revision 62580) +++ test/ruby/test_integer.rb (revision 62581) @@ -92,6 +92,17 @@ class TestInteger < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_integer.rb#L92 assert_equal(2 ** 50, Integer(2.0 ** 50)) assert_raise(TypeError) { Integer(nil) } + bug14552 = '[ruby-core:85813]' + obj = Object.new + def obj.to_int; "str"; end + assert_raise(TypeError, bug14552) { Integer(obj) } + def obj.to_i; 42; end + assert_equal(42, Integer(obj), bug14552) + + obj = Object.new + def obj.to_i; "str"; end + assert_raise(TypeError) { Integer(obj) } + bug6192 = '[ruby-core:43566]' assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16be"))} assert_raise(Encoding::CompatibilityError, bug6192) {Integer("0".encode("utf-16le"))} -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/