From df7ef3f04263f0206bee5ba56e94f5c5bf5c5e24 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 22 Nov 2025 16:20:08 +0100 Subject: [PATCH 1/7] fix(avl): add index and size overflow checks in GetByIndex and traversebyoffset --- examples/gno.land/p/nt/avl/node.gno | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/gno.land/p/nt/avl/node.gno b/examples/gno.land/p/nt/avl/node.gno index 3c64ad1347e..15190a24f53 100644 --- a/examples/gno.land/p/nt/avl/node.gno +++ b/examples/gno.land/p/nt/avl/node.gno @@ -108,12 +108,15 @@ func (node *Node) Get(key string) (index int, value any, exists bool) { // GetByIndex retrieves the key-value pair of the node at the given index // in the subtree rooted at the node. func (node *Node) GetByIndex(index int) (key string, value any) { + if index < 0 { + panic("GetByIndex: negative index not allowed") + } + if node.height == 0 { - if index == 0 { - return node.key, node.value - } else { + if index != 0 { panic("GetByIndex asked for invalid index") } + return node.key, node.value } else { // TODO: could improve this by storing the sizes leftNode := node.getLeftNode() @@ -382,14 +385,18 @@ func (node *Node) TraverseByOffset(offset, limit int, ascending bool, leavesOnly return false } + if offset < 0 { + panic("TraverseByOffset: negative offset not allowed") + } + if limit < 0 { + panic("TraverseByOffset: negative limit not allowed") + } + // fast paths. these happen only if TraverseByOffset is called directly on a leaf. - if limit <= 0 || offset >= node.size { + if limit == 0 || node.size <= offset { return false } if node.IsLeaf() { - if offset > 0 { - return false - } return cb(node) } From 8952f3e016f0a34beabea42fb3799e6d9f9b2cf4 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 22 Nov 2025 16:28:02 +0100 Subject: [PATCH 2/7] fix(avl): add overflow checks for height and size in calcHeightAndSize --- examples/gno.land/p/nt/avl/node.gno | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/gno.land/p/nt/avl/node.gno b/examples/gno.land/p/nt/avl/node.gno index 15190a24f53..1974e6423c1 100644 --- a/examples/gno.land/p/nt/avl/node.gno +++ b/examples/gno.land/p/nt/avl/node.gno @@ -270,6 +270,13 @@ func (node *Node) rotateLeft() *Node { func (node *Node) calcHeightAndSize() { node.height = maxInt8(node.getLeftNode().height, node.getRightNode().height) + 1 node.size = node.getLeftNode().size + node.getRightNode().size + + if node.height < 0 { + panic("height overflow: tree height exceeds int8 max") + } + if node.size < 0 { + panic("size overflow: node size exceeds int max") + } } // calcBalance calculates the balance factor of the node. From 0d749aeec319b79ccfc8e2693663b215e2a641b4 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 22 Nov 2025 16:32:57 +0100 Subject: [PATCH 3/7] fix(pager): add panic for invalid page number or page size in GetPageWithSize --- examples/gno.land/p/nt/avl/pager/pager.gno | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/gno.land/p/nt/avl/pager/pager.gno b/examples/gno.land/p/nt/avl/pager/pager.gno index 2d277834630..110980c5a09 100644 --- a/examples/gno.land/p/nt/avl/pager/pager.gno +++ b/examples/gno.land/p/nt/avl/pager/pager.gno @@ -53,6 +53,10 @@ func (p *Pager) GetPage(pageNumber int) *Page { } func (p *Pager) GetPageWithSize(pageNumber, pageSize int) *Page { + if pageNumber < 0 || pageSize < 0 { + panic("GetPageWithSize: invalid page number or page size") + } + totalItems := p.Tree.Size() totalPages := int(math.Ceil(float64(totalItems) / float64(pageSize))) From c9c1ca50c50b631524f162507c490e5fc2f3f93a Mon Sep 17 00:00:00 2001 From: David Date: Sat, 22 Nov 2025 16:37:07 +0100 Subject: [PATCH 4/7] fix(avl): remove panic on negative offset --- examples/gno.land/p/nt/avl/node.gno | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/gno.land/p/nt/avl/node.gno b/examples/gno.land/p/nt/avl/node.gno index 1974e6423c1..fb8abf3e810 100644 --- a/examples/gno.land/p/nt/avl/node.gno +++ b/examples/gno.land/p/nt/avl/node.gno @@ -392,15 +392,12 @@ func (node *Node) TraverseByOffset(offset, limit int, ascending bool, leavesOnly return false } - if offset < 0 { - panic("TraverseByOffset: negative offset not allowed") - } if limit < 0 { panic("TraverseByOffset: negative limit not allowed") } // fast paths. these happen only if TraverseByOffset is called directly on a leaf. - if limit == 0 || node.size <= offset { + if limit <= 0 || node.size <= offset { return false } if node.IsLeaf() { From e45d9d46c594359362edfa2ceb04c04ad9a5eab0 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 22 Nov 2025 16:41:41 +0100 Subject: [PATCH 5/7] fix(avl): remove panic on negative limit in TraverseByOffset --- examples/gno.land/p/nt/avl/node.gno | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/gno.land/p/nt/avl/node.gno b/examples/gno.land/p/nt/avl/node.gno index fb8abf3e810..2a71261e064 100644 --- a/examples/gno.land/p/nt/avl/node.gno +++ b/examples/gno.land/p/nt/avl/node.gno @@ -392,15 +392,14 @@ func (node *Node) TraverseByOffset(offset, limit int, ascending bool, leavesOnly return false } - if limit < 0 { - panic("TraverseByOffset: negative limit not allowed") - } - // fast paths. these happen only if TraverseByOffset is called directly on a leaf. if limit <= 0 || node.size <= offset { return false } if node.IsLeaf() { + if offset > 0 { + return false + } return cb(node) } From 8ecbfd647307672239092df2145521b887e17c84 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Nov 2025 13:43:14 +0100 Subject: [PATCH 6/7] fix(pager): remove check on negative pageNumber, as it should be supported (ref: pager/z_filetest.gno) --- examples/gno.land/p/nt/avl/pager/pager.gno | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/p/nt/avl/pager/pager.gno b/examples/gno.land/p/nt/avl/pager/pager.gno index 110980c5a09..8b531f55e7f 100644 --- a/examples/gno.land/p/nt/avl/pager/pager.gno +++ b/examples/gno.land/p/nt/avl/pager/pager.gno @@ -53,8 +53,8 @@ func (p *Pager) GetPage(pageNumber int) *Page { } func (p *Pager) GetPageWithSize(pageNumber, pageSize int) *Page { - if pageNumber < 0 || pageSize < 0 { - panic("GetPageWithSize: invalid page number or page size") + if pageSize <= 0 { + panic("GetPageWithSize: invalid page size") } totalItems := p.Tree.Size() From d161af2218874409464c40c44d124e8185d7d703 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 1 Dec 2025 09:34:59 +0100 Subject: [PATCH 7/7] fix(avl): reverse unnecessary change --- examples/gno.land/p/nt/avl/node.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/nt/avl/node.gno b/examples/gno.land/p/nt/avl/node.gno index 2a71261e064..56fe6811e48 100644 --- a/examples/gno.land/p/nt/avl/node.gno +++ b/examples/gno.land/p/nt/avl/node.gno @@ -393,7 +393,7 @@ func (node *Node) TraverseByOffset(offset, limit int, ascending bool, leavesOnly } // fast paths. these happen only if TraverseByOffset is called directly on a leaf. - if limit <= 0 || node.size <= offset { + if limit <= 0 || offset >= node.size { return false } if node.IsLeaf() {