diff options
author | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-02-26 07:31:10 +0000 |
---|---|---|
committer | mrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-02-26 07:31:10 +0000 |
commit | cc4be225a8c1dd5f42a4c4b6356b0b351b6e85d5 (patch) | |
tree | 151ec2e38f5711d6a61f230ae4727763d33a9a3f | |
parent | 6549f20ebf705d4ddb82c1507e3ee4b8474e8435 (diff) |
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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62581 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | object.c | 2 | ||||
-rw-r--r-- | spec/ruby/core/kernel/Integer_spec.rb | 17 | ||||
-rw-r--r-- | test/ruby/test_integer.rb | 11 |
3 files changed, 24 insertions, 6 deletions
@@ -3132,7 +3132,7 @@ rb_convert_to_integer(VALUE val, int base) 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; diff --git a/spec/ruby/core/kernel/Integer_spec.rb b/spec/ruby/core/kernel/Integer_spec.rb index 1e95fc9151..979283eb23 100644 --- a/spec/ruby/core/kernel/Integer_spec.rb +++ b/spec/ruby/core/kernel/Integer_spec.rb @@ -10,11 +10,18 @@ describe :kernel_integer, shared: true do 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 do 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 diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index 1b485760e3..92ad38d39a 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -92,6 +92,17 @@ class TestInteger < Test::Unit::TestCase 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"))} |