[libclang] Fix conversion from `StringRef` to `CXString`

`CXString createRef(StringRef String)` used to return an invalid string when invoked with some empty strings:

If a `StringRef` holds a non-nullptr pointer, for instance, pointing into contents of a larger string, and has a zero length, `createRef` previously returned the entire larger string, ignoring the fact that the actual string passed to it as a param is empty.

This was discovered when invoking `c-index-test` to dump the contents of documentation comments, in case the comment contains an empty HTML attribute, such as `src=""`.

Differential Revision: https://reviews.llvm.org/D133009
This commit is contained in:
Egor Zhdan 2022-08-30 18:43:17 +01:00
parent ad8e4dd2ad
commit 8c09352385
3 changed files with 21 additions and 1 deletions

View File

@ -1,5 +1,7 @@
// RUN: c-index-test -test-load-source-reparse 1 local %s | FileCheck %s
// XFAIL: *
// See PR 21254. We had too few bits to encode command IDs so if you created
// enough of them the ID codes would wrap around. This test creates commands up
// to an ID of 258. Ideally we should check for large numbers, but that would

View File

@ -744,6 +744,15 @@ void comment_to_html_conversion_37();
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[anchor] RenderAnchor Arg[0]=A)))]
/// Aaa ccc<img src="">
void comment_to_html_conversion_40();
// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_40:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa ccc<img src></p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_40</Name><USR>c:@F@comment_to_html_conversion_40#</USR><Declaration>void comment_to_html_conversion_40()</Declaration><Abstract><Para> Aaa ccc<rawHTML><![CDATA[<img src>]]></rawHTML></Para></Abstract></Function>]
// CHECK-NEXT: CommentAST=[
// CHECK-NEXT: (CXComment_FullComment
// CHECK-NEXT: (CXComment_Paragraph
// CHECK-NEXT: (CXComment_Text Text=[ Aaa ccc])
// CHECK-NEXT: (CXComment_HTMLStartTag Name=[img] Attrs: src=)
/// Aaa.
class comment_to_xml_conversion_01 {

View File

@ -78,13 +78,22 @@ CXString createDup(const char *String) {
}
CXString createRef(StringRef String) {
if (!String.data())
return createNull();
// If the string is empty, it might point to a position in another string
// while having zero length. Make sure we don't create a reference to the
// larger string.
if (String.empty())
return createEmpty();
// If the string is not nul-terminated, we have to make a copy.
// FIXME: This is doing a one past end read, and should be removed! For memory
// we don't manage, the API string can become unterminated at any time outside
// our control.
if (!String.empty() && String.data()[String.size()] != 0)
if (String.data()[String.size()] != 0)
return createDup(String);
CXString Result;