fix(copystructure): handle nil elements in slice copying

When copying slices containing nil interface{} elements, the copyValue
function would panic with 'reflect: call of reflect.Value.Set on zero
Value'. This occurred because reflect.ValueOf(nil) returns a zero Value
that cannot be set.

This issue was introduced in v4.1.0 when replacing mitchellh/copystructure
with an internal implementation. The fix mirrors the existing nil handling
logic used for map values.

Fixes helm template panic when processing charts with YAML like:
  extraArgs:
    -

Added test case to verify slice elements with nil values are properly
handled during deep copy operations.

Signed-off-by: Philipp Born <git@pborn.eu>
pull/31751/head
Philipp Born 1 week ago
parent 340b06d8f3
commit e3829ebbbb
No known key found for this signature in database
GPG Key ID: 8F5874E00662B261

@ -89,7 +89,15 @@ func copyValue(original reflect.Value) (any, error) {
}
copied := reflect.MakeSlice(original.Type(), original.Len(), original.Cap())
for i := 0; i < original.Len(); i++ {
val, err := copyValue(original.Index(i))
elem := original.Index(i)
// Handle nil values in slices (e.g., interface{} elements that are nil)
if elem.Kind() == reflect.Interface && elem.IsNil() {
copied.Index(i).Set(elem)
continue
}
val, err := copyValue(elem)
if err != nil {
return nil, err
}

@ -113,6 +113,21 @@ func TestCopy_Slice(t *testing.T) {
input[0]["key1"] = "modified"
assert.Equal(t, "value1", resultSlice[0]["key1"])
})
t.Run("slice with nil elements", func(t *testing.T) {
input := []any{
"value1",
nil,
"value2",
}
result, err := Copy(input)
require.NoError(t, err)
resultSlice, ok := result.([]any)
require.True(t, ok)
assert.Equal(t, input, resultSlice)
assert.Nil(t, resultSlice[1])
})
}
func TestCopy_Map(t *testing.T) {

Loading…
Cancel
Save