Bug #7499

public_send can be used to invoke protected methods

Added by Andy Lindeman almost 3 years ago. Updated over 2 years ago.

[ruby-core:50489]
Status:Closed
Priority:Normal
Assignee:-
ruby -v:ruby 2.0.0dev (2012-12-03) [x86_64-darwin12.2.1] Backport:

Description

class Foo
def bar
"wtf?"
end
protected :bar

def invoke_bar
public_send(:bar)
end
end

puts Foo.public_send(:bar) rescue puts "error; this seems normal"

puts Foo.new.invoke_bar

The last statement outputs "wtf?" on:

* 1.9.3p194

* 1.9.3p327

* ruby-head (2012-12-03)

The last statement raises a NoMethodError on:

* JRuby 1.7.0

* rubinius 2.0.0dev 2279857e

#

I /expected/ the NoMethodError behavior

bug-7499.patch Magnifier (2.7 KB) Charlie Somerville, 12/03/2012 08:10 PM

Associated revisions

Revision 38223
Added by Nobuyoshi Nakada almost 3 years ago

vm_eval.c: public_send does not consider how it is called

  • vm_eval.c (rb_method_call_status): use Qundef as no self instead of the current self.
  • vm_eval.c (send_internal): public_send does not consider how it is called, as mentioned in r14173. patched by charliesome (Charlie Somerville). [Bug #7499]

Revision 38223
Added by Nobuyoshi Nakada almost 3 years ago

vm_eval.c: public_send does not consider how it is called

  • vm_eval.c (rb_method_call_status): use Qundef as no self instead of the current self.
  • vm_eval.c (send_internal): public_send does not consider how it is called, as mentioned in r14173. patched by charliesome (Charlie Somerville). [Bug #7499]

History

#1 Updated by Charlie Somerville almost 3 years ago

rb_method_call_status checks the value of 'self' at the callsite to determine whether protected methods can be called.

Unfortunately this means calls to protected methods via public_send will erroneously succeed if they are in the right scope.

To fix this, I changed the meaning of Qundef as the 'self' argument to rb_call0. Formerly, Qundef meant 'use the self from the current control frame'. Now, Qundef means 'do not consider self so protected methods cannot be called'. I have updated the few calls to rb_call0 to fetch 'self' from the control frame manually. As rb_call0 and rb_method_call_status are static, there is no concern for ABI breakage.

#2 Updated by Marc-Andre Lafortune almost 3 years ago

Looks good to me.

#3 Updated by Nobuyoshi Nakada over 2 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r38223.
Andy, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


vm_eval.c: public_send does not consider how it is called

  • vm_eval.c (rb_method_call_status): use Qundef as no self instead of the current self.
  • vm_eval.c (send_internal): public_send does not consider how it is called, as mentioned in r14173. patched by charliesome (Charlie Somerville). [Bug #7499]

Also available in: Atom PDF