From 06ca351132b86961e14ee59f7353c1f7e1a0f50a Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 7 Feb 2008 14:25:32 +0000 Subject: Quote unprintable control characters in log output. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@619424 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/log/Statement.cpp | 30 +++++++++++++++++++++++++++++- cpp/src/tests/logging.cpp | 20 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'cpp/src') diff --git a/cpp/src/qpid/log/Statement.cpp b/cpp/src/qpid/log/Statement.cpp index 949927a32b..2935de9071 100644 --- a/cpp/src/qpid/log/Statement.cpp +++ b/cpp/src/qpid/log/Statement.cpp @@ -18,14 +18,42 @@ #include "Statement.h" #include "Logger.h" +#include #include +#include #include namespace qpid { namespace log { +namespace { +using namespace std; + +struct IsControl { bool operator()(unsigned char c) { return c < 32; } }; + +bool isClean(const std::string& str) { + return std::find_if(str.begin(), str.end(), IsControl()) == str.end(); +} + +std::string quote(const std::string& str) { + IsControl isControl; + size_t n = std::count_if(str.begin(), str.end(), isControl); + std::string ret; + ret.reserve(str.size()+n); // Avoid extra allocations. + for (string::const_iterator i = str.begin(); i != str.end(); ++i) { + if (isControl(*i)) { + ret.push_back('^'); + ret.push_back((*i)+64); + } + else ret.push_back(*i); + } + return ret; +} + +} + void Statement::log(const std::string& message) { - Logger::instance().log(*this,message); + Logger::instance().log(*this, isClean(message) ? message : quote(message)); } Statement::Initializer::Initializer(Statement& s) : statement(s) { diff --git a/cpp/src/tests/logging.cpp b/cpp/src/tests/logging.cpp index 984af2c3c7..4969c3d6a9 100644 --- a/cpp/src/tests/logging.cpp +++ b/cpp/src/tests/logging.cpp @@ -367,4 +367,24 @@ BOOST_AUTO_TEST_CASE(testLoggerConfigure) { unlink("logging.tmp"); } +BOOST_AUTO_TEST_CASE(testQuoteControlChars) { + Logger& l=Logger::instance(); + l.clear(); + Options opts; + opts.outputs.clear(); + opts.outputs.push_back("logging.tmp"); + opts.time=false; + l.configure(opts, "test"); + char s[] = "null\0tab\tspace newline\nret\r"; + string str(s, sizeof(s)); + QPID_LOG(critical, str); + ifstream log("logging.tmp"); + string line; + getline(log, line); + string expect="critical null^@tab^Ispace newline^Jret^M^@"; + BOOST_CHECK_EQUAL(expect, line); + log.close(); + unlink("logging.tmp"); +} + QPID_AUTO_TEST_SUITE_END() -- cgit v1.2.1