diff --git a/internal/packing/packing.go b/internal/packing/packing.go index 760c30d6d..65a1c381e 100644 --- a/internal/packing/packing.go +++ b/internal/packing/packing.go @@ -217,24 +217,33 @@ func (p *Page) Extend(count int) bool { if p.size >= p.maxSize { return false } + newSize := p.size for i := 0; i < count; i++ { newSize *= 2 } + + if newSize > p.maxSize { + return false + } + edgeNodes := []*Node{} abort := errors.New("abort") aborted := false - _ = walk(p.root, func(n *Node) error { - if n.x+n.width < p.size && n.y+n.height < p.size { + if p.root != nil { + _ = walk(p.root, func(n *Node) error { + if n.x+n.width < p.size && n.y+n.height < p.size { + return nil + } + if n.used { + aborted = true + return abort + } + edgeNodes = append(edgeNodes, n) return nil - } - if n.used { - aborted = true - return abort - } - edgeNodes = append(edgeNodes, n) - return nil - }) + }) + } + if aborted { origRoot := *p.root @@ -306,6 +315,7 @@ func (p *Page) Extend(count int) bool { } p.size = newSize + return true } diff --git a/internal/packing/packing_test.go b/internal/packing/packing_test.go index 170ddb56c..2ab6af79d 100644 --- a/internal/packing/packing_test.go +++ b/internal/packing/packing_test.go @@ -328,3 +328,34 @@ func TestExtend2(t *testing.T) { t.Errorf("p.Alloc(%d, %d) must fail but not", s, s) } } + +// Issue #1454 +func TestExtendTooMuch(t *testing.T) { + p := NewPage(1024, 4096) + p.Alloc(1, 1) + if got, want := p.Extend(3), false; got != want { + t.Errorf("got: %t, want: %t", got, want) + } +} + +func TestExtendWithoutAllocation(t *testing.T) { + p := NewPage(1024, 4096) + + if got, want := p.Extend(2), true; got != want { + t.Errorf("got: %t, want: %t", got, want) + } + + p.RollbackExtension() + if got, want := p.Size(), 1024; got != want { + t.Errorf("p.Size(): got: %d, want: %d", got, want) + } + + if got, want := p.Extend(2), true; got != want { + t.Errorf("got: %t, want: %t", got, want) + } + + p.CommitExtension() + if got, want := p.Size(), 4096; got != want { + t.Errorf("p.Size(): got: %d, want: %d", got, want) + } +}