From 4387af1b4a16fbd181a7c42424ffb8cf92d55110 Mon Sep 17 00:00:00 2001 From: Haldun Bayhantopcu Date: Wed, 11 Oct 2023 23:35:14 +0200 Subject: [PATCH] [ruby/prism] Fix parsing symbols in strings after labels https://github.com/ruby/prism/commit/e16531650d --- prism/prism.c | 5 +++-- test/prism/errors_test.rb | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/prism/prism.c b/prism/prism.c index a733e1f1e3..99cfe17c4f 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -11381,6 +11381,7 @@ static inline pm_node_t * parse_strings(pm_parser_t *parser) { assert(parser->current.type == PM_TOKEN_STRING_BEGIN); pm_node_t *result = NULL; + bool state_is_arg_labeled = lex_state_p(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED); while (match1(parser, PM_TOKEN_STRING_BEGIN)) { pm_node_t *node = NULL; @@ -11437,7 +11438,7 @@ parse_strings(pm_parser_t *parser) { expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM); node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); - } else if (accept1(parser, PM_TOKEN_LABEL_END)) { + } else if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) { node = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); } else { expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM); @@ -11471,7 +11472,7 @@ parse_strings(pm_parser_t *parser) { } } - if (accept1(parser, PM_TOKEN_LABEL_END)) { + if (accept1(parser, PM_TOKEN_LABEL_END) && !state_is_arg_labeled) { node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); } else { expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM); diff --git a/test/prism/errors_test.rb b/test/prism/errors_test.rb index 8a88270b44..e2f56ff07e 100644 --- a/test/prism/errors_test.rb +++ b/test/prism/errors_test.rb @@ -1404,6 +1404,20 @@ module Prism ] end + def test_symbol_in_keyword_parameter + source = "def foo(x:'y':); end" + assert_errors expression(source), source, [ + ["Expected a closing delimiter for the string literal", 14..14], + ] + end + + def test_symbol_in_hash + source = "{x:'y':}" + assert_errors expression(source), source, [ + ["Expected a closing delimiter for the string literal", 7..7], + ] + end + private def assert_errors(expected, source, errors, compare_ripper: RUBY_ENGINE == "ruby")