From af53579a3f4c0aefdad6b6f3bd08e67812b012ce Mon Sep 17 00:00:00 2001 From: George Date: Wed, 13 Nov 2024 14:50:40 -0800 Subject: [PATCH] Clamp cursors to min/max int32 range --- cmd/soroban-rpc/internal/db/cursor.go | 34 ++++++++++++++++++--------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/cmd/soroban-rpc/internal/db/cursor.go b/cmd/soroban-rpc/internal/db/cursor.go index 4102038d..8f3be397 100644 --- a/cmd/soroban-rpc/internal/db/cursor.go +++ b/cmd/soroban-rpc/internal/db/cursor.go @@ -7,7 +7,9 @@ import ( "strconv" "strings" + "github.com/stellar/go/support/ordered" "github.com/stellar/go/toid" + "golang.org/x/exp/constraints" ) const ( @@ -40,9 +42,15 @@ type CursorRange struct { // String returns a string representation of this cursor func (c Cursor) String() string { + // TOID maxes out at int32, so we need to clamp accordingly to avoid + // generating invalid cursors + ledger := int32(clamp(c.Ledger, 0, math.MaxInt32)) + tx := int32(clamp(c.Tx, 0, math.MaxInt32)) + op := int32(clamp(c.Op, 0, math.MaxInt32)) + return fmt.Sprintf( "%019d-%010d", - toid.New(int32(c.Ledger), int32(c.Tx), int32(c.Op)).ToInt64(), + toid.New(ledger, tx, op).ToInt64(), c.Event, ) } @@ -95,16 +103,6 @@ func ParseCursor(input string) (Cursor, error) { }, nil } -func cmp(a, b uint32) int { - if a < b { - return -1 - } - if a > b { - return 1 - } - return 0 -} - // Cmp compares two cursors. // 0 is returned if the c is equal to other. // 1 is returned if c is greater than other. @@ -122,6 +120,20 @@ func (c Cursor) Cmp(other Cursor) int { return cmp(c.Ledger, other.Ledger) } +func cmp(a, b uint32) int { + if a < b { + return -1 + } + if a > b { + return 1 + } + return 0 +} + +func clamp[T constraints.Ordered](val, floor, ceil T) T { + return ordered.Min(ceil, ordered.Max(floor, val)) +} + var ( // MinCursor is the smallest possible cursor //nolint:gochecknoglobals