cmd/cloner, cmd/viewer: handle named map/slice types with Clone/View methods
The cloner and viewer code generators didn't handle named types
with basic underlying types (map/slice) that have their own Clone
or View methods. For example, a type like:
type Map map[string]any
func (m Map) Clone() Map { ... }
func (m Map) View() MapView { ... }
When used as a struct field, the cloner would descend into the
underlying map[string]any and fail because it can't clone the any
(interface{}) value type. Similarly, the viewer would try to create
a MapFnOf view and fail.
Fix the cloner to check for a Clone method on the named type
before falling through to the underlying type handling.
Fix the viewer to check for a View method on named map/slice types,
so the type author can provide a purpose-built safe view that
doesn't leak raw any values. Named map/slice types without a View
method fall through to normal handling, which correctly rejects
types like map[string]any as unsupported.
Updates tailscale/corp#39502 (needed by tailscale/corp#39594)
Change-Id: Iaef0192a221e02b4b8e409c99ef8398090327744
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
5a899e406d
commit
86f42ea87b
@@ -154,6 +154,34 @@ func TestMapWithPointers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamedMapContainer(t *testing.T) {
|
||||
orig := &clonerex.NamedMapContainer{
|
||||
Attrs: clonerex.NamedMap{
|
||||
"str": "hello",
|
||||
"num": int64(42),
|
||||
"bool": true,
|
||||
},
|
||||
}
|
||||
|
||||
cloned := orig.Clone()
|
||||
if !reflect.DeepEqual(orig, cloned) {
|
||||
t.Errorf("Clone() = %v, want %v", cloned, orig)
|
||||
}
|
||||
|
||||
// Mutate the cloned map to verify no aliasing.
|
||||
cloned.Attrs["str"] = "modified"
|
||||
if orig.Attrs["str"] == "modified" {
|
||||
t.Errorf("Clone() aliased memory in Attrs: original was modified")
|
||||
}
|
||||
|
||||
// Verify nil handling.
|
||||
nilContainer := &clonerex.NamedMapContainer{}
|
||||
nilClone := nilContainer.Clone()
|
||||
if !reflect.DeepEqual(nilContainer, nilClone) {
|
||||
t.Errorf("Clone() of nil Attrs = %v, want %v", nilClone, nilContainer)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeeplyNestedMap(t *testing.T) {
|
||||
num := 123
|
||||
orig := &clonerex.DeeplyNestedMap{
|
||||
|
||||
Reference in New Issue
Block a user