Description
Hello,
We have observed in Crossplane project's CNCF fuzzing tests that runtime.DefaultUnstructuredConverter.ToUnstructured
(from k8s.io/[email protected]
) consuming sigs.k8s.io/structured-merge-diff/[email protected]
panics with the following sample program:
package main
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
type Test struct {
Time *metav1.Time
}
func main() {
if _, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&Test{}); err != nil {
panic(err)
}
}
, producing the following stacktrace:
panic: value method k8s.io/apimachinery/pkg/apis/meta/v1.Time.ToUnstructured called using nil *Time pointer
goroutine 1 [running]:
k8s.io/apimachinery/pkg/apis/meta/v1.(*Time).ToUnstructured(0x100000001?)
<autogenerated>:1 +0x48
sigs.k8s.io/structured-merge-diff/v4/value.TypeReflectCacheEntry.ToUnstructured({0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, {0x0, 0x0, 0x0}}, ...)
/Users/alper/data/workspaces/go/pkg/mod/sigs.k8s.io/structured-merge-diff/[email protected]/value/reflectcache.go:188 +0x6b0
k8s.io/apimachinery/pkg/runtime.toUnstructured({0x100f7cba0?, 0x140001aa3d0?, 0x0?}, {0x100efef60?, 0x14000193f10?, 0x0?})
/Users/alper/data/workspaces/go/pkg/mod/k8s.io/[email protected]/pkg/runtime/converter.go:655 +0x8a0
k8s.io/apimachinery/pkg/runtime.structToUnstructured({0x100f1f260?, 0x140001aa3d0?, 0x100f7f5e0?}, {0x100f0a3c0?, 0x140001aa3d8?, 0x100a61548?})
/Users/alper/data/workspaces/go/pkg/mod/k8s.io/[email protected]/pkg/runtime/converter.go:843 +0x7ac
k8s.io/apimachinery/pkg/runtime.toUnstructured({0x100f1f260?, 0x140001aa3d0?, 0x140001aa3d0?}, {0x100f0a3c0?, 0x140001aa3d8?, 0x140000021a0?})
/Users/alper/data/workspaces/go/pkg/mod/k8s.io/[email protected]/pkg/runtime/converter.go:692 +0x7f4
k8s.io/apimachinery/pkg/runtime.(*unstructuredConverter).ToUnstructured(0x101277530, {0x100edca80?, 0x140001aa3d0})
/Users/alper/data/workspaces/go/pkg/mod/k8s.io/[email protected]/pkg/runtime/converter.go:586 +0x364
main.main()
/Users/alper/data/workspaces/github.com/ulucinar/crossplane/crossplane/cmd/test/main.go:13 +0x44
The same behavior is observed also with k8s.io/[email protected]
, which depends on sigs.k8s.io/structured-merge-diff/[email protected]
.
As a workaround, if a json tag is added with the omitempty
specifier, then no panic is observed:
package main
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
type Test struct {
Time *metav1.Time `json:"time,omitempty"`
}
func main() {
if _, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&Test{}); err != nil {
panic(err)
}
}
As the stacktrace points, it looks like we are calling converter.ToUnstructured
with a nil converter
here.
Would adding a nil
check for the converter
variable there be appropriate (and maybe returning a nil, nil
so that we do not attempt to convert a nil
value, or return an error)?