Skip to content

Commit

Permalink
Correct validation on bitlist Marshalling
Browse files Browse the repository at this point in the history
  • Loading branch information
Bez625 committed Jan 16, 2025
1 parent 03cd290 commit 3b8b938
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
20 changes: 20 additions & 0 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,26 @@ func ValidateBitlist(buf []byte, bitLimit uint64) error {
return nil
}

// BitlistLen provides the bitlist length of a byte array
func BitlistLen(b []byte) int {
if len(b) == 0 {
return 0
}
// The most significant bit is present in the last byte in the array.
last := b[len(b)-1]

// Determine the position of the most significant bit.
msb := bits.Len8(last)
if msb == 0 {
return 0
}

// The absolute position of the most significant bit will be the number of
// bits in the preceding bytes plus the position of the most significant
// bit. Subtract this value by 1 to determine the length of the bitlist.
return 8*(len(b)-1) + msb - 1
}

// DecodeDynamicLength decodes the length from the dynamic input
func DecodeDynamicLength(buf []byte, maxSize int) (int, error) {
if len(buf) == 0 {
Expand Down
4 changes: 2 additions & 2 deletions spectests/structs_encoding.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion sszgen/generator/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package generator

func (v *Value) validate() string {
switch v.t {
case TypeBitList, TypeBytes:
case TypeBytes:
// this is a fixed-length array, not a slice, so it's size is a constant we don't need to check
if v.c {
return ""
Expand All @@ -25,6 +25,29 @@ func (v *Value) validate() string {
"size": v.s,
})

case TypeBitList:
// this is a fixed-length array, not a slice, so it's size is a constant we don't need to check
if v.c {
return ""
}
// for fixed size collections, we need to ensure the size is an exact match
cmp := "!="
// for variable size values, we want to ensure it doesn't exceed max size bound
if !v.isFixed() {
cmp = ">"
}

tmpl := `if size := ssz.BitlistLen(::.{{.name}}); size {{.cmp}} {{.size}} {
err = ssz.ErrBytesLengthFn("--.{{.name}}", size, {{.size}})
return
}
`
return execTmpl(tmpl, map[string]interface{}{
"cmp": cmp,
"name": v.name,
"size": v.s,
})

case TypeVector:
// this is a fixed-length array, not a slice, so it's size is a constant we don't need to check
if v.c {
Expand Down

0 comments on commit 3b8b938

Please sign in to comment.