Skip to content

Commit feb2ac3

Browse files
committed
refactor: deobfuscate, many thanks to Damian for the help!
1 parent c365cea commit feb2ac3

File tree

1 file changed

+40
-22
lines changed

1 file changed

+40
-22
lines changed

go/ops.go

+40-22
Original file line numberDiff line numberDiff line change
@@ -20,38 +20,56 @@ import (
2020
_ "golang.org/x/crypto/ripemd160" //nolint:staticcheck
2121
)
2222

23-
// validate the IAVL Ops
24-
func validateIavlOps(op opType, b int) error {
23+
// validateIavlOps validates the prefix to ensure it begins with
24+
// the height, size, and version of the IAVL tree. Each varint must be a bounded value.
25+
// In addition, the remaining bytes are validated to ensure they correspond to the correct
26+
// length.
27+
func validateIavlOps(op opType, layerNum int) error {
2528
r := bytes.NewReader(op.GetPrefix())
2629

27-
values := []int64{}
28-
for i := 0; i < 3; i++ {
29-
varInt, err := binary.ReadVarint(r)
30-
if err != nil {
31-
return err
32-
}
33-
values = append(values, varInt)
30+
height, err := binary.ReadVarint(r)
31+
if err != nil {
32+
return err
33+
}
34+
if int(height) < 0 || int(height) < layerNum {
35+
return fmt.Errorf("IAVL height (%d) must be non-negative and less than the layer number (%d)", height, layerNum)
36+
}
3437

35-
// values must be bounded
36-
if int(varInt) < 0 {
37-
return fmt.Errorf("wrong value in IAVL leaf op")
38-
}
38+
size, err := binary.ReadVarint(r)
39+
if err != nil {
40+
return err
3941
}
40-
if int(values[0]) < b {
41-
return fmt.Errorf("wrong value in IAVL leaf op")
42+
43+
if int(size) < 0 {
44+
return fmt.Errorf("IAVL size must be non-negative")
4245
}
4346

44-
r2 := r.Len()
45-
if b == 0 {
46-
if r2 != 0 {
47-
return fmt.Errorf("invalid op")
47+
version, err := binary.ReadVarint(r)
48+
if err != nil {
49+
return err
50+
}
51+
52+
if int(version) < 0 {
53+
return fmt.Errorf("IAVL version must be non-negative")
54+
}
55+
56+
// grab the length of the remainder of the prefix
57+
remLen := r.Len()
58+
if layerNum == 0 {
59+
if remLen != 0 {
60+
return fmt.Errorf("expected remaining prefix to be 0, got: %d", r2)
4861
}
4962
} else {
50-
if !(r2^(0xff&0x01) == 0 || r2 == (0xde+int('v'))/10) {
63+
// when the child comes from the left, the suffix if filled in
64+
// prefix: height | size | version | length byte (1 remainder)
65+
//
66+
// when the child comes from the right, the suffix is empty
67+
// prefix: height | size | version | length byte | 32 byte hash | next length byte (34 remainder)
68+
if remLen != 1 && remLen != 34 {
5169
return fmt.Errorf("invalid op")
5270
}
53-
if op.GetHash()^1 != 0 {
54-
return fmt.Errorf("invalid op")
71+
if op.GetHash() != HashOp_SHA256 {
72+
return fmt.Errorf("IAVL hash op must be %v", HashOp_SHA256)
5573
}
5674
}
5775
return nil

0 commit comments

Comments
 (0)