Skip to content

Commit 916fec6

Browse files
committed
Fix incorrect use of virtual method from log destructor.
1 parent 5dd28d5 commit 916fec6

File tree

3 files changed

+49
-34
lines changed

3 files changed

+49
-34
lines changed

ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
sasl-xoauth2 (0.24) unstable; urgency=low [NOT YET RELEASED]
2+
3+
* Fix bug in logging code that resulted in missing messages (and the
4+
occasional segfault).
5+
6+
-- Tarick Bedeir <[email protected]> Mon, 17 Jul 2023 17:57:00 -0700
7+
18
sasl-xoauth2 (0.23) unstable; urgency=low [NOT YET RELEASED]
29

310
* Add new config option, "always_log_to_syslog", to unconditionally

src/log.cc

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,40 +39,49 @@ std::string Now() {
3939
return std::string(time_str);
4040
}
4141

42-
class NoOpLogger : public Log {
42+
class NoOpLogger : public LogImpl {
4343
public:
44-
NoOpLogger(Options options) : Log(options) {}
44+
NoOpLogger() = default;
4545
~NoOpLogger() override = default;
4646

47-
protected:
4847
void WriteLine(const std::string &line) override {}
4948
};
5049

51-
class SysLogLogger : public Log {
50+
class SysLogLogger : public LogImpl {
5251
public:
53-
SysLogLogger(Options options) : Log(options) {
54-
openlog("sasl-xoauth2", 0, 0);
55-
}
52+
SysLogLogger() = default;
53+
~SysLogLogger() override = default;
5654

57-
~SysLogLogger() override { closelog(); }
58-
59-
protected:
6055
void WriteLine(const std::string &line) override {
56+
openlog("sasl-xoauth2", 0, 0);
6157
syslog(LOG_WARNING, "%s\n", line.c_str());
58+
closelog();
6259
}
6360
};
6461

65-
class StdErrLogger : public Log {
62+
class StdErrLogger : public LogImpl {
6663
public:
67-
StdErrLogger(Options options) : Log(options) {}
64+
StdErrLogger() = default;
6865
~StdErrLogger() override = default;
6966

70-
protected:
7167
void WriteLine(const std::string &line) override {
7268
fprintf(stderr, "%s\n", line.c_str());
7369
}
7470
};
7571

72+
std::unique_ptr<LogImpl> CreateLogImpl(Log::Target target) {
73+
switch (target) {
74+
case Log::TARGET_NONE:
75+
return std::make_unique<NoOpLogger>();
76+
case Log::TARGET_SYSLOG:
77+
return std::make_unique<SysLogLogger>();
78+
case Log::TARGET_STDERR:
79+
return std::make_unique<StdErrLogger>();
80+
default:
81+
exit(1);
82+
};
83+
}
84+
7685
} // namespace
7786

7887
void EnableLoggingForTesting() {
@@ -83,16 +92,7 @@ void EnableLoggingForTesting() {
8392
std::unique_ptr<Log> Log::Create(Options options, Target target) {
8493
options = static_cast<Options>(options | s_default_options);
8594
if (target == TARGET_DEFAULT) target = s_default_target;
86-
switch (target) {
87-
case TARGET_NONE:
88-
return std::make_unique<NoOpLogger>(options);
89-
case TARGET_SYSLOG:
90-
return std::make_unique<SysLogLogger>(options);
91-
case TARGET_STDERR:
92-
return std::make_unique<StdErrLogger>(options);
93-
default:
94-
return {};
95-
};
95+
return std::unique_ptr<Log>(new Log(CreateLogImpl(target), options));
9696
}
9797

9898
Log::~Log() {
@@ -108,24 +108,23 @@ void Log::Write(const char *fmt, ...) {
108108

109109
const std::string line = buf;
110110
if (options_ & OPTIONS_IMMEDIATE) {
111-
WriteLine(line);
111+
impl_->WriteLine(line);
112112
} else {
113113
lines_.push_back(Now() + ": " + line);
114114
}
115115
}
116116

117117
void Log::Flush() {
118118
if (lines_.empty()) return;
119-
120119
if (options_ & OPTIONS_FULL_TRACE_ON_FAILURE) {
121-
WriteLine("auth failed:");
122-
for (const auto &line : lines_) WriteLine(" " + line);
120+
impl_->WriteLine("auth failed:");
121+
for (const auto &line : lines_) impl_->WriteLine(" " + line);
123122
} else {
124123
if (summary_.empty()) summary_ = lines_.back();
125-
WriteLine("auth failed: " + summary_);
124+
impl_->WriteLine("auth failed: " + summary_);
126125
if (lines_.size() > 1) {
127-
WriteLine("set log_full_trace_on_failure to see full " +
128-
std::to_string(lines_.size()) + " line(s) of tracing.");
126+
impl_->WriteLine("set log_full_trace_on_failure to see full " +
127+
std::to_string(lines_.size()) + " line(s) of tracing.");
129128
}
130129
}
131130
}

src/log.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ namespace sasl_xoauth2 {
2525

2626
void EnableLoggingForTesting();
2727

28+
// Log implementation interface, not for direct use.
29+
class LogImpl {
30+
public:
31+
virtual ~LogImpl() = default;
32+
33+
virtual void WriteLine(const std::string &line) = 0;
34+
};
35+
2836
class Log {
2937
public:
3038
enum Options {
@@ -44,18 +52,19 @@ class Log {
4452
static std::unique_ptr<Log> Create(Options options = OPTIONS_NONE,
4553
Target target = TARGET_DEFAULT);
4654

47-
virtual ~Log();
55+
~Log();
4856

4957
void Write(const char *fmt, ...);
5058
void Flush();
5159
void SetFlushOnDestroy();
5260

5361
protected:
54-
Log(Options options) : options_(options) {}
55-
56-
virtual void WriteLine(const std::string &line) = 0;
62+
Log(std::unique_ptr<LogImpl> impl, Options options)
63+
: impl_(std::move(impl)), options_(options) {}
5764

5865
private:
66+
const std::unique_ptr<LogImpl> impl_;
67+
5968
Options options_;
6069
std::string summary_;
6170
std::vector<std::string> lines_;

0 commit comments

Comments
 (0)