Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Fix data race in decodeStruct #101

Merged
merged 1 commit into from
Oct 17, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions mapstructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,11 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)

// Compile the list of all the fields that we're going to be decoding
// from all the structs.
fields := make(map[*reflect.StructField]reflect.Value)
type field struct {
field reflect.StructField
val reflect.Value
}
fields := []field{}
for len(structs) > 0 {
structVal := structs[0]
structs = structs[1:]
Expand Down Expand Up @@ -718,14 +722,16 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
}

// Normal struct field, store it away
fields[&fieldType] = structVal.Field(i)
fields = append(fields, field{fieldType, structVal.Field(i)})
}
}

for fieldType, field := range fields {
fieldName := fieldType.Name
// for fieldType, field := range fields {
for _, f := range fields {
field, fieldValue := f.field, f.val
fieldName := field.Name

tagValue := fieldType.Tag.Get(d.config.TagName)
tagValue := field.Tag.Get(d.config.TagName)
tagValue = strings.SplitN(tagValue, ",", 2)[0]
if tagValue != "" {
fieldName = tagValue
Expand Down Expand Up @@ -760,14 +766,14 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
// Delete the key we're using from the unused map so we stop tracking
delete(dataValKeysUnused, rawMapKey.Interface())

if !field.IsValid() {
if !fieldValue.IsValid() {
// This should never happen
panic("field is not valid")
}

// If we can't set the field, then it is unexported or something,
// and we just continue onwards.
if !field.CanSet() {
if !fieldValue.CanSet() {
continue
}

Expand All @@ -777,7 +783,7 @@ func (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value)
fieldName = fmt.Sprintf("%s.%s", name, fieldName)
}

if err := d.decode(fieldName, rawMapVal.Interface(), field); err != nil {
if err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {
errors = appendErrors(errors, err)
}
}
Expand Down