On Tuesday 28 January 2003 11:44 pm, Gennady wrote:
| Hi, fellow Rubyists
|
| What is the rationale behind the following change in SAFE level when
| invoking a method with "call":
|
| class Test
|    attr_accessor :value
|    def show
|      "Safe level: #{$SAFE}"
|    end
| end
|
| Test.taint
| t = Test.new
|
| p t.show  # ==> Safe level: 0
| p t.method(:show).call # ==> Safe level: 4
|
| So every time you invoke a method with "call", safe level is set to 4
| for the duration of the call with all consequences -- when you invoke
| value= with
| t.method(:value=).call(1), you get an error:
|
| ttt.rb:17:in `value=': Insecure: can't modify instance variable
| (SecurityError)
|          from ttt.rb:17:in `call'
|          from ttt.rb:17
|
| Even puts from a so invoked method fails:
|
| ttt.rb:5:in `write': Insecure operation `write' at level 4
| (SecurityError)
|          from ttt.rb:5:in `puts'
|          from ttt.rb:5:in `show'
|          from ttt.rb:15:in `call'
|          from ttt.rb:15
|
| I came across this behavior when experimenting with safe level 3, where
| all objects are created tainted.
|
| Thanks in advance for any suggestions and/or enlightments.
| Gennady.
|
| P.S. I checked in eval.c, there ruby_safe_level is explicitly set to 4
| in method_call().

Interesting, since Object#send works fine:

>> class Test
>>    attr_accessor :value
>>    def show
>>      "Safe level: #{$SAFE}"
>>    end
>> end
=> nil
>>
?> Test.taint
=> Test
>> t = Test.new
=> #<Test:0x401db06c>
>> t.show
=> "Safe level: 0"
>> t.send :value=, 4
=> 4

-- 
Bruce R. Williams :: [iusris/#ruby-lang] :: http://www.codedbliss.com

  'It does not require a majority to prevail, but rather an irate,
  tireless minority keen to set brush fires in people's minds.'
  -- Samuel Adams