aboutsummaryrefslogtreecommitdiffstats
path: root/prism/prism.c
diff options
context:
space:
mode:
authorTSUYUSATO Kitsune <make.just.on@gmail.com>2023-11-24 01:29:18 +0900
committergit <svn-admin@ruby-lang.org>2023-11-28 17:27:09 +0000
commitb5796d7b113a78b17e27f2ad23c209f4e2d2900b (patch)
tree72305bb09db658e189711bc6878dc8e880d69159 /prism/prism.c
parentfadd28c7ba6b55ec934f379cfc30a8111e340404 (diff)
downloadruby-b5796d7b113a78b17e27f2ad23c209f4e2d2900b.tar.gz
[ruby/prism] Check circular references in default values of params
Fix https://github.com/ruby/prism/pull/1637 https://github.com/ruby/prism/commit/0172d69cba
Diffstat (limited to 'prism/prism.c')
-rw-r--r--prism/prism.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 1720d9089d..d0cfbef41d 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -4040,11 +4040,22 @@ pm_local_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, c
return node;
}
+static bool context_p(pm_parser_t *parser, pm_context_t context);
+
/**
* Allocate a new LocalVariableReadNode node.
*/
static pm_local_variable_read_node_t *
pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) {
+ pm_constant_id_t name_id = pm_parser_constant_id_token(parser, name);
+
+ if (
+ context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) &&
+ parser->current_param_name == name_id
+ ) {
+ pm_parser_err_token(parser, name, PM_ERR_PARAMETER_CIRCULAR);
+ }
+
pm_local_variable_read_node_t *node = PM_ALLOC_NODE(parser, pm_local_variable_read_node_t);
*node = (pm_local_variable_read_node_t) {
@@ -4052,7 +4063,7 @@ pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name,
.type = PM_LOCAL_VARIABLE_READ_NODE,
.location = PM_LOCATION_TOKEN_VALUE(name)
},
- .name = pm_parser_constant_id_token(parser, name),
+ .name = name_id,
.depth = depth
};
@@ -11596,10 +11607,14 @@ parse_parameters(
if (accept1(parser, PM_TOKEN_EQUAL)) {
pm_token_t operator = parser->previous;
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
+ pm_constant_id_t old_param_name = parser->current_param_name;
+ parser->current_param_name = pm_parser_constant_id_token(parser, &name);
pm_node_t *value = parse_value_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT);
pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value);
pm_parameters_node_optionals_append(params, param);
+
+ parser->current_param_name = old_param_name;
context_pop(parser);
// If parsing the value of the parameter resulted in error recovery,
@@ -11655,7 +11670,10 @@ parse_parameters(
if (token_begins_expression_p(parser->current.type)) {
context_push(parser, PM_CONTEXT_DEFAULT_PARAMS);
+ pm_constant_id_t old_param_name = parser->current_param_name;
+ parser->current_param_name = pm_parser_constant_id_token(parser, &local);
pm_node_t *value = parse_value_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT_KW);
+ parser->current_param_name = old_param_name;
context_pop(parser);
param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value);
}