diff --git a/frontend/src/liboperator/operator/clients.go b/frontend/src/liboperator/operator/clients.go index 66043b4ea5a..f5b687a3383 100644 --- a/frontend/src/liboperator/operator/clients.go +++ b/frontend/src/liboperator/operator/clients.go @@ -80,16 +80,17 @@ func (c *PolledClient) ToDevice(msg interface{}) error { func (c *PolledClient) GetMessages(start int, count int) []interface{} { c.msgMtx.Lock() defer c.msgMtx.Unlock() - if count < 0 { - count = len(c.messages) - start + if start < 0 { + start = 0 + } + if start > len(c.messages) { + start = len(c.messages) } - end := start + count - if end > len(c.messages) { - end = len(c.messages) - count = end - start + if count < 0 || count > len(c.messages)-start { + count = len(c.messages) - start } ret := make([]interface{}, count) - copy(ret, c.messages[start:end]) + copy(ret, c.messages[start:start+count]) return ret } diff --git a/frontend/src/liboperator/operator/clients_test.go b/frontend/src/liboperator/operator/clients_test.go index 28da6eace81..748e5b25db8 100644 --- a/frontend/src/liboperator/operator/clients_test.go +++ b/frontend/src/liboperator/operator/clients_test.go @@ -78,6 +78,30 @@ func TestMessages(t *testing.T) { } } +func TestGetMessagesBounds(t *testing.T) { + ps := NewPolledSet() + c := ps.NewConnection(newDevice("d1", nil, 0, "")) + c.Send("msg1") + c.Send("msg2") + c.Send("msg3") + + // Negative start is clamped to the beginning of the buffer. + if msgs := c.GetMessages(-1, -1); len(msgs) != 3 { + t.Errorf("negative start: got %d messages, want 3", len(msgs)) + } + // start past the end of the buffer returns an empty slice. + if msgs := c.GetMessages(10, -1); len(msgs) != 0 { + t.Errorf("start past end: got %d messages, want 0", len(msgs)) + } + if msgs := c.GetMessages(10, 2); len(msgs) != 0 { + t.Errorf("start past end with count: got %d messages, want 0", len(msgs)) + } + // A count larger than the remaining messages is clamped. + if msgs := c.GetMessages(2, 100); len(msgs) != 1 { + t.Errorf("oversized count: got %d messages, want 1", len(msgs)) + } +} + func TestDestroy(t *testing.T) { ps := NewPolledSet() c := ps.NewConnection(newDevice("d1", nil, 0, ""))