]> granicus.if.org Git - clang/commitdiff
Comment parsing: close a hole in CDATA escaping in XML output
authorDmitri Gribenko <gribozavr@gmail.com>
Tue, 22 Apr 2014 12:34:52 +0000 (12:34 +0000)
committerDmitri Gribenko <gribozavr@gmail.com>
Tue, 22 Apr 2014 12:34:52 +0000 (12:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@206886 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Index/CommentToXML.cpp
test/Index/comment-to-html-xml-conversion.cpp

index 377440f81d58ca61cbf37e217752998f5a94e35c..4f5c0745d7279801d9fa210a79798fe6e00202fe 100644 (file)
@@ -563,6 +563,7 @@ public:
 
   // Helpers.
   void appendToResultWithXMLEscaping(StringRef S);
+  void appendToResultWithCDATAEscaping(StringRef S);
 
   void formatTextOfDeclaration(const DeclInfo *DI,
                                SmallString<128> &Declaration);
@@ -670,9 +671,16 @@ void CommentASTToXMLConverter::visitHTMLStartTagComment(
   Result << "<rawHTML";
   if (C->isSafeToPassThrough())
     Result << " isSafeToPassThrough=\"1\"";
-  Result << "><![CDATA[";
-  printHTMLStartTagComment(C, Result);
-  Result << "]]></rawHTML>";
+  Result << ">";
+  {
+    SmallString<32> Tag;
+    {
+      llvm::raw_svector_ostream TagOS(Tag);
+      printHTMLStartTagComment(C, TagOS);
+    }
+    appendToResultWithCDATAEscaping(Tag);
+  }
+  Result << "</rawHTML>";
 }
 
 void
@@ -1106,6 +1114,28 @@ void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
   }
 }
 
+void CommentASTToXMLConverter::appendToResultWithCDATAEscaping(StringRef S) {
+  if (S.empty())
+    return;
+
+  Result << "<![CDATA[";
+  while (!S.empty()) {
+    size_t Pos = S.find("]]>");
+    if (Pos == 0) {
+      Result << "]]]]><![CDATA[>";
+      S = S.drop_front(3);
+      continue;
+    }
+    if (Pos == StringRef::npos)
+      Pos = S.size();
+
+    Result << S.substr(0, Pos);
+
+    S = S.drop_front(Pos);
+  }
+  Result << "]]>";
+}
+
 void CommentToXMLConverter::convertCommentToHTML(const FullComment *FC,
                                                  SmallVectorImpl<char> &HTML,
                                                  const ASTContext &Context) {
index 590e18719741546a6197732f5cf687d580e71149..f93126b1e552cc24d95e21f3fb1ebd39ac2f0f6e 100644 (file)
@@ -721,6 +721,18 @@ void comment_to_html_conversion_35();
 // CHECK-NEXT:         (CXComment_Text Text=[Γ])
 // CHECK-NEXT:         (CXComment_Text Text=[ Greek letter Gamma Γ.])))]
 
+/// <h1 id="]]>">Aaa</h1>
+void comment_to_html_conversion_36();
+
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_36:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <h1 id="]]>">Aaa</h1></p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_36</Name><USR>c:@F@comment_to_html_conversion_36#</USR><Declaration>void comment_to_html_conversion_36()</Declaration><Abstract><Para> <rawHTML isSafeToPassThrough="1"><![CDATA[<h1 id="]]]]><![CDATA[>">]]></rawHTML>Aaa<rawHTML isSafeToPassThrough="1">&lt;/h1&gt;</rawHTML></Para></Abstract></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_HTMLStartTag Name=[h1] Attrs: id=]]>)
+// CHECK-NEXT:         (CXComment_Text Text=[Aaa])
+// CHECK-NEXT:         (CXComment_HTMLEndTag Name=[h1])))]
+
 
 /// Aaa.
 class comment_to_xml_conversion_01 {