summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2024-11-08 14:33:48 -0500
committerPeter Zhu <peter@peterzhu.ca>2024-11-08 15:43:41 -0500
commit51ffef281996727c60571771cd07c1459ba58cd2 (patch)
treea6b6706cb5ed5324fadf271d49ecd0a336d9a53b /test/ruby
parent72550d269ea89cd0bfcede7ad01a7c70ed01ba06 (diff)
Fix memory leak in prism when syntax error in iseq compilation
If there's a syntax error during iseq compilation then prism would leak memory because it would not free the pm_parse_result_t. This commit changes pm_iseq_new_with_opt to have a rb_protect to catch when an error is raised, and return NULL and set error_state to a value that can be raised by calling rb_jump_tag after memory has been freed. For example: 10.times do 10_000.times do eval("/[/=~s") rescue SyntaxError end puts `ps -o rss= -p #{$$}` end Before: 39280 68736 99232 128864 158896 188208 217344 246304 275376 304592 After: 12192 13200 14256 14848 16000 16000 16000 16064 17232 17952
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/12036
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_eval.rb24
1 files changed, 24 insertions, 0 deletions
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index cf1c2bb2f6..2129272b00 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -612,4 +612,28 @@ class TestEval < Test::Unit::TestCase
x = orphan_lambda
assert_equal(:ok, x.call)
end
+
+ def test_syntax_error_no_memory_leak
+ assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
+ begin;
+ 100_000.times do
+ eval("/[/=~s")
+ rescue SyntaxError
+ else
+ raise "Expected SyntaxError to be raised"
+ end
+ end;
+
+ assert_no_memory_leak([], "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
+ begin;
+ a = 1
+
+ 100_000.times do
+ eval("if a in [0, 0] | [0, a]; end")
+ rescue SyntaxError
+ else
+ raise "Expected SyntaxError to be raised"
+ end
+ end;
+ end
end