1
0
mirror of https://github.com/rancher/os.git synced 2025-09-04 00:04:25 +00:00

bump libcompose (avoid panics on non-string leaf values in certain data types)

This commit is contained in:
Ivan Mikushin
2015-12-09 09:55:50 +05:00
parent 0c0cb2aa5f
commit cc6a161df1
3 changed files with 87 additions and 41 deletions

View File

@@ -95,7 +95,7 @@ import:
- volume - volume
- package: github.com/docker/libcompose - package: github.com/docker/libcompose
version: 3e678b6a30d314e86441cbd9ad01534b7534d53a version: 5cad17e57c7c5a2faa180b75c5beb90afc7dde05
subpackages: subpackages:
- cli - cli
- docker - docker

View File

@@ -18,13 +18,25 @@ func (s Stringorslice) MarshalYAML() (tag string, value interface{}, err error)
return "", s.parts, nil return "", s.parts, nil
} }
func toStrings(s []interface{}) ([]string, error) {
r := make([]string, len(s))
for k, v := range s {
if sv, ok := v.(string); ok {
r[k] = sv
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
}
return r, nil
}
// UnmarshalYAML implements the Unmarshaller interface. // UnmarshalYAML implements the Unmarshaller interface.
func (s *Stringorslice) UnmarshalYAML(tag string, value interface{}) error { func (s *Stringorslice) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) { switch value := value.(type) {
case []interface{}: case []interface{}:
parts := make([]string, len(value)) parts, err := toStrings(value)
for k, v := range value { if err != nil {
parts[k] = v.(string) return err
} }
s.parts = parts s.parts = parts
case string: case string:
@@ -72,9 +84,9 @@ func (s *Command) UnmarshalYAML(tag string, value interface{}) error {
var err error var err error
switch value := value.(type) { switch value := value.(type) {
case []interface{}: case []interface{}:
parts := make([]string, len(value)) parts, err := toStrings(value)
for k, v := range value { if err != nil {
parts[k] = v.(string) return err
} }
s.parts = parts s.parts = parts
case string: case string:
@@ -116,21 +128,33 @@ func (s *SliceorMap) UnmarshalYAML(tag string, value interface{}) error {
case map[interface{}]interface{}: case map[interface{}]interface{}:
parts := map[string]string{} parts := map[string]string{}
for k, v := range value { for k, v := range value {
parts[k.(string)] = v.(string) if sk, ok := k.(string); ok {
if sv, ok := v.(string); ok {
parts[sk] = sv
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", k, k)
}
} }
s.parts = parts s.parts = parts
case []interface{}: case []interface{}:
parts := map[string]string{} parts := map[string]string{}
for _, str := range value { for _, s := range value {
str := strings.TrimSpace(str.(string)) if str, ok := s.(string); ok {
keyValueSlice := strings.SplitN(str, "=", 2) str := strings.TrimSpace(str)
keyValueSlice := strings.SplitN(str, "=", 2)
key := keyValueSlice[0] key := keyValueSlice[0]
val := "" val := ""
if len(keyValueSlice) == 2 { if len(keyValueSlice) == 2 {
val = keyValueSlice[1] val = keyValueSlice[1]
}
parts[key] = val
} else {
return fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", s, s)
} }
parts[key] = val
} }
s.parts = parts s.parts = parts
default: default:
@@ -163,19 +187,35 @@ func (s MaporEqualSlice) MarshalYAML() (tag string, value interface{}, err error
return "", s.parts, nil return "", s.parts, nil
} }
func toSepMapParts(value map[interface{}]interface{}, sep string) ([]string, error) {
parts := make([]string, 0, len(value))
for k, v := range value {
if sk, ok := k.(string); ok {
if sv, ok := v.(string); ok {
parts = append(parts, sk+sep+sv)
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", v, v)
}
} else {
return nil, fmt.Errorf("Cannot unmarshal '%v' of type %T into a string value", k, k)
}
}
return parts, nil
}
// UnmarshalYAML implements the Unmarshaller interface. // UnmarshalYAML implements the Unmarshaller interface.
func (s *MaporEqualSlice) UnmarshalYAML(tag string, value interface{}) error { func (s *MaporEqualSlice) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) { switch value := value.(type) {
case []interface{}: case []interface{}:
parts := make([]string, len(value)) parts, err := toStrings(value)
for k, v := range value { if err != nil {
parts[k] = v.(string) return err
} }
s.parts = parts s.parts = parts
case map[interface{}]interface{}: case map[interface{}]interface{}:
parts := make([]string, 0, len(value)) parts, err := toSepMapParts(value, "=")
for k, v := range value { if err != nil {
parts = append(parts, strings.Join([]string{k.(string), v.(string)}, "=")) return err
} }
s.parts = parts s.parts = parts
default: default:
@@ -209,15 +249,15 @@ func (s MaporColonSlice) MarshalYAML() (tag string, value interface{}, err error
func (s *MaporColonSlice) UnmarshalYAML(tag string, value interface{}) error { func (s *MaporColonSlice) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) { switch value := value.(type) {
case []interface{}: case []interface{}:
parts := make([]string, len(value)) parts, err := toStrings(value)
for k, v := range value { if err != nil {
parts[k] = v.(string) return err
} }
s.parts = parts s.parts = parts
case map[interface{}]interface{}: case map[interface{}]interface{}:
parts := make([]string, 0, len(value)) parts, err := toSepMapParts(value, ":")
for k, v := range value { if err != nil {
parts = append(parts, strings.Join([]string{k.(string), v.(string)}, ":")) return err
} }
s.parts = parts s.parts = parts
default: default:
@@ -251,15 +291,15 @@ func (s MaporSpaceSlice) MarshalYAML() (tag string, value interface{}, err error
func (s *MaporSpaceSlice) UnmarshalYAML(tag string, value interface{}) error { func (s *MaporSpaceSlice) UnmarshalYAML(tag string, value interface{}) error {
switch value := value.(type) { switch value := value.(type) {
case []interface{}: case []interface{}:
parts := make([]string, len(value)) parts, err := toStrings(value)
for k, v := range value { if err != nil {
parts[k] = v.(string) return err
} }
s.parts = parts s.parts = parts
case map[interface{}]interface{}: case map[interface{}]interface{}:
parts := make([]string, 0, len(value)) parts, err := toSepMapParts(value, " ")
for k, v := range value { if err != nil {
parts = append(parts, strings.Join([]string{k.(string), v.(string)}, " ")) return err
} }
s.parts = parts s.parts = parts
default: default:

View File

@@ -5,6 +5,7 @@ import (
yaml "github.com/cloudfoundry-incubator/candiedyaml" yaml "github.com/cloudfoundry-incubator/candiedyaml"
"fmt"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -142,21 +143,26 @@ func TestSliceOrMapYaml(t *testing.T) {
assert.Equal(t, map[string]string{"bar": "baz", "far": "faz"}, s2.Foos.parts) assert.Equal(t, map[string]string{"bar": "baz", "far": "faz"}, s2.Foos.parts)
} }
var sampleStructSliceorMap = `udav: var sampleStructSliceorMap = `
foos: foos:
io.rancher.os.bar: baz io.rancher.os.bar: baz
io.rancher.os.far: faz io.rancher.os.far: true
bars: [] bars: []
` `
func TestUnmarshalSliceOrMap(t *testing.T) {
s := StructSliceorMap{}
err := yaml.Unmarshal([]byte(sampleStructSliceorMap), &s)
assert.Equal(t, fmt.Errorf("Cannot unmarshal 'true' of type bool into a string value"), err)
}
func TestStr2SliceOrMapPtrMap(t *testing.T) { func TestStr2SliceOrMapPtrMap(t *testing.T) {
s := map[string]*StructSliceorMap{"udav": { s := map[string]*StructSliceorMap{"udav": {
Foos: SliceorMap{map[string]string{"io.rancher.os.bar": "baz", "io.rancher.os.far": "faz"}}, Foos: SliceorMap{map[string]string{"io.rancher.os.bar": "baz", "io.rancher.os.far": "true"}},
Bars: []string{}, Bars: []string{},
}} }}
d, err := yaml.Marshal(&s) d, err := yaml.Marshal(&s)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, sampleStructSliceorMap, string(d))
s2 := map[string]*StructSliceorMap{} s2 := map[string]*StructSliceorMap{}
yaml.Unmarshal(d, &s2) yaml.Unmarshal(d, &s2)