Skip to content

Commit

Permalink
[Bug #20033] Dynamic regexp should not assign captures
Browse files Browse the repository at this point in the history
  • Loading branch information
nobu committed Dec 1, 2023
1 parent 9d20909 commit 85dc2ad
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 10 deletions.
28 changes: 20 additions & 8 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -4213,11 +4213,28 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
}

static int
compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped)
{
int cnt;

if (!RNODE_DREGX(node)->nd_next) {
VALUE match = RNODE_DREGX(node)->nd_lit;
if (RB_TYPE_P(match, T_REGEXP)) {
if (!popped) {
ADD_INSN1(ret, node, putobject, match);
RB_OBJ_WRITTEN(iseq, Qundef, match);
}
return COMPILE_OK;
}
}

CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
ADD_INSN2(ret, node, toregexp, INT2FIX(RNODE_DREGX(node)->nd_cflag), INT2FIX(cnt));

if (popped) {
ADD_INSN(ret, node, pop);
}

return COMPILE_OK;
}

Expand Down Expand Up @@ -9901,14 +9918,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_EVSTR:
CHECK(compile_evstr(iseq, ret, RNODE_EVSTR(node)->nd_body, popped));
break;
case NODE_DREGX:{
compile_dregx(iseq, ret, node);

if (popped) {
ADD_INSN(ret, node, pop);
}
case NODE_DREGX:
compile_dregx(iseq, ret, node, popped);
break;
}
case NODE_ONCE:{
int ic_index = body->ise_size++;
const rb_iseq_t *block_iseq;
Expand Down
4 changes: 2 additions & 2 deletions parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -12891,8 +12891,8 @@ new_regexp(struct parser_params *p, NODE *node, int options, const YYLTYPE *loc)
}
if (!RNODE_DREGX(node)->nd_next) {
VALUE src = RNODE_DREGX(node)->nd_lit;
nd_set_type(node, NODE_LIT);
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit = reg_compile(p, src, options));
VALUE re = reg_compile(p, src, options);
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_DREGX(node)->nd_lit = re);
}
if (options & RE_OPTION_ONCE) {
node = NEW_ONCE(node, loc);
Expand Down
1 change: 1 addition & 0 deletions test/ruby/test_parse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,7 @@ def test_named_capture_in_block
'(%w();/(?<a>.*)/)',
'(1; (2; 3; (4; /(?<a>.*)/)))',
'(1+1; /(?<a>.*)/)',
'/#{""}(?<a>.*)/',
) do |code, pass|
token = Random.bytes(4).unpack1("H*")
if pass
Expand Down

0 comments on commit 85dc2ad

Please sign in to comment.