From 75d1ee80082747660b6e1ec1f114b445c50cd375 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Wed, 7 Aug 2019 10:58:53 -0700 Subject: [PATCH] Handle BasicObject in drb Also fix a bug in rescue clause of any_to_s because sprintf does not handle the %l modifier. Fixes [Bug #7833] --- lib/drb/drb.rb | 67 ++++++++++++++++++++++++++++++++++++--------- test/drb/drbtest.rb | 8 ++++++ test/drb/ut_drb.rb | 9 ++++++ 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb index caffd5df25..8cac9a4ad3 100644 --- a/lib/drb/drb.rb +++ b/lib/drb/drb.rb @@ -377,7 +377,12 @@ def to_obj(ref) # This implementation returns the object's __id__ in the local # object space. def to_id(obj) - obj.nil? ? nil : obj.__id__ + case obj + when Object + obj.nil? ? nil : obj.__id__ + when BasicObject + obj.__id__ + end end end @@ -560,7 +565,14 @@ def initialize(config) # :nodoc: end def dump(obj, error=false) # :nodoc: - obj = make_proxy(obj, error) if obj.kind_of? DRbUndumped + case obj + when DRbUndumped + obj = make_proxy(obj, error) + when Object + # nothing + else + obj = make_proxy(obj, error) + end begin str = Marshal::dump(obj) rescue @@ -1092,7 +1104,14 @@ def _dump(lv) def initialize(obj, uri=nil) @uri = nil @ref = nil - if obj.nil? + case obj + when Object + is_nil = obj.nil? + when BasicObject + is_nil = false + end + + if is_nil return if uri.nil? @uri, option = DRbProtocol.uri_option(uri, DRb.config) @ref = DRbURIOption.new(option) unless option.nil? @@ -1527,7 +1546,13 @@ def insecure_method?(msg_id) def any_to_s(obj) obj.to_s + ":#{obj.class}" rescue - sprintf("#<%s:0x%lx>", obj.class, obj.__id__) + case obj + when Object + klass = obj.class + else + klass = Kernel.instance_method(:class).bind(obj).call + end + sprintf("#<%s:0x%dx>", klass, obj.__id__) end # Check that a method is callable via dRuby. @@ -1543,14 +1568,27 @@ def check_insecure_method(obj, msg_id) raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class raise(SecurityError, "insecure method `#{msg_id}'") if insecure_method?(msg_id) - if obj.private_methods.include?(msg_id) - desc = any_to_s(obj) - raise NoMethodError, "private method `#{msg_id}' called for #{desc}" - elsif obj.protected_methods.include?(msg_id) - desc = any_to_s(obj) - raise NoMethodError, "protected method `#{msg_id}' called for #{desc}" + case obj + when Object + if obj.private_methods.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "private method `#{msg_id}' called for #{desc}" + elsif obj.protected_methods.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "protected method `#{msg_id}' called for #{desc}" + else + true + end else - true + if Kernel.instance_method(:private_methods).bind(obj).call.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "private method `#{msg_id}' called for #{desc}" + elsif Kernel.instance_method(:protected_methods).bind(obj).call.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "protected method `#{msg_id}' called for #{desc}" + else + true + end end end public :check_insecure_method @@ -1596,8 +1634,11 @@ def perform end end @succ = true - if @msg_id == :to_ary && @result.class == Array - @result = DRbArray.new(@result) + case @result + when Array + if @msg_id == :to_ary + @result = DRbArray.new(@result) + end end return @succ, @result rescue StandardError, ScriptError, Interrupt diff --git a/test/drb/drbtest.rb b/test/drb/drbtest.rb index b3e857877e..f904278b6b 100644 --- a/test/drb/drbtest.rb +++ b/test/drb/drbtest.rb @@ -158,6 +158,14 @@ def test_01_02_loop end end + def test_02_basic_object + obj = @there.basic_object + assert_kind_of(DRb::DRbObject, obj) + assert_equal(1, obj.foo) + assert_raise(NoMethodError){obj.prot} + assert_raise(NoMethodError){obj.priv} + end + def test_02_unknown obj = @there.unknown_class assert_kind_of(DRb::DRbUnknown, obj) diff --git a/test/drb/ut_drb.rb b/test/drb/ut_drb.rb index 6a94a0fb40..b1306d0cb0 100644 --- a/test/drb/ut_drb.rb +++ b/test/drb/ut_drb.rb @@ -63,6 +63,15 @@ def unknown_module FooBar.new end + class BO < ::BasicObject + def foo; 1 end + protected def prot; 2; end + private def priv; 3; end + end + def basic_object + BO.new + end + def unknown_class Unknown2.new end -- 2.21.0