https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/152877
Fixes #152829 --- This patch addresses the issue where the preprocessor could crash when parsing `#embed` parameters containing unmatched closing brackets ```cpp #embed "file" prefix(]) #embed "file" prefix(}) ``` >From 6bb7069f535c129157254bbeff8d44972baadbc5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Sat, 9 Aug 2025 22:59:29 +0300 Subject: [PATCH] [Clang] Fixed a crash when parsing #embed parameters with unmatched closing brackets --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Lex/PPDirectives.cpp | 6 +++++- clang/test/Preprocessor/embed_parsing_errors.c | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 0e9fcaa5fac6a..837ef80f07e87 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -282,6 +282,7 @@ Crash and bug fixes ^^^^^^^^^^^^^^^^^^^ - Fixed a crash in the static analyzer that when the expression in an ``[[assume(expr)]]`` attribute was enclosed in parentheses. (#GH151529) +- Fixed a crash when parsing ``#embed`` parameters with unmatched closing brackets. (#GH152829) Improvements ^^^^^^^^^^^^ diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 3fa060f7ec1bd..9d01b8d99e227 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -3793,9 +3793,13 @@ Preprocessor::LexEmbedParameters(Token &CurTok, bool ForHasEmbed) { [[fallthrough]]; case tok::r_brace: case tok::r_square: { + if (BracketStack.empty()) { + ExpectOrDiagAndSkipToEOD(tok::r_paren); + return false; + } tok::TokenKind Matching = GetMatchingCloseBracket(BracketStack.back().first); - if (BracketStack.empty() || CurTok.getKind() != Matching) { + if (CurTok.getKind() != Matching) { DiagMismatchedBracesAndSkipToEOD(Matching, BracketStack.back()); return false; } diff --git a/clang/test/Preprocessor/embed_parsing_errors.c b/clang/test/Preprocessor/embed_parsing_errors.c index 490ec6d4ded2c..a8bbdea91eb16 100644 --- a/clang/test/Preprocessor/embed_parsing_errors.c +++ b/clang/test/Preprocessor/embed_parsing_errors.c @@ -94,6 +94,9 @@ char buffer[] = { #embed "embed_parsing_errors.c" prefix() // OK: tokens within parens are optional #embed "embed_parsing_errors.c" prefix) // expected-error@-1 {{expected '('}} +#embed "embed_parsing_errors.c" prefix()) // expected-error {{expected identifier}} +#embed "embed_parsing_errors.c" prefix(]) // expected-error {{expected ')'}} +#embed "embed_parsing_errors.c" prefix(}) // expected-error {{expected ')'}} #embed "embed_parsing_errors.c" suffix // expected-error@-1 {{expected '('}} @@ -115,6 +118,9 @@ char buffer[] = { #embed "embed_parsing_errors.c" suffix() // OK: tokens within parens are optional #embed "embed_parsing_errors.c" suffix) // expected-error@-1 {{expected '('}} +#embed "embed_parsing_errors.c" suffix()) // expected-error {{expected identifier}} +#embed "embed_parsing_errors.c" suffix(]) // expected-error {{expected ')'}} +#embed "embed_parsing_errors.c" suffix(}) // expected-error {{expected ')'}} #embed "embed_parsing_errors.c" if_empty(1/0) // OK: emitted as tokens, not evaluated yet. #embed "embed_parsing_errors.c" if_empty(([{}])) // OK: delimiters balanced @@ -128,3 +134,6 @@ char buffer[] = { #embed "embed_parsing_errors.c" if_empty) // expected-error@-1 {{expected '('}} }; +#embed "embed_parsing_errors.c" if_empty()) // expected-error {{expected identifier}} +#embed "embed_parsing_errors.c" if_empty(]) // expected-error {{expected ')'}} +#embed "embed_parsing_errors.c" if_empty(}) // expected-error {{expected ')'}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits