November 2008 Archives

$SAFE is Proc-local

| 1 Comment

While researching Ruby's new-in-1.9 Object methods untrusted?, untrust, and trust, I discovered something I did not know about the $SAFE variable: in addition to being Thread-local, it is also Proc-local. Proc objects (both procs and lambdas) have their own copy of $SAFE, and they run at whatever $SAFE level was in effect when the Proc was created not the safe level that is in effect when they are invoked. This was discussed three years ago over at _why's old blog.

There is a corollary, however that was demonstrated but not discussed in a recent ruby-core post by Shugo Maeda: if you set $SAFE inside a proc or a lambda, that setting is local, and does not change the global safe level. Googling for "safe_eval" implementations shows that everyone uses Thread.new to create a sandbox with a locally elevated safe level. It turns out, however, that an ordinary lambda will also work. (One can argue, however, that a thread gives extra safety because it can be monitored and killed to guard against runaway code that doesn't terminate.)

In any case, here is the method I defined to try this out. Pass it a safe level (it defaults to 4) and a block of code, and it will execute the block at that level without altering the global safe level and without creating a new thread:

# Execute a block at the specified safe level. Tested with Ruby 1.9 and 1.8.7
def safely(level = 4)
  sandbox = lambda do # Set up a sandbox 
    $SAFE = level     # Go to the specified safe level for this lambda only
    yield             # Invoke the block at that level
  end
  sandbox.call        # Invoke the sandbox without changing $SAFE globally
end

# Use this method like this. 
x = safely { eval('"untrusted code"') }
[x, x.tainted?, x.untrusted?]  # => ["untrusted code", true, true]

I'm not convinced that this method is actually useful in practice, but I thought it was interesting, and it reminds me again how cool it is to be able to define methods that accept blocks and act like control statements.

Bending the Arc of History

President-elect Obama sure writes and delivers a great speech! My favorite line from his victory speech last night:

put their hands on the arc of history and bend it once more toward the hope of a better day.

I love the image of bending the arc of history. Certainly appropriate to the occasion last night. Let's hope that under the Obama administration we can continue to bend the arc of history toward (to pick one example) reduced CO2 emissions!

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference

Advertising

Pages

Hosted By

Powered by Movable Type 4.21-en