mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
util: Filter control characters out of log messages
Belts and suspenders: make sure outgoing log messages don't contain potentially suspicious characters, such as terminal control codes. This escapes control characters except newline ('\n') in C syntax. It escapes instead of removes them to still allow for troubleshooting issues where they accidentally end up in strings.
This commit is contained in:
parent
d882f63589
commit
d7820a1250
2 changed files with 41 additions and 1 deletions
|
@ -224,10 +224,32 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str)
|
|||
return strStamped;
|
||||
}
|
||||
|
||||
namespace BCLog {
|
||||
/** Belts and suspenders: make sure outgoing log messages don't contain
|
||||
* potentially suspicious characters, such as terminal control codes.
|
||||
*
|
||||
* This escapes control characters except newline ('\n') in C syntax.
|
||||
* It escapes instead of removes them to still allow for troubleshooting
|
||||
* issues where they accidentally end up in strings.
|
||||
*/
|
||||
std::string LogEscapeMessage(const std::string& str) {
|
||||
std::string ret;
|
||||
for (char ch_in : str) {
|
||||
uint8_t ch = (uint8_t)ch_in;
|
||||
if ((ch >= 32 || ch == '\n') && ch != '\x7f') {
|
||||
ret += ch_in;
|
||||
} else {
|
||||
ret += strprintf("\\x%02x", ch);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void BCLog::Logger::LogPrintStr(const std::string& str)
|
||||
{
|
||||
std::lock_guard<std::mutex> scoped_lock(m_cs);
|
||||
std::string str_prefixed = str;
|
||||
std::string str_prefixed = LogEscapeMessage(str);
|
||||
|
||||
if (m_log_threadnames && m_started_new_line) {
|
||||
str_prefixed.insert(0, "[" + util::ThreadGetInternalName() + "] ");
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
/* defined in logging.cpp */
|
||||
namespace BCLog {
|
||||
std::string LogEscapeMessage(const std::string& str);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(util_criticalsection)
|
||||
|
@ -1696,4 +1701,17 @@ BOOST_AUTO_TEST_CASE(test_spanparsing)
|
|||
BOOST_CHECK_EQUAL(SpanToStr(results[3]), "");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_LogEscapeMessage)
|
||||
{
|
||||
// ASCII and UTF-8 must pass through unaltered.
|
||||
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Valid log message貓"), "Valid log message貓");
|
||||
// Newlines must pass through unaltered.
|
||||
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("Message\n with newlines\n"), "Message\n with newlines\n");
|
||||
// Other control characters are escaped in C syntax.
|
||||
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage("\x01\x7f Corrupted log message\x0d"), R"(\x01\x7f Corrupted log message\x0d)");
|
||||
// Embedded NULL characters are escaped too.
|
||||
const std::string NUL("O\x00O", 3);
|
||||
BOOST_CHECK_EQUAL(BCLog::LogEscapeMessage(NUL), R"(O\x00O)");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Add table
Reference in a new issue