Skip to content

Commit 6f0d60b

Browse files
committed
Reject END { next } as well
Followup for https://bugs.ruby-lang.org/issues/20409
1 parent bf01f6a commit 6f0d60b

6 files changed

Lines changed: 18 additions & 36 deletions

File tree

parse.y

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,22 +1659,7 @@ static NODE *add_block_exit(struct parser_params *p, NODE *node);
16591659
static rb_node_exits_t *init_block_exit(struct parser_params *p);
16601660
static rb_node_exits_t *allow_block_exit(struct parser_params *p);
16611661
static void restore_block_exit(struct parser_params *p, rb_node_exits_t *exits);
1662-
static void clear_block_exit(struct parser_params *p, unsigned int error_mask);
1663-
1664-
static unsigned int
1665-
exits_mask(enum node_type t)
1666-
{
1667-
switch (t) {
1668-
case NODE_BREAK:
1669-
case NODE_NEXT:
1670-
case NODE_REDO:
1671-
return 1u << (t - NODE_BREAK);
1672-
default:
1673-
UNREACHABLE_RETURN(0);
1674-
}
1675-
}
1676-
1677-
#define EXITS_MASK_ALL (exits_mask(NODE_BREAK)|exits_mask(NODE_NEXT)|exits_mask(NODE_REDO))
1662+
static void clear_block_exit(struct parser_params *p, bool error);
16781663

16791664
static void
16801665
next_rescue_context(struct lex_context *next, const struct lex_context *outer, enum rescue_context def)
@@ -1692,7 +1677,7 @@ restore_defun(struct parser_params *p, rb_node_def_temp_t *temp)
16921677
p->ctxt.in_rescue = ctxt.in_rescue;
16931678
p->max_numparam = temp->save.max_numparam;
16941679
numparam_pop(p, temp->save.numparam_save);
1695-
clear_block_exit(p, EXITS_MASK_ALL);
1680+
clear_block_exit(p, true);
16961681
}
16971682

16981683
static void
@@ -1849,23 +1834,20 @@ restore_block_exit(struct parser_params *p, rb_node_exits_t *exits)
18491834
}
18501835

18511836
static void
1852-
clear_block_exit(struct parser_params *p, unsigned int error_mask)
1837+
clear_block_exit(struct parser_params *p, bool error)
18531838
{
18541839
rb_node_exits_t *exits = p->exits;
18551840
if (!exits) return;
1856-
if (error_mask) {
1841+
if (error) {
18571842
for (NODE *e = RNODE(exits); (e = RNODE_EXITS(e)->nd_chain) != 0; ) {
18581843
switch (nd_type(e)) {
18591844
case NODE_BREAK:
1860-
if (!(error_mask & exits_mask(NODE_BREAK))) break;
18611845
yyerror1(&e->nd_loc, "Invalid break");
18621846
break;
18631847
case NODE_NEXT:
1864-
if (!(error_mask & exits_mask(NODE_NEXT))) break;
18651848
yyerror1(&e->nd_loc, "Invalid next");
18661849
break;
18671850
case NODE_REDO:
1868-
if (!(error_mask & exits_mask(NODE_REDO))) break;
18691851
yyerror1(&e->nd_loc, "Invalid redo");
18701852
break;
18711853
default:
@@ -3230,7 +3212,7 @@ top_stmts : none
32303212

32313213
top_stmt : stmt
32323214
{
3233-
clear_block_exit(p, EXITS_MASK_ALL);
3215+
clear_block_exit(p, true);
32343216
$$ = $1;
32353217
}
32363218
| keyword_BEGIN begin_block
@@ -3370,7 +3352,7 @@ stmt : keyword_alias[kw] fitem[new] {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fit
33703352
}
33713353
| stmt[body] modifier_while[mod] expr_value[cond_expr]
33723354
{
3373-
clear_block_exit(p, 0);
3355+
clear_block_exit(p, false);
33743356
if ($body && nd_type_p($body, NODE_BEGIN)) {
33753357
$$ = NEW_WHILE(cond(p, $cond_expr, &@cond_expr), RNODE_BEGIN($body)->nd_body, 0, &@$, &@mod, &NULL_LOC);
33763358
}
@@ -3401,7 +3383,7 @@ stmt : keyword_alias[kw] fitem[new] {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fit
34013383
}
34023384
| k_END[k_end] block_open[lbrace] compstmt(stmts)[body] '}'[rbrace]
34033385
{
3404-
clear_block_exit(p, exits_mask(NODE_BREAK) | exits_mask(NODE_REDO));
3386+
clear_block_exit(p, true);
34053387
restore_block_exit(p, $block_open);
34063388
p->ctxt = $k_end;
34073389
{

prism/prism.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15332,9 +15332,6 @@ parse_block_exit(pm_parser_t *parser, pm_node_t *node) {
1533215332
if (parser->version < PM_OPTIONS_VERSION_CRUBY_4_1) {
1533315333
return;
1533415334
}
15335-
if (PM_NODE_TYPE_P(node, PM_NEXT_NODE)) {
15336-
return;
15337-
}
1533815335
}
1533915336
PRISM_FALLTHROUGH
1534015337
case PM_CONTEXT_DEF:

test/prism/errors/4.1/end_block_exit.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ END {
33
^~~~~ Invalid break
44
}
55

6+
END {
7+
next
8+
^~~~ Invalid next
9+
}
10+

test/prism/fixtures/3.3-4.0/end_block_exit.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ END {
55
END {
66
break
77
}
8+
9+
END {
10+
next
11+
}

test/prism/fixtures/end_block_exit.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.

test/ruby/test_ast.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,8 @@ def test_invalid_exit
255255
assert_invalid_parse(msg, "#{code}")
256256
assert_invalid_parse(msg, "def m; #{code}; end")
257257
assert_invalid_parse(msg, "begin; #{code}; end")
258-
if code.start_with?("next")
259-
assert_parse("END {#{code}}")
260-
else
261-
assert_invalid_parse(msg, "END {#{code}}")
262-
end
258+
assert_invalid_parse(msg, "BEGIN {#{code}}")
259+
assert_invalid_parse(msg, "END {#{code}}")
263260

264261
assert_parse("!defined?(#{code})")
265262
assert_parse("def m; defined?(#{code}); end")

0 commit comments

Comments
 (0)