From 52e127280bacf19f38284c68149351f192e71e5d Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 1 Nov 2023 09:51:03 -0400 Subject: [PATCH] [ruby/prism] Disallow assigning to numbered parameters in regexp https://github.com/ruby/prism/commit/ec419422f8 --- prism/prism.c | 21 ++++++++++++++++----- test/prism/errors_test.rb | 16 ++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/prism/prism.c b/prism/prism.c index 8ac30c43d1..42d9712063 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -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); diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 726bb14303..aeea04d04d 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -1390,17 +1390,21 @@ module Prism 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