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