public
Created

Patch ERB to not reuse TOPLEVEL_BINDING when none is specified

  • Download Gist
gistfile1.diff
Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.