91 lines
3.0 KiB
Diff
91 lines
3.0 KiB
Diff
From a53f3d57d1c70f35534c457de2c471d84a55956a Mon Sep 17 00:00:00 2001
|
|
From: Takashi Kokubun <takashikkbn@gmail.com>
|
|
Date: Tue, 21 Apr 2026 16:27:44 +0900
|
|
Subject: [PATCH 1/2] [ruby/erb] Prohibit def_method on marshal-loaded ERB
|
|
instances
|
|
|
|
Extends the @_init guard to def_method so that an ERB object created
|
|
via Marshal.load (which bypasses initialize) raises ArgumentError
|
|
instead of evaluating arbitrary source. def_module and def_class both
|
|
delegate to def_method and are covered by the same check.
|
|
|
|
Co-authored-by: Tristan Madani <TristanInSec@gmail.com>
|
|
---
|
|
lib/erb.rb | 3 +++
|
|
test/erb/test_erb.rb | 27 +++++++++++++++++++++++++++
|
|
2 files changed, 30 insertions(+)
|
|
|
|
diff --git a/lib/erb.rb b/lib/erb.rb
|
|
index bc1615d7da..a7317c0856 100644
|
|
--- a/lib/erb.rb
|
|
+++ b/lib/erb.rb
|
|
@@ -463,6 +463,9 @@ def new_toplevel(vars = nil)
|
|
# erb.def_method(MyClass, 'render(arg1, arg2)', filename)
|
|
# print MyClass.new.render('foo', 123)
|
|
def def_method(mod, methodname, fname='(ERB)')
|
|
+ unless @_init.equal?(self.class.singleton_class)
|
|
+ raise ArgumentError, "not initialized"
|
|
+ end
|
|
src = self.src.sub(/^(?!#|$)/) {"def #{methodname}\n"} << "\nend\n"
|
|
mod.module_eval do
|
|
eval(src, binding, fname, -1)
|
|
diff --git a/test/erb/test_erb.rb b/test/erb/test_erb.rb
|
|
index 555345a140..1266b64e41 100644
|
|
--- a/test/erb/test_erb.rb
|
|
+++ b/test/erb/test_erb.rb
|
|
@@ -714,6 +714,33 @@ def test_prohibited_marshal_load
|
|
assert_raise(ArgumentError) {erb.result}
|
|
end
|
|
|
|
+ def test_prohibited_marshal_load_def_method
|
|
+ erb = ERB.allocate
|
|
+ erb.instance_variable_set(:@src, "")
|
|
+ erb.instance_variable_set(:@lineno, 1)
|
|
+ erb.instance_variable_set(:@_init, true)
|
|
+ erb = Marshal.load(Marshal.dump(erb))
|
|
+ assert_raise(ArgumentError) {erb.def_method(Class.new, 'render')}
|
|
+ end
|
|
+
|
|
+ def test_prohibited_marshal_load_def_module
|
|
+ erb = ERB.allocate
|
|
+ erb.instance_variable_set(:@src, "")
|
|
+ erb.instance_variable_set(:@lineno, 1)
|
|
+ erb.instance_variable_set(:@_init, true)
|
|
+ erb = Marshal.load(Marshal.dump(erb))
|
|
+ assert_raise(ArgumentError) {erb.def_module}
|
|
+ end
|
|
+
|
|
+ def test_prohibited_marshal_load_def_class
|
|
+ erb = ERB.allocate
|
|
+ erb.instance_variable_set(:@src, "")
|
|
+ erb.instance_variable_set(:@lineno, 1)
|
|
+ erb.instance_variable_set(:@_init, true)
|
|
+ erb = Marshal.load(Marshal.dump(erb))
|
|
+ assert_raise(ArgumentError) {erb.def_class}
|
|
+ end
|
|
+
|
|
def test_multi_line_comment_lineno
|
|
erb = ERB.new(<<~EOS)
|
|
<%= __LINE__ %>
|
|
|
|
From 2f223e90edf40f5d537760cb26c77b608bddff36 Mon Sep 17 00:00:00 2001
|
|
From: Takashi Kokubun <takashikkbn@gmail.com>
|
|
Date: Tue, 21 Apr 2026 17:14:06 +0900
|
|
Subject: [PATCH 2/2] [ruby/erb] Version 4.0.3.1
|
|
|
|
---
|
|
lib/erb/version.rb | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/lib/erb/version.rb b/lib/erb/version.rb
|
|
index 295fc5fa6f..85e2a79def 100644
|
|
--- a/lib/erb/version.rb
|
|
+++ b/lib/erb/version.rb
|
|
@@ -1,5 +1,5 @@
|
|
# frozen_string_literal: true
|
|
class ERB
|
|
- VERSION = '4.0.3'
|
|
+ VERSION = '4.0.3.1'
|
|
private_constant :VERSION
|
|
end
|