Skip to content

Commit

Permalink
mapper: validate set length constraints in SetField()
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
dcbw committed May 11, 2023
1 parent 98cc6c7 commit 3c71180
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 5 deletions.
20 changes: 19 additions & 1 deletion mapper/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,25 @@ func (i *Info) SetField(column string, value interface{}) error {
return fmt.Errorf("column %s: native value %v (%s) is not assignable to field %s (%s)",
column, value, reflect.TypeOf(value), fieldName, fieldValue.Type())
}
fieldValue.Set(reflect.ValueOf(value))

colSchema := i.Metadata.TableSchema.Column(column)
if colSchema == nil {
return fmt.Errorf("SetField: column %s schema not found", column)
}

// Validate set length requirements
newVal := reflect.ValueOf(value)
if colSchema.Type == ovsdb.TypeSet || colSchema.Type == ovsdb.TypeEnum {
maxVal := colSchema.TypeObj.Max()
minVal := colSchema.TypeObj.Min()
if maxVal > 1 && newVal.Len() > maxVal {
return fmt.Errorf("SetField: column %s overflow: %d new elements but max is %d", column, newVal.Len(), maxVal)
} else if minVal > 0 && newVal.Len() < minVal {
return fmt.Errorf("SetField: column %s underflow: %d new elements but min is %d", column, newVal.Len(), minVal)
}
}

fieldValue.Set(newVal)
return nil
}

Expand Down
32 changes: 28 additions & 4 deletions mapper/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ var sampleTable = []byte(`{
"min": 0
}
},
"aLimitedSet": {
"type": {
"key": "string",
"max": 3,
"min": 0
}
},
"aMap": {
"type": {
"key": "string",
Expand Down Expand Up @@ -75,10 +82,11 @@ func TestNewMapperInfo(t *testing.T) {

func TestMapperInfoSet(t *testing.T) {
type obj struct {
Ostring string `ovsdb:"aString"`
Oint int `ovsdb:"aInteger"`
Oset []string `ovsdb:"aSet"`
Omap map[string]string `ovsdb:"aMap"`
Ostring string `ovsdb:"aString"`
Oint int `ovsdb:"aInteger"`
Oset []string `ovsdb:"aSet"`
OLimitedSet []string `ovsdb:"aLimitedSet"`
Omap map[string]string `ovsdb:"aMap"`
}

type test struct {
Expand Down Expand Up @@ -106,6 +114,22 @@ func TestMapperInfoSet(t *testing.T) {
column: "aSet",
err: false,
},
{
name: "limited set under max",
table: sampleTable,
obj: &obj{},
field: []string{"foo", "bar"},
column: "aLimitedSet",
err: false,
},
{
name: "limited set over max",
table: sampleTable,
obj: &obj{},
field: []string{"foo", "bar", "baz", "qux"},
column: "aLimitedSet",
err: true,
},
{
name: "map",
table: sampleTable,
Expand Down

0 comments on commit 3c71180

Please sign in to comment.