Safe Mode Lowering


#1

I am aware that the safe mode in Ruby can only be set higher, not
lower. This makes sense, as unsafe code should not be able to lower
the safe mode. However, is there a way to lower it at all, as I can
think of many times this may be useful. Would it not make a lot more
sense to be able to do something like this?

safe_mode(x) do # x must be greater than the current safe mode

do risky code here

end

back to original safe mode

Maybe the above is possible and I am just missing how, but I would
think that it would be much more useful to have in a form similar to
this all the time.

  • Jake McArthur

#2

Jake McArthur wrote:

Maybe the above is possible and I am just missing how, but I would think
that it would be much more useful to have in a form similar to this all
the time.

  • Jake McArthur

If you change $SAFE in a thread, it affects only that thread.


#3

On Wed, 26 Apr 2006, Jake McArthur wrote:

Maybe the above is possible and I am just missing how, but I would think that
it would be much more useful to have in a form similar to this all the time.

  • Jake McArthur

you have

fork {
$SAFE = 4

}
Process.wait

and also

t = Thread.new{
$SAFE = 4

}
t.value

fyi.

-a


#4

I have even used that technique before. I’m dumb. So, something like
this would probably work for the type of abstraction I’m thinking of
(too lazy for an irb test).

def safe_block(mode)
t = Thread.new do
@SAFE = mode
yield
end
t.value
end

  • Jake McArthur

#5

On Apr 26, 2006, at 12:27 AM, Jake McArthur wrote:

Maybe the above is possible and I am just missing how, but I would
think that it would be much more useful to have in a form similar
to this all the time.

module Kernel
def with_safe(mode)
Thread.new {
$SAFE = mode
yield
}.join
end
end

with_safe(3) do
eval(“1+2”)
end

$SAFE, along with some other global variables, is thread local.

– Daniel


#6

On Apr 25, 2006, at 4:02 PM, David P. wrote:

Jake,

Here’s code that will do what you want:

You implemented Thread#value.

$ ruby
t = Thread.new { raise }
t.value
p ‘can’t do it’
-:1: unhandled exception
from -:2:in `value’
from -:2


Eric H. - removed_email_address@domain.invalid - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com


#7

Eric,

Thanks for the correction. I’ll update the code to:

module SafeDo
def safe_do(safe_level)
(Thread.new {$SAFE = safe_level ; yield } ).value
end
end

David


#8

Jake,

Here’s code that will do what you want:

module SafeDo
require ‘monitor’

def safe_do(safe_level)
ret = nil
waiter = ‘’
waiter.extend(MonitorMixin)
wait_cond = waiter.new_cond
is_exception = false
is_done = false

Thread.start do
  begin
    $SAFE = safe_level

    ret = yield
    is_done = true
    waiter.synchronize do
      wait_cond.signal
    end
  rescue Exception => e
    ret = e
    is_exception = true
    is_done = true
    waiter.synchronize do
      wait_cond.signal
    end

  end
end

waiter.synchronize do
  wait_cond.wait_while { !is_done }
end

raise ret if is_exception

return ret

end
end

Thanks,

David