llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-format

Author: r4nt

<details>
<summary>Changes</summary>

In UnwrappedLineParser::parseFile(), TextProto and Json inputs are parsed by 
calling parseBracedList() directly instead of parseLevel(). Previously, 
parseBracedList() returned early before eof() in two cases:
1. Encountering a semicolon (even though TextFormat protobufs allow ';' as an 
optional field separator), which returned false without consuming the token and 
unwound all enclosing parseBracedList() calls.
2. Encountering an unmatched closing '}' (e.g. in partial R"pb(...)pb" raw 
string fragments concatenated via StrCat), which returned after consuming '}' 
and left any remaining tokens unconsumed.

Both cases triggered the assert(eof()) in UnwrappedLineParser::parse().

---
Full diff: https://github.com/llvm/llvm-project/pull/234527.diff


2 Files Affected:

- (modified) clang/lib/Format/UnwrappedLineParser.cpp (+5-3) 
- (modified) clang/unittests/Format/FormatTestTextProto.cpp (+19) 


``````````diff
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp 
b/clang/lib/Format/UnwrappedLineParser.cpp
index 1b00e9015ea6e..e5603feb37977 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -277,7 +277,8 @@ void UnwrappedLineParser::parseFile() {
   ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
                                           MustBeDeclaration);
   if (Style.isTextProto() || (Style.isJson() && FormatTok->IsFirst))
-    parseBracedList();
+    while (!eof())
+      parseBracedList();
   else
     parseLevel();
   // Make sure to format the remaining tokens.
@@ -2670,10 +2671,11 @@ bool UnwrappedLineParser::parseBracedList(bool 
IsAngleBracket, bool IsEnum) {
       break;
     case tok::semi:
       // JavaScript (or more precisely TypeScript) can have semicolons in 
braced
-      // lists (in so-called TypeMemberLists). Thus, the semicolon cannot be
+      // lists (in so-called TypeMemberLists). TextProto and Proto options also
+      // allow semicolons as field separators. Thus, the semicolon cannot be
       // used for error recovery if we have otherwise determined that this is
       // a braced list.
-      if (Style.isJavaScript()) {
+      if (Style.isJavaScript() || Style.isProto() || Style.isJson()) {
         nextToken();
         break;
       }
diff --git a/clang/unittests/Format/FormatTestTextProto.cpp 
b/clang/unittests/Format/FormatTestTextProto.cpp
index 6cddb838a0abe..f919af5b78dd8 100644
--- a/clang/unittests/Format/FormatTestTextProto.cpp
+++ b/clang/unittests/Format/FormatTestTextProto.cpp
@@ -721,6 +721,25 @@ TEST_F(FormatTestTextProto, KeepsAmpersandsNextToKeys) {
                "}");
 }
 
+TEST_F(FormatTestTextProto, SupportsSemicolonSeparators) {
+  verifyFormat("field_a: OK; field_b: OK");
+  verifyFormat("field_a: OK;\n"
+               "field_b { field_c: OK };\n"
+               "field_d: OKOKOK;\n"
+               "field_e: OK");
+  verifyFormat("msg_field <\n"
+               "  field_a: OK;\n"
+               "  field_b: <>;\n"
+               "  field_c: OK\n"
+               ">");
+}
+
+TEST_F(FormatTestTextProto, DoesNotCrashOnUnmatchedClosingBrace) {
+  verifyNoCrash("field_a: 1 } field_b: 2");
+  verifyNoCrash("} field_a: 1");
+  verifyNoCrash("msg { field_a: 1 } } field_b: 2");
+}
+
 } // namespace
 } // namespace test
 } // namespace format

``````````

</details>


https://github.com/llvm/llvm-project/pull/234527
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to