Merge pull request #68 from sitano/fix_decode_slice

fix decode slice in zero fields false case
diff --git a/mapstructure.go b/mapstructure.go
index bd46603..1595982 100644
--- a/mapstructure.go
+++ b/mapstructure.go
@@ -606,6 +606,9 @@
 
 	for i := 0; i < dataVal.Len(); i++ {
 		currentData := dataVal.Index(i).Interface()
+		for valSlice.Len() <= i {
+			valSlice = reflect.Append(valSlice, reflect.Zero(valElemType))
+		}
 		currentField := valSlice.Index(i)
 
 		fieldName := fmt.Sprintf("%s[%d]", name, i)
diff --git a/mapstructure_bugs_test.go b/mapstructure_bugs_test.go
index 2e210ca..08e4956 100644
--- a/mapstructure_bugs_test.go
+++ b/mapstructure_bugs_test.go
@@ -59,7 +59,7 @@
 		},
 	}
 
-	result:=NestedPointer{
+	result := NestedPointer{
 		Vbar: &Basic{
 			Vuint: 42,
 		},
@@ -96,10 +96,9 @@
 
 }
 
-
 type NestedSlice struct {
-	Vfoo string
-	Vbars []Basic
+	Vfoo   string
+	Vbars  []Basic
 	Vempty []Basic
 }
 
@@ -110,16 +109,16 @@
 	input := map[string]interface{}{
 		"vfoo": "foo",
 		"vbars": []map[string]interface{}{
-			{ "vstring": "foo", "vint":    42, "vbool":   true },
-			{ "vint":    42, "vbool":   true },
+			{"vstring": "foo", "vint": 42, "vbool": true},
+			{"vint": 42, "vbool": true},
 		},
 		"vempty": []map[string]interface{}{
-			{ "vstring": "foo", "vint":    42, "vbool":   true },
-			{ "vint":    42, "vbool":   true },
+			{"vstring": "foo", "vint": 42, "vbool": true},
+			{"vint": 42, "vbool": true},
 		},
 	}
 
-	result:=NestedSlice{
+	result := NestedSlice{
 		Vbars: []Basic{
 			{Vuint: 42},
 			{Vstring: "foo"},
@@ -141,7 +140,6 @@
 	if result.Vbars[0].Vuint != 42 {
 		t.Errorf("vuint value should be 42: %#v", result.Vbars[0].Vuint)
 	}
-
 }
 
 // #48 workaround
@@ -157,7 +155,7 @@
 		},
 	}
 
-	result:=Nested{
+	result := Nested{
 		Vbar: Basic{
 			Vuint: 42,
 		},
@@ -192,4 +190,71 @@
 		t.Errorf("vuint value should be 42: %#v", result.Vbar.Vuint)
 	}
 
-}
\ No newline at end of file
+}
+
+// #67 panic() on extending slices (decodeSlice with disabled ZeroValues)
+func TestDecodeSliceToEmptySliceWOZeroing(t *testing.T) {
+	t.Parallel()
+
+	type TestStruct struct {
+		Vfoo []string
+	}
+
+	decode := func(m interface{}, rawVal interface{}) error {
+		config := &DecoderConfig{
+			Metadata:   nil,
+			Result:     rawVal,
+			ZeroFields: false,
+		}
+
+		decoder, err := NewDecoder(config)
+		if err != nil {
+			return err
+		}
+
+		return decoder.Decode(m)
+	}
+
+	{
+		input := map[string]interface{}{
+			"vfoo": []string{"1"},
+		}
+
+		result := &TestStruct{}
+
+		err := decode(input, &result)
+		if err != nil {
+			t.Fatalf("got an err: %s", err.Error())
+		}
+	}
+
+	{
+		input := map[string]interface{}{
+			"vfoo": []string{"1"},
+		}
+
+		result := &TestStruct{
+			Vfoo: []string{},
+		}
+
+		err := decode(input, &result)
+		if err != nil {
+			t.Fatalf("got an err: %s", err.Error())
+		}
+	}
+
+	{
+		input := map[string]interface{}{
+			"vfoo": []string{"2", "3"},
+		}
+
+		result := &TestStruct{
+			Vfoo: []string{"1"},
+		}
+
+		err := decode(input, &result)
+		if err != nil {
+			t.Fatalf("got an err: %s", err.Error())
+		}
+	}
+}