mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	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.
This commit is contained in:
		
							
								
								
									
										24
									
								
								src/log.cpp
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user