Skip to content

Commit

Permalink
Disallow assigning to numbered parameters in regexp
Browse files Browse the repository at this point in the history
  • Loading branch information
kddnewton committed Nov 1, 2023
1 parent e03b438 commit ec41942
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
21 changes: 16 additions & 5 deletions src/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -15359,21 +15359,32 @@ parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t *

for (size_t index = 0; index < named_captures.length; index++) {
pm_string_t *name = &named_captures.strings[index];
pm_constant_id_t local;

const uint8_t *source = pm_string_source(name);
size_t length = pm_string_length(name);

pm_constant_id_t local;
if (content->type == PM_STRING_SHARED) {
// If the unescaped string is a slice of the source, then we can
// copy the names directly. The pointers will line up.
local = pm_parser_local_add_location(parser, name->source, name->source + name->length);
local = pm_parser_local_add_location(parser, source, source + length);

if (token_is_numbered_parameter(source, source + length)) {
pm_parser_err(parser, source, source + length, PM_ERR_PARAMETER_NUMBERED_RESERVED);
}
} else {
// Otherwise, the name is a slice of the malloc-ed owned string,
// in which case we need to copy it out into a new string.
size_t length = pm_string_length(name);

void *memory = malloc(length);
memcpy(memory, pm_string_source(name), length);
if (memory == NULL) abort();

memcpy(memory, source, length);
local = pm_parser_local_add_owned(parser, (const uint8_t *) memory, length);

if (token_is_numbered_parameter(source, source + length)) {
const pm_location_t *location = &call->receiver->location;
pm_parser_err_location(parser, location, PM_ERR_PARAMETER_NUMBERED_RESERVED);
}
}

pm_constant_id_list_append(&match->locals, local);
Expand Down
16 changes: 10 additions & 6 deletions test/prism/errors_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1390,17 +1390,21 @@ def test_repeated_parameter_name_in_destructured_params
end

def test_assign_to_numbered_parameter
source = "
source = <<~RUBY
a in _1
a => _1
1 => a, _1
1 in a, _1
"
/(?<_1>)/ =~ a
RUBY

message = "Token reserved for a numbered parameter"
assert_errors expression(source), source, [
["Token reserved for a numbered parameter", 14..16],
["Token reserved for a numbered parameter", 30..32],
["Token reserved for a numbered parameter", 49..51],
["Token reserved for a numbered parameter", 68..70],
[message, 5..7],
[message, 13..15],
[message, 24..26],
[message, 35..37],
[message, 42..44]
]
end

Expand Down

0 comments on commit ec41942

Please sign in to comment.