Skip to content

Commit eb8480c

Browse files
committed
fix: panic in configpatcher when the whole section is missing
Reproducer can be found in testdata, but tl;dr it tries to traverse via `*T` where `T` is a nested struct, and the pointer value is nil. It was seen in the tests with Talos 1.13+ which drops `.machine.network` completely by default. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> (cherry picked from commit 415bfae)
1 parent 4d44306 commit eb8480c

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

pkg/machinery/config/configloader/internal/decoder/selector.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ func deleteForPath(val reflect.Value, path []string, key, value string) error {
141141
}
142142

143143
if val.Kind() == reflect.Pointer || val.Kind() == reflect.Interface {
144+
if val.IsNil() {
145+
return ErrLookupFailed
146+
}
147+
144148
return deleteForPath(val.Elem(), path, key, value)
145149
}
146150

pkg/machinery/config/configpatcher/apply_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,36 @@ func TestApplyMultiDocCPDelete(t *testing.T) {
292292
})
293293
}
294294
}
295+
296+
//go:embed testdata/patchdeletemissing/config.yaml
297+
var configPatchDeleteMissing []byte
298+
299+
func TestPatchDeleteMissing(t *testing.T) {
300+
patches, err := configpatcher.LoadPatches([]string{
301+
"@testdata/patchdeletemissing/strategic1.yaml",
302+
})
303+
require.NoError(t, err)
304+
305+
cfg, err := configloader.NewFromBytes(configPatchDeleteMissing)
306+
require.NoError(t, err)
307+
308+
for _, tt := range []struct {
309+
name string
310+
input configpatcher.Input
311+
}{
312+
{
313+
name: "WithConfig",
314+
input: configpatcher.WithConfig(cfg),
315+
},
316+
{
317+
name: "WithBytes",
318+
input: configpatcher.WithBytes(configPatchDeleteMissing),
319+
},
320+
} {
321+
t.Run(tt.name, func(t *testing.T) {
322+
_, err := configpatcher.Apply(tt.input, patches)
323+
require.Error(t, err)
324+
require.ErrorContains(t, err, `patch delete: path 'machine.network.hostname' in document '/v1alpha1': failed to delete path 'machine.network.hostname': lookup failed`)
325+
})
326+
}
327+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
version: v1alpha1
2+
machine: {}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
machine:
2+
network:
3+
hostname:
4+
$patch: delete

0 commit comments

Comments
 (0)