[PATCH] Use the same set of whitespace characters for all operations in BreakableToken.
Alexander Kornienko
alexfh at google.com
Thu Jun 20 06:49:19 PDT 2013
Hi klimek,
Fixes a problem where \t,\v or \f could lead to a crash when placed as
a first character in a line comment. The cause is that rtrim and ltrim handle
these characters, but our code didn't, so some invariants could be broken.
http://llvm-reviews.chandlerc.com/D1013
Files:
lib/Format/BreakableToken.cpp
unittests/Format/FormatTest.cpp
Index: lib/Format/BreakableToken.cpp
===================================================================
--- lib/Format/BreakableToken.cpp
+++ lib/Format/BreakableToken.cpp
@@ -26,6 +26,19 @@
namespace format {
namespace {
+static const char *Blanks = " \t\v\f";
+static bool IsBlank(char C) {
+ switch (C) {
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ return true;
+ default:
+ return false;
+ }
+}
+
BreakableToken::Split getCommentSplit(StringRef Text,
unsigned ContentStartColumn,
unsigned ColumnLimit,
@@ -41,22 +54,22 @@
MaxSplitBytes +=
encoding::getCodePointNumBytes(Text[MaxSplitBytes], Encoding);
- StringRef::size_type SpaceOffset = Text.rfind(' ', MaxSplitBytes);
+ StringRef::size_type SpaceOffset = Text.find_last_of(Blanks, MaxSplitBytes);
if (SpaceOffset == StringRef::npos ||
// Don't break at leading whitespace.
- Text.find_last_not_of(' ', SpaceOffset) == StringRef::npos) {
+ Text.find_last_not_of(Blanks, SpaceOffset) == StringRef::npos) {
// Make sure that we don't break at leading whitespace that
// reaches past MaxSplit.
- StringRef::size_type FirstNonWhitespace = Text.find_first_not_of(" ");
+ StringRef::size_type FirstNonWhitespace = Text.find_first_not_of(Blanks);
if (FirstNonWhitespace == StringRef::npos)
// If the comment is only whitespace, we cannot split.
return BreakableToken::Split(StringRef::npos, 0);
- SpaceOffset =
- Text.find(' ', std::max<unsigned>(MaxSplitBytes, FirstNonWhitespace));
+ SpaceOffset = Text.find_first_of(
+ Blanks, std::max<unsigned>(MaxSplitBytes, FirstNonWhitespace));
}
if (SpaceOffset != StringRef::npos && SpaceOffset != 0) {
- StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim();
- StringRef AfterCut = Text.substr(SpaceOffset).ltrim();
+ StringRef BeforeCut = Text.substr(0, SpaceOffset).rtrim(Blanks);
+ StringRef AfterCut = Text.substr(SpaceOffset).ltrim(Blanks);
return BreakableToken::Split(BeforeCut.size(),
AfterCut.begin() - BeforeCut.end());
}
@@ -92,11 +105,11 @@
if (Chars > MaxSplit)
break;
- if (Text[0] == ' ')
+ if (IsBlank(Text[0]))
SpaceOffset = SplitPoint;
if (Text[0] == '/')
SlashOffset = SplitPoint;
- if (Text[0] != '\\' && !isAlphanumeric(Text[0]))
+ if (Advance == 1 && !isAlphanumeric(Text[0]))
WordStartOffset = SplitPoint;
SplitPoint += Advance;
@@ -280,13 +293,13 @@
// Calculate the end of the non-whitespace text in the previous line.
EndOfPreviousLine =
- Lines[LineIndex - 1].find_last_not_of(" \t", EndOfPreviousLine);
+ Lines[LineIndex - 1].find_last_not_of(Blanks, EndOfPreviousLine);
if (EndOfPreviousLine == StringRef::npos)
EndOfPreviousLine = 0;
else
++EndOfPreviousLine;
// Calculate the start of the non-whitespace text in the current line.
- size_t StartOfLine = Lines[LineIndex].find_first_not_of(" \t");
+ size_t StartOfLine = Lines[LineIndex].find_first_not_of(Blanks);
if (StartOfLine == StringRef::npos)
StartOfLine = Lines[LineIndex].size();
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -893,6 +893,9 @@
" int bbb, // xxxxxxx yyyyyyyyy\n"
" int c, int d, int e) {}",
getLLVMStyleWithColumns(40)));
+ EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ getLLVMStyleWithColumns(20)));
}
TEST_F(FormatTest, PriorityOfCommentBreaking) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1013.1.patch
Type: text/x-patch
Size: 3828 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130620/a9d1ba1a/attachment.bin>
More information about the cfe-commits
mailing list