summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2020-07-24 21:08:50 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-07-24 21:08:50 +0900
commit3ead2770a1fd7452a9b875a8be7b93335f41abda (patch)
tree43abe79c1b540741f0a0d0a62b6c3a0e5d515f4e
parent2735da2039b9e441e41b11b606ba362db350a658 (diff)
Respect visibility in non-array Enumerable#inject [Bug #13592]
-rw-r--r--enum.c2
-rw-r--r--test/ruby/test_enum.rb56
2 files changed, 57 insertions, 1 deletions
diff --git a/enum.c b/enum.c
index 8769680..69c1641 100644
--- a/enum.c
+++ b/enum.c
@@ -734,7 +734,7 @@ inject_op_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, p))
}
else if (SYMBOL_P(name = memo->u3.value)) {
const ID mid = SYM2ID(name);
- MEMO_V1_SET(memo, rb_funcallv(memo->v1, mid, 1, &i));
+ MEMO_V1_SET(memo, rb_funcallv_public(memo->v1, mid, 1, &i));
}
else {
VALUE args[2];
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 809db31..8d30b34 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -239,6 +239,62 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal(2.0+3.0i, [2.0, 3.0i].inject(:+))
end
+ def test_inject_op_redefined
+ assert_separately([], "#{<<~"end;"}\n""end")
+ k = Class.new do
+ include Enumerable
+ def each
+ yield 1
+ yield 2
+ yield 3
+ end
+ end
+ all_assertions_foreach("", *%i[+ * / - %]) do |op|
+ bug = '[ruby-dev:49510] [Bug#12178] should respect redefinition'
+ begin
+ Integer.class_eval do
+ alias_method :orig, op
+ define_method(op) do |x|
+ 0
+ end
+ end
+ assert_equal(0, k.new.inject(op), bug)
+ ensure
+ Integer.class_eval do
+ undef_method op
+ alias_method op, :orig
+ end
+ end
+ end;
+ end
+
+ def test_inject_op_private
+ assert_separately([], "#{<<~"end;"}\n""end")
+ k = Class.new do
+ include Enumerable
+ def each
+ yield 1
+ yield 2
+ yield 3
+ end
+ end
+ all_assertions_foreach("", *%i[+ * / - %]) do |op|
+ bug = '[ruby-core:81349] [Bug #13592] should respect visibility'
+ assert_raise_with_message(NoMethodError, /private method/, bug) do
+ begin
+ Integer.class_eval do
+ private op
+ end
+ k.new.inject(op)
+ ensure
+ Integer.class_eval do
+ public op
+ end
+ end
+ end
+ end;
+ end
+
def test_inject_array_op_redefined
assert_separately([], "#{<<~"end;"}\n""end")
all_assertions_foreach("", *%i[+ * / - %]) do |op|