From e722368eeca135c887ef9632a43b469f1ebd70cf Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Tue, 27 Oct 2026 23:15:25 +0100 Subject: [PATCH] structdiff: fix IsEqual panic on named string map keys equalMapStringKey asserted keys with k.Interface().(string), which panics for a defined string key type (e.g. type ScriptHook string). Use Value.String(), as diffMapStringKey already does. Co-authored-by: Isaac --- libs/structs/structdiff/diff_test.go | 8 ++++++++ libs/structs/structdiff/equal.go | 9 ++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/libs/structs/structdiff/diff_test.go b/libs/structs/structdiff/diff_test.go index 15f90f076f6..e273f8774b4 100644 --- a/libs/structs/structdiff/diff_test.go +++ b/libs/structs/structdiff/diff_test.go @@ -974,6 +974,14 @@ func TestGetStructDiffNamedStringMapKey(t *testing.T) { assert.Equal(t, []ResolvedChange{{Field: "m['pre']", Old: "a", New: "b"}}, resolveChanges(got)) } +func TestIsEqualNamedStringMapKey(t *testing.T) { + a := namedKeyMapHolder{M: map[namedMapKey]string{"pre": "a", "post": "x"}} + b := namedKeyMapHolder{M: map[namedMapKey]string{"pre": "b", "post": "x"}} + + assert.True(t, IsEqual(&a, &a)) + assert.False(t, IsEqual(&a, &b)) +} + // Types for the "whole block" tests below: two levels of nesting under an // optional pointer, mirroring a schema like Outer{Field *Mid{A *Inner{b,c}}}. type wbInner struct { diff --git a/libs/structs/structdiff/equal.go b/libs/structs/structdiff/equal.go index 014f6f7af36..6ed8243d40b 100644 --- a/libs/structs/structdiff/equal.go +++ b/libs/structs/structdiff/equal.go @@ -155,13 +155,12 @@ func equalStruct(s1, s2 reflect.Value) bool { func equalMapStringKey(m1, m2 reflect.Value) bool { keySet := map[string]reflect.Value{} for _, k := range m1.MapKeys() { - // Key is always string at this point - ks := k.Interface().(string) - keySet[ks] = k + // Key kind is always String at this point; Value.String() also handles a + // named string key type, where a .(string) assertion panics. + keySet[k.String()] = k } for _, k := range m2.MapKeys() { - ks := k.Interface().(string) - keySet[ks] = k + keySet[k.String()] = k } for _, k := range keySet {