Skip to content

Commit 3c71180

Browse files
committed
mapper: validate set length constraints in SetField()
Signed-off-by: Dan Williams <[email protected]>
1 parent 98cc6c7 commit 3c71180

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

mapper/info.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,25 @@ func (i *Info) SetField(column string, value interface{}) error {
6666
return fmt.Errorf("column %s: native value %v (%s) is not assignable to field %s (%s)",
6767
column, value, reflect.TypeOf(value), fieldName, fieldValue.Type())
6868
}
69-
fieldValue.Set(reflect.ValueOf(value))
69+
70+
colSchema := i.Metadata.TableSchema.Column(column)
71+
if colSchema == nil {
72+
return fmt.Errorf("SetField: column %s schema not found", column)
73+
}
74+
75+
// Validate set length requirements
76+
newVal := reflect.ValueOf(value)
77+
if colSchema.Type == ovsdb.TypeSet || colSchema.Type == ovsdb.TypeEnum {
78+
maxVal := colSchema.TypeObj.Max()
79+
minVal := colSchema.TypeObj.Min()
80+
if maxVal > 1 && newVal.Len() > maxVal {
81+
return fmt.Errorf("SetField: column %s overflow: %d new elements but max is %d", column, newVal.Len(), maxVal)
82+
} else if minVal > 0 && newVal.Len() < minVal {
83+
return fmt.Errorf("SetField: column %s underflow: %d new elements but min is %d", column, newVal.Len(), minVal)
84+
}
85+
}
86+
87+
fieldValue.Set(newVal)
7088
return nil
7189
}
7290

mapper/info_test.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ var sampleTable = []byte(`{
2424
"min": 0
2525
}
2626
},
27+
"aLimitedSet": {
28+
"type": {
29+
"key": "string",
30+
"max": 3,
31+
"min": 0
32+
}
33+
},
2734
"aMap": {
2835
"type": {
2936
"key": "string",
@@ -75,10 +82,11 @@ func TestNewMapperInfo(t *testing.T) {
7582

7683
func TestMapperInfoSet(t *testing.T) {
7784
type obj struct {
78-
Ostring string `ovsdb:"aString"`
79-
Oint int `ovsdb:"aInteger"`
80-
Oset []string `ovsdb:"aSet"`
81-
Omap map[string]string `ovsdb:"aMap"`
85+
Ostring string `ovsdb:"aString"`
86+
Oint int `ovsdb:"aInteger"`
87+
Oset []string `ovsdb:"aSet"`
88+
OLimitedSet []string `ovsdb:"aLimitedSet"`
89+
Omap map[string]string `ovsdb:"aMap"`
8290
}
8391

8492
type test struct {
@@ -106,6 +114,22 @@ func TestMapperInfoSet(t *testing.T) {
106114
column: "aSet",
107115
err: false,
108116
},
117+
{
118+
name: "limited set under max",
119+
table: sampleTable,
120+
obj: &obj{},
121+
field: []string{"foo", "bar"},
122+
column: "aLimitedSet",
123+
err: false,
124+
},
125+
{
126+
name: "limited set over max",
127+
table: sampleTable,
128+
obj: &obj{},
129+
field: []string{"foo", "bar", "baz", "qux"},
130+
column: "aLimitedSet",
131+
err: true,
132+
},
109133
{
110134
name: "map",
111135
table: sampleTable,

0 commit comments

Comments
 (0)