From e4182931710dc1d16bec781a92a70e729c4cef36 Mon Sep 17 00:00:00 2001 From: Wen Yuxiang Date: Wed, 19 Aug 2026 13:16:22 +0800 Subject: [PATCH] fix(regex): reject empty unicode brace escape --- string/internal/regex_parser/parser.mbt | 2 ++ string/internal/regex_parser/parser_test.mbt | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/string/internal/regex_parser/parser.mbt b/string/internal/regex_parser/parser.mbt index 66fa7777b5..20d0d52245 100644 --- a/string/internal/regex_parser/parser.mbt +++ b/string/internal/regex_parser/parser.mbt @@ -63,6 +63,7 @@ fn Parser::class_atom( } (rest, Char(c)) } + (re"^\\u", after=_) => raise ctx.error_at(rest, HINT_INVALID_ESCAPE) (re"^\\" + (re"[\^$\\.*+?()\[\]{}|/\"\-:&]" as c), after=rest) => (rest, Char(c.to_int())) (re"^\[:ascii:\]", after=rest) => (rest, Class(posix_cset_ascii)) @@ -289,6 +290,7 @@ fn Parser::term( } (rest, @re.char(@re.RecharSet::char(c)), false) } + (re"^\\u", after=_) => raise ctx.error_at(rest, HINT_INVALID_ESCAPE) (re"^\\" + (re"[\^$\\.*+?()\[\]{}|/\"]" as c), after=rest) => (rest, @re.char(@re.RecharSet::char(c.to_int())), false) (re"^\\.", after=_) => raise ctx.error_at(rest, HINT_INVALID_ESCAPE) diff --git a/string/internal/regex_parser/parser_test.mbt b/string/internal/regex_parser/parser_test.mbt index 78f8047162..b5f57c72a6 100644 --- a/string/internal/regex_parser/parser_test.mbt +++ b/string/internal/regex_parser/parser_test.mbt @@ -894,6 +894,18 @@ test "parse/error_invalid_escape" { ) } +///| +test "parse/error_empty_unicode_brace_escape" { + debug_inspect( + Ok(parse(profile=profile_unicode(), mode=String, "[\\u{}]")) catch { + e => Err(e) + }, + content=( + #|Err(ParserError(at=1, hint="Invalid escape sequence")) + ), + ) +} + ///| test "parse/error_unicode_out_of_range" { debug_inspect(