From 4182c988c97c14fb0ccd7e99a76fe7583681eb1b Mon Sep 17 00:00:00 2001 From: eileencodes Date: Tue, 17 Oct 2023 13:13:37 -0400 Subject: [PATCH] Ensure last encoding flag wins You can't encoding a string with more than one encoding so ensure that the last one wins. --- src/prism.c | 11 +++++++---- test/prism/regexp_test.rb | 12 ++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/prism.c b/src/prism.c index 34c4abf9e9a..56b2252c688 100644 --- a/src/prism.c +++ b/src/prism.c @@ -779,6 +779,7 @@ parse_decimal_number(pm_parser_t *parser, const uint8_t *start, const uint8_t *e static inline pm_node_flags_t pm_regular_expression_flags_create(const pm_token_t *closing) { pm_node_flags_t flags = 0; + pm_node_flags_t mask = (uint16_t) 0xFF0F; if (closing->type == PM_TOKEN_REGEXP_END) { for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) { @@ -786,11 +787,13 @@ pm_regular_expression_flags_create(const pm_token_t *closing) { case 'i': flags |= PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break; case 'm': flags |= PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break; case 'x': flags |= PM_REGULAR_EXPRESSION_FLAGS_EXTENDED; break; - case 'e': flags |= PM_REGULAR_EXPRESSION_FLAGS_EUC_JP; break; - case 'n': flags |= PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break; - case 's': flags |= PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break; - case 'u': flags |= PM_REGULAR_EXPRESSION_FLAGS_UTF_8; break; case 'o': flags |= PM_REGULAR_EXPRESSION_FLAGS_ONCE; break; + + case 'e': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_EUC_JP; break; + case 'n': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break; + case 's': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break; + case 'u': flags &= mask; flags |= PM_REGULAR_EXPRESSION_FLAGS_UTF_8; break; + default: assert(false && "unreachable"); } } diff --git a/test/prism/regexp_test.rb b/test/prism/regexp_test.rb index 67114c7bf3d..0a5fc2b4fc4 100644 --- a/test/prism/regexp_test.rb +++ b/test/prism/regexp_test.rb @@ -227,6 +227,18 @@ def test_flag_combined assert_equal(value, options("mix")) end + def test_last_encoding_option_wins + regex = "/foo/nu" + option = Prism.parse(regex).value.statements.body.first.options + + assert_equal Regexp::FIXEDENCODING, option + + regex = "/foo/un" + option = Prism.parse(regex).value.statements.body.first.options + + assert_equal Regexp::NOENCODING, option + end + private def named_captures(source)