mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 03:10:48 +00:00
Merge 802eb91441 into dddbaa4bf3
This commit is contained in:
commit
8124678cfa
2 changed files with 29 additions and 5 deletions
|
|
@ -397,20 +397,25 @@ func decodeRestartTrailer(keySection []byte) ([]uint32, []uint32, int, error) {
|
|||
}
|
||||
nRestarts := binary.BigEndian.Uint32(keySection[len(keySection)-4:])
|
||||
|
||||
// Decode the trailer
|
||||
// Decode the trailer. The multiplication is performed in 64-bit to prevent
|
||||
// the result from wrapping around for large restart counts.
|
||||
if uint64(len(keySection)) < uint64(nRestarts)*8+4 {
|
||||
return nil, nil, 0, fmt.Errorf("key section too short, restarts: %d, size: %d", nRestarts, len(keySection))
|
||||
}
|
||||
var (
|
||||
keyOffsets = make([]uint32, 0, int(nRestarts))
|
||||
valOffsets = make([]uint32, 0, int(nRestarts))
|
||||
keyLimit = len(keySection) - 4 - int(nRestarts)*8 // End of key data
|
||||
)
|
||||
if len(keySection) < int(8*nRestarts)+4 {
|
||||
return nil, nil, 0, fmt.Errorf("key section too short, restarts: %d, size: %d", nRestarts, len(keySection))
|
||||
}
|
||||
for i := range int(nRestarts) {
|
||||
o := len(keySection) - 4 - (int(nRestarts)-i)*8
|
||||
keyOffset := binary.BigEndian.Uint32(keySection[o : o+4])
|
||||
if i != 0 && keyOffset <= keyOffsets[i-1] {
|
||||
return nil, nil, 0, fmt.Errorf("key offset is out of order, prev: %v, cur: %v", keyOffsets[i-1], keyOffset)
|
||||
}
|
||||
if int(keyOffset) > keyLimit {
|
||||
return nil, nil, 0, fmt.Errorf("key offset is out of range, offset: %d, limit: %d", keyOffset, keyLimit)
|
||||
}
|
||||
keyOffsets = append(keyOffsets, keyOffset)
|
||||
|
||||
// Same value offset is allowed just in case all the trie nodes in the last
|
||||
|
|
@ -421,7 +426,6 @@ func decodeRestartTrailer(keySection []byte) ([]uint32, []uint32, int, error) {
|
|||
}
|
||||
valOffsets = append(valOffsets, valOffset)
|
||||
}
|
||||
keyLimit := len(keySection) - 4 - int(nRestarts)*8 // End of key data
|
||||
return keyOffsets, valOffsets, keyLimit, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -656,6 +656,26 @@ func TestDecodeSingleCorruptedData(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("Expected error for invalid restart count")
|
||||
}
|
||||
|
||||
// Test with a restart count large enough to overflow the trailer size
|
||||
// computation (8*nRestarts wraps around for nRestarts >= 1<<29).
|
||||
corrupted = make([]byte, len(keySection))
|
||||
copy(corrupted, keySection)
|
||||
binary.BigEndian.PutUint32(corrupted[len(corrupted)-4:], 1<<29)
|
||||
err = decodeSingle(corrupted, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for overflowing restart count")
|
||||
}
|
||||
|
||||
// Test with a key offset pointing beyond the end of the key data
|
||||
corrupted = make([]byte, 12)
|
||||
binary.BigEndian.PutUint32(corrupted[0:4], 0xffffffff) // key offset
|
||||
binary.BigEndian.PutUint32(corrupted[4:8], 0) // value offset
|
||||
binary.BigEndian.PutUint32(corrupted[8:12], 1) // restart count
|
||||
err = decodeSingle(corrupted, nil)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error for out-of-range key offset")
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to test encode/decode cycle
|
||||
|
|
|
|||
Loading…
Reference in a new issue