Skip to content

Instantly share code, notes, and snippets.

@headius
Created September 21, 2012 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/3764377 to your computer and use it in GitHub Desktop.
Save headius/3764377 to your computer and use it in GitHub Desktop.
Patch ERB to not reuse TOPLEVEL_BINDING when none is specified
diff --git a/lib/erb.rb b/lib/erb.rb
index 26c34ee..a78a8cb 100644
--- a/lib/erb.rb
+++ b/lib/erb.rb
@@ -818,7 +818,7 @@ class ERB
end
# Generate results and print them. (see ERB#result)
- def run(b=TOPLEVEL_BINDING)
+ def run(b=new_toplevel)
print self.result(b)
end
@@ -830,7 +830,7 @@ class ERB
# _b_ accepts a Binding or Proc object which is used to set the context of
# code evaluation.
#
- def result(b=TOPLEVEL_BINDING)
+ def result(b=new_toplevel)
if @safe_level
proc {
$SAFE = @safe_level
@@ -841,6 +841,12 @@ class ERB
end
end
+ def new_toplevel
+ # New binding each time *near* toplevel for unspecified runs
+ eval "proc{binding}.call", TOPLEVEL_BINDING
+ end
+ private :new_toplevel
+
# Define _methodname_ as instance method of _mod_ from compiled ruby source.
#
# example:
diff --git a/test/erb/test_erb.rb b/test/erb/test_erb.rb
index 7ddbc87..47caf03 100644
--- a/test/erb/test_erb.rb
+++ b/test/erb/test_erb.rb
@@ -49,6 +49,14 @@ class TestERB < Test::Unit::TestCase
assert_equal("", ERB::Util.html_escape(nil))
assert_equal("123", ERB::Util.html_escape(123))
end
+
+ def test_concurrent_default_binding
+ template1 = 'one <%= ERB.new(template2).result %>'
+
+ eval 'template2 = "two"', TOPLEVEL_BINDING
+
+ assert_equal("one two", ERB.new(template1).result)
+ end
end
class TestERBCore < Test::Unit::TestCase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment