Skip to content

Commit

Permalink
node/bindnode: subtract all absents in Length at the repr level
Browse files Browse the repository at this point in the history
For structs at the repr level, we were only subtracting the number of
trailing absents, which isn't right.

Rod's added checks in the codecs caught this as a failure,
thanks to the node/tests suite already having one such case.
  • Loading branch information
mvdan committed Jan 18, 2022
1 parent de5750b commit 1930bab
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions node/bindnode/repr.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ func (w *_nodeRepr) MapIterator() datamodel.MapIterator {
switch stg := reprStrategy(w.schemaType).(type) {
case schema.StructRepresentation_Map:
itr := (*_node)(w).MapIterator().(*_structIterator)
// When we reach the last non-absent field, we should stop.
itr.reprEnd = int(w.lengthMinusTrailingAbsents())
return (*_structIteratorRepr)(itr)
case schema.UnionRepresentation_Keyed:
Expand Down Expand Up @@ -291,6 +292,17 @@ func (w *_listIteratorRepr) Done() bool {
return w.nextIndex >= w.val.Len()
}

func (w *_nodeRepr) lengthMinusAbsents() int64 {
fields := w.schemaType.(*schema.TypeStruct).Fields()
n := int64(len(fields))
for i, field := range fields {
if field.IsOptional() && w.val.Field(i).IsNil() {
n--
}
}
return n
}

func (w *_nodeRepr) lengthMinusTrailingAbsents() int64 {
fields := w.schemaType.(*schema.TypeStruct).Fields()
for i := len(fields) - 1; i >= 0; i-- {
Expand All @@ -307,9 +319,9 @@ func (w *_nodeRepr) Length() int64 {
case schema.StructRepresentation_Stringjoin:
return -1
case schema.StructRepresentation_Map:
return w.lengthMinusTrailingAbsents()
return w.lengthMinusAbsents()
case schema.StructRepresentation_Tuple:
return w.lengthMinusTrailingAbsents()
return w.lengthMinusAbsents()
case schema.UnionRepresentation_Keyed:
return (*_node)(w).Length()
case schema.UnionRepresentation_Kinded:
Expand Down

0 comments on commit 1930bab

Please sign in to comment.