diff options
author | Ekdohibs <nathanael.courant@laposte.net> | 2016-04-21 10:45:42 +0200 |
---|---|---|
committer | paramat <mat.gregory@virginmedia.com> | 2016-04-21 10:15:17 +0100 |
commit | c350cfb50b3bf81c075a80307adb15393ea773d0 (patch) | |
tree | 141921a19662a79cc3943d730f87c413e6c9c6eb /src/log.cpp | |
parent | 5c32c5e945275c612c10021bbd2117a73a97fc3f (diff) | |
download | minetest-c350cfb50b3bf81c075a80307adb15393ea773d0.tar.gz minetest-c350cfb50b3bf81c075a80307adb15393ea773d0.tar.bz2 minetest-c350cfb50b3bf81c075a80307adb15393ea773d0.zip |
Make logging use a fixed-length buffer to avoid race conditions.
Previously, race conditions occurred inside logging, that caused
segfaults because a thread was trying to use an old pointer that
was freed when the string was reallocated. Using a fixed-length buffer
avoids this, at the cost of cutting too long messages over seveal lines.
Diffstat (limited to 'src/log.cpp')
-rw-r--r-- | src/log.cpp | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/log.cpp b/src/log.cpp index 600e715c1..589cfd909 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -34,9 +34,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <cerrno> #include <cstring> +const int BUFFER_LENGTH = 256; + class StringBuffer : public std::streambuf { public: - StringBuffer() {} + StringBuffer() { + buffer_index = 0; + } int overflow(int c); virtual void flush(const std::string &buf) = 0; @@ -44,7 +48,8 @@ public: void push_back(char c); private: - std::string buffer; + char buffer[BUFFER_LENGTH]; + int buffer_index; }; @@ -338,11 +343,18 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n) void StringBuffer::push_back(char c) { if (c == '\n' || c == '\r') { - if (!buffer.empty()) - flush(buffer); - buffer.clear(); + if (buffer_index) + flush(std::string(buffer, buffer_index)); + buffer_index = 0; } else { - buffer.push_back(c); + int index = buffer_index; + buffer[index++] = c; + if (index >= BUFFER_LENGTH) { + flush(std::string(buffer, buffer_index)); + buffer_index = 0; + } else { + buffer_index = index; + } } } |