Skip to content

Commit 14d5e71

Browse files
dsoko1ovlupin012
andauthored
Guard negative maxResult in debug_storageRangeAt (#21221)
Clamp negative maxResult in debug_storageRangeAt to prevent empty-heap access in geth-compat mode, and add a regression test that proves the path is safe. Co-authored-by: lupin012 <58134934+lupin012@users.noreply.github.com>
1 parent cc427cd commit 14d5e71

3 files changed

Lines changed: 15 additions & 0 deletions

File tree

rpc/jsonrpc/debug_api.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ func (api *DebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Ha
131131
}
132132
defer tx.Rollback()
133133

134+
if maxResult < 0 {
135+
maxResult = 0
136+
}
137+
134138
blockNrOrHash := rpc.BlockNumberOrHashWithHash(blockHash, true)
135139
blockNumber, _, _, err := rpchelper.GetCanonicalBlockNumber(ctx, blockNrOrHash, tx, api._blockReader, api.filters)
136140
if err != nil {

rpc/jsonrpc/debug_api_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,13 @@ func TestStorageRangeAtGethCompat(t *testing.T) {
390390
if !reflect.DeepEqual(result, expect) {
391391
t.Fatalf("wrong result:\ngot %s\nwant %s", dumper.Sdump(result), dumper.Sdump(&expect))
392392
}
393+
394+
// negative maxResult should be handled safely and must not panic.
395+
result, err = api.StorageRangeAt(m.Ctx, latestBlock.Hash(), 0, addr, nil, -1)
396+
require.NoError(t, err)
397+
require.Empty(t, result.Storage)
398+
require.NotNil(t, result.NextKey)
399+
require.Equal(t, keys[0], *result.NextKey)
393400
})
394401
}
395402

rpc/jsonrpc/storage_range.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ func storageRangeAtErigon(ttx kv.TemporalTx, contractAddress common.Address, sta
131131
func storageRangeAtGethCompat(ttx kv.TemporalTx, contractAddress common.Address, start []byte, txNum uint64, maxResult int) (StorageRangeResult, error) {
132132
result := StorageRangeResult{Storage: storageMap{}}
133133

134+
if maxResult < 0 {
135+
maxResult = 0
136+
}
137+
134138
// Always scan all storage for this contract — we need to sort by hashed key
135139
// to match Geth's trie-based iteration order.
136140
fromKey := common.Copy(contractAddress.Bytes())

0 commit comments

Comments
 (0)