File tree Expand file tree Collapse file tree 2 files changed +41
-1
lines changed
Expand file tree Collapse file tree 2 files changed +41
-1
lines changed Original file line number Diff line number Diff line change @@ -224,10 +224,32 @@ std::string BCLog::Logger::LogTimestampStr(const std::string& str)
224224 return strStamped;
225225}
226226
227+ namespace BCLog {
228+ /* * Belts and suspenders: make sure outgoing log messages don't contain
229+ * potentially suspicious characters, such as terminal control codes.
230+ *
231+ * This escapes control characters except newline ('\n') in C syntax.
232+ * It escapes instead of removes them to still allow for troubleshooting
233+ * issues where they accidentally end up in strings.
234+ */
235+ std::string LogEscapeMessage (const std::string& str) {
236+ std::string ret;
237+ for (char ch_in : str) {
238+ uint8_t ch = (uint8_t )ch_in;
239+ if ((ch >= 32 || ch == ' \n ' ) && ch != ' \x7f ' ) {
240+ ret += ch_in;
241+ } else {
242+ ret += strprintf (" \\ x%02x" , ch);
243+ }
244+ }
245+ return ret;
246+ }
247+ }
248+
227249void BCLog::Logger::LogPrintStr (const std::string& str)
228250{
229251 std::lock_guard<std::mutex> scoped_lock (m_cs);
230- std::string str_prefixed = str;
252+ std::string str_prefixed = LogEscapeMessage ( str) ;
231253
232254 if (m_log_threadnames && m_started_new_line) {
233255 str_prefixed.insert (0 , " [" + util::ThreadGetInternalName () + " ] " );
Original file line number Diff line number Diff line change 2525
2626#include < boost/test/unit_test.hpp>
2727
28+ /* defined in logging.cpp */
29+ namespace BCLog {
30+ std::string LogEscapeMessage (const std::string& str);
31+ }
32+
2833BOOST_FIXTURE_TEST_SUITE (util_tests, BasicTestingSetup)
2934
3035BOOST_AUTO_TEST_CASE(util_criticalsection)
@@ -1572,4 +1577,17 @@ BOOST_AUTO_TEST_CASE(test_Capitalize)
15721577 BOOST_CHECK_EQUAL (Capitalize (" \x00\xfe\xff " ), " \x00\xfe\xff " );
15731578}
15741579
1580+ BOOST_AUTO_TEST_CASE (test_LogEscapeMessage)
1581+ {
1582+ // ASCII and UTF-8 must pass through unaltered.
1583+ BOOST_CHECK_EQUAL (BCLog::LogEscapeMessage (" Valid log message貓" ), " Valid log message貓" );
1584+ // Newlines must pass through unaltered.
1585+ BOOST_CHECK_EQUAL (BCLog::LogEscapeMessage (" Message\n with newlines\n " ), " Message\n with newlines\n " );
1586+ // Other control characters are escaped in C syntax.
1587+ BOOST_CHECK_EQUAL (BCLog::LogEscapeMessage (" \x01\x7f Corrupted log message\x0d " ), R"( \x01\x7f Corrupted log message\x0d)" );
1588+ // Embedded NULL characters are escaped too.
1589+ const std::string NUL (" O\x00 O" , 3 );
1590+ BOOST_CHECK_EQUAL (BCLog::LogEscapeMessage (NUL), R"( O\x00O)" );
1591+ }
1592+
15751593BOOST_AUTO_TEST_SUITE_END ()
You can’t perform that action at this time.
0 commit comments