diff --git a/pkg/local_object_storage/blobstor/blobovnicza.go b/pkg/local_object_storage/blobstor/blobovnicza.go index 2afde24e..2d07ef94 100644 --- a/pkg/local_object_storage/blobstor/blobovnicza.go +++ b/pkg/local_object_storage/blobstor/blobovnicza.go @@ -628,7 +628,7 @@ func (b *blobovniczas) getObjectRange(blz *blobovnicza.Blobovnicza, prm GetRange to := from + prm.rng.GetLength() payload := obj.Payload() - if uint64(len(payload)) < to { + if pLen := uint64(len(payload)); to < from || pLen < from || pLen < to { var errOutOfRange apistatus.ObjectOutOfRange return GetRangeSmallRes{}, errOutOfRange diff --git a/pkg/local_object_storage/blobstor/get_range_big.go b/pkg/local_object_storage/blobstor/get_range_big.go index 65b6d010..d6d174dd 100644 --- a/pkg/local_object_storage/blobstor/get_range_big.go +++ b/pkg/local_object_storage/blobstor/get_range_big.go @@ -54,7 +54,7 @@ func (b *BlobStor) GetRangeBig(prm GetRangeBigPrm) (GetRangeBigRes, error) { payload := obj.Payload() ln, off := prm.rng.GetLength(), prm.rng.GetOffset() - if pLen := uint64(len(payload)); pLen < ln+off { + if pLen := uint64(len(payload)); ln+off < off || pLen < off || pLen < ln+off { var errOutOfRange apistatus.ObjectOutOfRange return GetRangeBigRes{}, errOutOfRange diff --git a/pkg/local_object_storage/shard/range.go b/pkg/local_object_storage/shard/range.go index 23f5d3ed..e74e838c 100644 --- a/pkg/local_object_storage/shard/range.go +++ b/pkg/local_object_storage/shard/range.go @@ -113,7 +113,7 @@ func (s *Shard) GetRange(prm RngPrm) (RngRes, error) { payload := res.Payload() from := rng.GetOffset() to := from + rng.GetLength() - if uint64(len(payload)) < to { + if pLen := uint64(len(payload)); to < from || pLen < from || pLen < to { return nil, apistatus.ObjectOutOfRange{} } diff --git a/pkg/local_object_storage/shard/range_test.go b/pkg/local_object_storage/shard/range_test.go index fda085f8..10769cfd 100644 --- a/pkg/local_object_storage/shard/range_test.go +++ b/pkg/local_object_storage/shard/range_test.go @@ -1,6 +1,7 @@ package shard_test import ( + "math" "testing" "github.com/nspcc-dev/neo-go/pkg/util/slice" @@ -45,15 +46,18 @@ func testShardGetRange(t *testing.T, hasWriteCache bool) { testCases := []testCase{ {false, "small object, good", 1024, newRange(11, 123)}, - {true, "small object, out of range", 1024, newRange(10, 1020)}, + {true, "small object, out of range, big len", 1024, newRange(10, 1020)}, + {true, "small object, out of range, big offset", 1024, newRange(1025, math.MaxUint64-10)}, {false, "big object, good", 2048, newRange(11, 123)}, - {true, "big object, out of range", 2048, newRange(100, 2000)}, + {true, "big object, out of range, big len", 2048, newRange(100, 2000)}, + {true, "big object, out of range, big offset", 2048, newRange(2048, math.MaxUint64-10)}, } if hasWriteCache { testCases = append(testCases, testCase{false, "object in write-cache, good", 100, newRange(2, 18)}, - testCase{true, "object in write-cache, out of range", 100, newRange(4, 99)}) + testCase{true, "object in write-cache, out of range, big len", 100, newRange(4, 99)}, + testCase{true, "object in write-cache, out of range, big offset", 100, newRange(101, math.MaxUint64-10)}) } sh := newCustomShard(t, t.TempDir(), hasWriteCache,