Skip to content

Commit

Permalink
[Bug #20234] Fix segv when parsing begin statement in method definition
Browse files Browse the repository at this point in the history
In a method definition, the `begin` may not have an `nd_body`. When that
happens we get a null expr back from `last_expr_node` which causes a
segv for the following examples:

```ruby
def (begin;end).foo; end
def (begin;else;end).foo; end
def (begin;ensure;else;end).foo; end
```

In addition, I've added tests for other cases that weren't causing a
segv but appeared untested.`

Fixes https://bugs.ruby-lang.org/issues/20234
  • Loading branch information
eileencodes authored and tenderlove committed Feb 23, 2024
1 parent 510404f commit 50ace99
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
2 changes: 1 addition & 1 deletion parse.y
Expand Up @@ -1415,7 +1415,7 @@ last_expr_node(NODE *expr)
if (nd_type_p(expr, NODE_BLOCK)) {
expr = RNODE_BLOCK(RNODE_BLOCK(expr)->nd_end)->nd_head;
}
else if (nd_type_p(expr, NODE_BEGIN)) {
else if (nd_type_p(expr, NODE_BEGIN) && RNODE_BEGIN(expr)->nd_body) {
expr = RNODE_BEGIN(expr)->nd_body;
}
else {
Expand Down
10 changes: 10 additions & 0 deletions test/ruby/test_parse.rb
Expand Up @@ -1109,6 +1109,16 @@ def test_unused_variable
assert_warning('') {o.instance_eval("def marg2((a)); nil; end")}
end

def test_parsing_begin_statement_inside_method_definition
assert_equal :bug_20234, eval("def (begin;end).bug_20234; end")
assert_equal :bug_20234, eval("def (begin;rescue;end).bug_20234; end")
assert_equal :bug_20234, eval("def (begin;ensure;end).bug_20234; end")
assert_equal :bug_20234, eval("def (begin;rescue;else;end).bug_20234; end")

assert_raise(SyntaxError) { eval("def (begin;else;end).bug_20234; end") }
assert_raise(SyntaxError) { eval("def (begin;ensure;else;end).bug_20234; end") }
end

def test_named_capture_conflict
a = 1
assert_warning('') {eval("a = 1; /(?<a>)/ =~ ''")}
Expand Down

0 comments on commit 50ace99

Please sign in to comment.