summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2025-03-29 15:25:02 +0900
committernagachika <nagachika@ruby-lang.org>2025-03-29 15:32:49 +0900
commit770060f7662698ca74bc28428919a688b8fe06d2 (patch)
treec4e9f9b21976bc516f2eb2e1271e193b4a6fd1f2
parentd2eda78e4091a99c1a387d43967af5794d8eac70 (diff)
merge revision(s) 1acfb29015dbc38fd345d8786aa78aad59f7dcd1: [Backport #21186]
[Bug #21186] multibyte char literal should be a single letter word
-rw-r--r--parse.y13
-rw-r--r--test/ruby/test_parse.rb2
-rw-r--r--version.h2
3 files changed, 9 insertions, 8 deletions
diff --git a/parse.y b/parse.y
index baf391e52d..f84320b4b4 100644
--- a/parse.y
+++ b/parse.y
@@ -9884,6 +9884,7 @@ parse_qmark(struct parser_params *p, int space_seen)
rb_encoding *enc;
register int c;
VALUE lit;
+ const char *start = p->lex.pcur;
if (IS_END()) {
SET_LEX_STATE(EXPR_VALUE);
@@ -9908,13 +9909,11 @@ parse_qmark(struct parser_params *p, int space_seen)
}
newtok(p);
enc = p->enc;
- if (!parser_isascii(p)) {
- if (tokadd_mbchar(p, c) == -1) return 0;
- }
- else if ((rb_enc_isalnum(c, p->enc) || c == '_') &&
- !lex_eol_p(p) && is_identchar(p, p->lex.pcur, p->lex.pend, p->enc)) {
+ int w = parser_precise_mbclen(p, start);
+ if (is_identchar(p, start, p->lex.pend, p->enc) &&
+ !(lex_eol_ptr_n_p(p, start, w) || !is_identchar(p, start + w, p->lex.pend, p->enc))) {
if (space_seen) {
- const char *start = p->lex.pcur - 1, *ptr = start;
+ const char *ptr = start;
do {
int n = parser_precise_mbclen(p, ptr);
if (n < 0) return -1;
@@ -9942,7 +9941,7 @@ parse_qmark(struct parser_params *p, int space_seen)
}
}
else {
- tokadd(p, c);
+ if (tokadd_mbchar(p, c) == -1) return 0;
}
tokfix(p);
lit = STR_NEW3(tok(p), toklen(p), enc, 0);
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 341d63c38a..28cd5bf1f0 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -631,6 +631,8 @@ class TestParse < Test::Unit::TestCase
assert_equal("\u{1234}", eval('?\u{1234}'))
assert_equal("\u{1234}", eval('?\u1234'))
assert_syntax_error('?\u{41 42}', 'Multiple codepoints at single character literal')
+ assert_syntax_error("?and", /unexpected '\?'/)
+ assert_syntax_error("?\u1234and", /unexpected '\?'/)
e = assert_syntax_error('"#{?\u123}"', 'invalid Unicode escape')
assert_not_match(/end-of-input/, e.message)
diff --git a/version.h b/version.h
index 4a81276a08..7d9016b449 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 7
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 136
+#define RUBY_PATCHLEVEL 137
#include "ruby/version.h"
#include "ruby/internal/abi.h"