Skip to content

Commit

Permalink
Fix some crashes and deadlocks in FormatAnsiTerminalCodes
Browse files Browse the repository at this point in the history
Summary:
This patch fixes a few problems with the FormatAnsiTerminalCodes function:

* It does an infinite loop on an unknown color value.
* It crashes when the color value is at the end of the string.
* It deletes the first character behind the color token.

Also added a few tests that reproduce those problems (and test some other corner cases).

Reviewers: davide, labath

Reviewed By: labath

Subscribers: labath, lldb-commits, mgorny

Differential Revision: https://reviews.llvm.org/D49307

llvm-svn: 337189
  • Loading branch information
Teemperor committed Jul 16, 2018
1 parent 94d8408 commit 2d42579
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
10 changes: 7 additions & 3 deletions lldb/include/lldb/Utility/AnsiTerminal.h
Expand Up @@ -119,17 +119,21 @@ inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
break;
}

bool found_code = false;
for (const auto &code : codes) {
if (!right.consume_front(code.name))
continue;

if (do_color)
fmt.append(code.value);
format = right;
found_code = true;
break;
}

format = format.drop_front();
format = right;
// If we haven't found a valid replacement value, we just copy the string
// to the result without any modifications.
if (!found_code)
fmt.append(tok_hdr);
}
return fmt;
}
Expand Down
55 changes: 55 additions & 0 deletions lldb/unittests/Utility/AnsiTerminalTest.cpp
@@ -0,0 +1,55 @@
//===-- AnsiTerminalTest.cpp ------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"

#include "lldb/Utility/AnsiTerminal.h"

using namespace lldb_utility;

TEST(AnsiTerminal, Empty) { EXPECT_EQ("", ansi::FormatAnsiTerminalCodes("")); }

TEST(AnsiTerminal, WhiteSpace) {
EXPECT_EQ(" ", ansi::FormatAnsiTerminalCodes(" "));
}

TEST(AnsiTerminal, AtEnd) {
EXPECT_EQ("abc\x1B[30m",
ansi::FormatAnsiTerminalCodes("abc${ansi.fg.black}"));
}

TEST(AnsiTerminal, AtStart) {
EXPECT_EQ("\x1B[30mabc",
ansi::FormatAnsiTerminalCodes("${ansi.fg.black}abc"));
}

TEST(AnsiTerminal, KnownPrefix) {
EXPECT_EQ("${ansi.fg.redish}abc",
ansi::FormatAnsiTerminalCodes("${ansi.fg.redish}abc"));
}

TEST(AnsiTerminal, Unknown) {
EXPECT_EQ("${ansi.fg.foo}abc",
ansi::FormatAnsiTerminalCodes("${ansi.fg.foo}abc"));
}

TEST(AnsiTerminal, Incomplete) {
EXPECT_EQ("abc${ansi.", ansi::FormatAnsiTerminalCodes("abc${ansi."));
}

TEST(AnsiTerminal, Twice) {
EXPECT_EQ("\x1B[30m\x1B[31mabc",
ansi::FormatAnsiTerminalCodes("${ansi.fg.black}${ansi.fg.red}abc"));
}

TEST(AnsiTerminal, Basic) {
EXPECT_EQ(
"abc\x1B[31mabc\x1B[0mabc",
ansi::FormatAnsiTerminalCodes("abc${ansi.fg.red}abc${ansi.normal}abc"));
}
1 change: 1 addition & 0 deletions lldb/unittests/Utility/CMakeLists.txt
@@ -1,4 +1,5 @@
add_lldb_unittest(UtilityTests
AnsiTerminalTest.cpp
ArgsTest.cpp
OptionsWithRawTest.cpp
ArchSpecTest.cpp
Expand Down

0 comments on commit 2d42579

Please sign in to comment.