Skip to content

Commit 33d3dbd

Browse files
authored
Fix leaf-list binary unmarshalling. (#900)
1 parent ca98dd5 commit 33d3dbd

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

ytypes/leaf.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,11 @@ func unmarshalLeaf(inSchema *yang.Entry, parent interface{}, value interface{},
382382
if err != nil {
383383
return err
384384
}
385-
if ykind == yang.Ybinary {
385+
fieldIsSliceofSlice, err := isFieldSliceofSlice(parent, fieldName)
386+
if err != nil {
387+
return err
388+
}
389+
if ykind == yang.Ybinary && !fieldIsSliceofSlice {
386390
// Binary is a slice field which is treated as a scalar.
387391
return util.InsertIntoStruct(parent, fieldName, v)
388392
}
@@ -397,6 +401,24 @@ func unmarshalLeaf(inSchema *yang.Entry, parent interface{}, value interface{},
397401
return util.UpdateField(parent, fieldName, v)
398402
}
399403

404+
func isFieldSliceofSlice(parentStruct interface{}, fieldName string) (bool, error) {
405+
if util.IsValueNil(parentStruct) {
406+
return false, fmt.Errorf("parent is nil in UpdateField for field %s", fieldName)
407+
}
408+
409+
pt := reflect.TypeOf(parentStruct)
410+
411+
if !util.IsTypeStructPtr(pt) {
412+
return false, fmt.Errorf("parent type %T must be a struct ptr", parentStruct)
413+
}
414+
ft, ok := pt.Elem().FieldByName(fieldName)
415+
if !ok {
416+
return false, fmt.Errorf("parent type %T does not have a field name %s", parentStruct, fieldName)
417+
}
418+
419+
return ft.Type.Kind() == reflect.Slice && ft.Type.Elem().Kind() == reflect.Slice, nil
420+
}
421+
400422
// unmarshalUnion unmarshals a union schema type with the given value into
401423
// parent.
402424
/*

ytypes/leaf_list_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ func TestValidateLeafList(t *testing.T) {
148148

149149
type LeafListContainer struct {
150150
Int32LeafList []*int32 `path:"int32-leaf-list"`
151+
BinaryLeafList []Binary `path:"binary-leaf-list"`
151152
EnumLeafList []EnumType `path:"enum-leaf-list"`
152153
UnionLeafSlice []UnionLeafType `path:"union-leaflist"`
153154
UnionLeafSliceSimple []UnionLeafTypeSimple `path:"union-leaflist-simple"`
@@ -214,6 +215,14 @@ func TestUnmarshalLeafListGNMIEncoding(t *testing.T) {
214215
Type: &yang.YangType{Kind: yang.Yint32},
215216
}
216217

218+
binaryLeafListSchema := &yang.Entry{
219+
Parent: containerSchema,
220+
Name: "binary-leaf-list",
221+
Kind: yang.LeafEntry,
222+
ListAttr: yang.NewDefaultListAttr(),
223+
Type: &yang.YangType{Kind: yang.Ybinary},
224+
}
225+
217226
enumLeafListSchema := &yang.Entry{
218227
Parent: containerSchema,
219228
Name: "enum-leaf-list",
@@ -294,6 +303,20 @@ func TestUnmarshalLeafListGNMIEncoding(t *testing.T) {
294303
}},
295304
want: LeafListContainer{Int32LeafList: []*int32{ygot.Int32(-42), ygot.Int32(0), ygot.Int32(42)}},
296305
},
306+
{
307+
desc: "binary success",
308+
sch: binaryLeafListSchema,
309+
val: &gpb.TypedValue{Value: &gpb.TypedValue_LeaflistVal{
310+
LeaflistVal: &gpb.ScalarArray{
311+
Element: []*gpb.TypedValue{
312+
{Value: &gpb.TypedValue_BytesVal{BytesVal: []byte{0xa0, 0x00, 0x00, 0x00}}},
313+
{Value: &gpb.TypedValue_BytesVal{BytesVal: []byte{0xb0, 0x00, 0x00, 0x00}}},
314+
{Value: &gpb.TypedValue_BytesVal{BytesVal: []byte{0xc0, 0x00, 0x00, 0x00}}},
315+
},
316+
},
317+
}},
318+
want: LeafListContainer{BinaryLeafList: []Binary{Binary([]byte{0xa0, 0x00, 0x00, 0x00}), Binary([]byte{0xb0, 0x00, 0x00, 0x00}), Binary([]byte{0xc0, 0x00, 0x00, 0x00})}},
319+
},
297320
{
298321
desc: "int32 success with existing values",
299322
sch: int32LeafListSchema,

0 commit comments

Comments
 (0)