mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-22 17:18:39 +00:00
Ensure that null C strings do not break logging (#15255)
This commit is contained in:
parent
4e6e8b7bf1
commit
2188adc0f9
6 changed files with 225 additions and 73 deletions
43
src/log.h
43
src/log.h
|
@ -32,21 +32,60 @@ class StreamProxy {
|
|||
public:
|
||||
StreamProxy(std::ostream *os) : m_os(os) { }
|
||||
|
||||
static void fix_stream_state(std::ostream &os);
|
||||
|
||||
template<typename T>
|
||||
StreamProxy& operator<<(T&& arg) {
|
||||
StreamProxy& operator<<(T&& arg)
|
||||
{
|
||||
if (m_os) {
|
||||
if (!m_os->good())
|
||||
fix_stream_state(*m_os);
|
||||
*m_os << std::forward<T>(arg);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&)) {
|
||||
StreamProxy& operator<<(std::ostream& (*manip)(std::ostream&))
|
||||
{
|
||||
if (m_os) {
|
||||
if (!m_os->good())
|
||||
fix_stream_state(*m_os);
|
||||
*m_os << manip;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
StreamProxy& emit_with_null_check(T&& arg)
|
||||
{
|
||||
// These calls explicitly use the templated version of operator<<,
|
||||
// so that they won't use the overloads created by ADD_NULL_CHECK.
|
||||
if (arg == nullptr)
|
||||
return this->operator<< <const char*> ("(null)");
|
||||
else
|
||||
return this->operator<< <T>(std::forward<T>(arg));
|
||||
}
|
||||
|
||||
public:
|
||||
// Add specific overrides for operator<< which check for NULL string
|
||||
// pointers. This is undefined behavior in the C++ spec, so emit "(null)"
|
||||
// instead. These are method overloads, rather than template specializations.
|
||||
#define ADD_NULL_CHECK(_type) \
|
||||
StreamProxy& operator<<(_type arg) \
|
||||
{ \
|
||||
return emit_with_null_check(std::forward<_type>(arg)); \
|
||||
}
|
||||
|
||||
ADD_NULL_CHECK(char*)
|
||||
ADD_NULL_CHECK(unsigned char*)
|
||||
ADD_NULL_CHECK(signed char*)
|
||||
ADD_NULL_CHECK(const char*)
|
||||
ADD_NULL_CHECK(const unsigned char*)
|
||||
ADD_NULL_CHECK(const signed char*)
|
||||
|
||||
#undef ADD_NULL_CHECK
|
||||
|
||||
private:
|
||||
std::ostream *m_os;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue