diff --git a/proxy/logMonitor.go b/proxy/logMonitor.go index 130b721..7e40adc 100644 --- a/proxy/logMonitor.go +++ b/proxy/logMonitor.go @@ -30,13 +30,19 @@ func NewLogMonitorWriter(stdout io.Writer) *LogMonitor { } func (w *LogMonitor) Write(p []byte) (n int, err error) { + if len(p) == 0 { + return 0, nil + } + n, err = w.stdout.Write(p) if err != nil { return n, err } w.bufferMu.Lock() - w.buffer.Value = p + bufferCopy := make([]byte, len(p)) + copy(bufferCopy, p) + w.buffer.Value = bufferCopy w.buffer = w.buffer.Next() w.bufferMu.Unlock() @@ -49,7 +55,7 @@ func (w *LogMonitor) GetHistory() []byte { defer w.bufferMu.RUnlock() var history []byte - w.buffer.Do(func(p interface{}) { + w.buffer.Do(func(p any) { if p != nil { if content, ok := p.([]byte); ok { history = append(history, content...) diff --git a/proxy/logMonitor_test.go b/proxy/logMonitor_test.go index 08f6d74..67384ac 100644 --- a/proxy/logMonitor_test.go +++ b/proxy/logMonitor_test.go @@ -1,6 +1,7 @@ package proxy import ( + "bytes" "io" "sync" "testing" @@ -61,3 +62,34 @@ func TestLogMonitor(t *testing.T) { t.Errorf("Client2 expected %s, got: %s", expectedHistory, c2Data) } } + +func TestWrite_ImmutableBuffer(t *testing.T) { + // Create a new LogMonitor instance + lm := NewLogMonitorWriter(io.Discard) + + // Prepare a message to write + msg := []byte("Hello, World!") + lenmsg := len(msg) + + // Write the message to the LogMonitor + n, err := lm.Write(msg) + if err != nil { + t.Fatalf("Write failed: %v", err) + } + + if n != lenmsg { + t.Errorf("Expected %d bytes written but got %d", lenmsg, n) + } + + // Change the original message + msg[0] = 'B' // This should not affect the buffer + + // Get the history from the LogMonitor + history := lm.GetHistory() + + // Check that the history contains the original message, not the modified one + expected := []byte("Hello, World!") + if !bytes.Equal(history, expected) { + t.Errorf("Expected history to be %q, got %q", expected, history) + } +}