Commit e0bb5ba5 authored by Markus Zimmermann's avatar Markus Zimmermann Committed by Robert Griesemer

container/list: mark must be an element of the list

The methods MoveAfter and MoveBefore of the container/list package did silently corrupt the interal structure of the list if a mark element is used which is not an element of the list.

LGTM=gri
R=golang-codereviews, gobot, gri
CC=golang-codereviews
https://golang.org/cl/60980043
parent a9495638
...@@ -180,18 +180,18 @@ func (l *List) MoveToBack(e *Element) { ...@@ -180,18 +180,18 @@ func (l *List) MoveToBack(e *Element) {
} }
// MoveBefore moves element e to its new position before mark. // MoveBefore moves element e to its new position before mark.
// If e is not an element of l, or e == mark, the list is not modified. // If e or mark is not an element of l, or e == mark, the list is not modified.
func (l *List) MoveBefore(e, mark *Element) { func (l *List) MoveBefore(e, mark *Element) {
if e.list != l || e == mark { if e.list != l || e == mark || mark.list != l {
return return
} }
l.insert(l.remove(e), mark.prev) l.insert(l.remove(e), mark.prev)
} }
// MoveAfter moves element e to its new position after mark. // MoveAfter moves element e to its new position after mark.
// If e is not an element of l, or e == mark, the list is not modified. // If e or mark is not an element of l, or e == mark, the list is not modified.
func (l *List) MoveAfter(e, mark *Element) { func (l *List) MoveAfter(e, mark *Element) {
if e.list != l || e == mark { if e.list != l || e == mark || mark.list != l {
return return
} }
l.insert(l.remove(e), mark) l.insert(l.remove(e), mark)
......
...@@ -324,3 +324,20 @@ func TestInsertAfterUnknownMark(t *testing.T) { ...@@ -324,3 +324,20 @@ func TestInsertAfterUnknownMark(t *testing.T) {
l.InsertAfter(1, new(Element)) l.InsertAfter(1, new(Element))
checkList(t, &l, []interface{}{1, 2, 3}) checkList(t, &l, []interface{}{1, 2, 3})
} }
// Test that a list l is not modified when calling MoveAfter or MoveBefore with a mark that is not an element of l.
func TestMoveUnkownMark(t *testing.T) {
var l1 List
e1 := l1.PushBack(1)
var l2 List
e2 := l2.PushBack(2)
l1.MoveAfter(e1, e2)
checkList(t, &l1, []interface{}{1})
checkList(t, &l2, []interface{}{2})
l1.MoveBefore(e1, e2)
checkList(t, &l1, []interface{}{1})
checkList(t, &l2, []interface{}{2})
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment