From e1bf8d692c2e51c980bdc5ba48fbde74f7331982 Mon Sep 17 00:00:00 2001 From: git-hulk Date: Mon, 25 Nov 2024 19:54:20 +0800 Subject: [PATCH] Fix panic in DefaultResolveFn if uses the string type alias in source key This closes #700. --- executor.go | 15 ++++++++++++++- executor_test.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/executor.go b/executor.go index 7440ae21e..cea74c54f 100644 --- a/executor.go +++ b/executor.go @@ -995,7 +995,20 @@ func DefaultResolveFn(p ResolveParams) (interface{}, error) { // Try accessing as map via reflection if r := reflect.ValueOf(p.Source); r.Kind() == reflect.Map && r.Type().Key().Kind() == reflect.String { - val := r.MapIndex(reflect.ValueOf(p.Info.FieldName)) + fieldNameValue := reflect.ValueOf(p.Info.FieldName) + mapKeyType := r.Type().Key() + // The map key type might be a string type alias and its underlying type is string, + // but it will be panic if we try to use it as a string value in `MapIndex`. + // So we need to convert the value of the field name to the map key type before + // using it as a map key. + // + // Related issue: https://github.com/graphql-go/graphql/issues/700 + if !fieldNameValue.CanConvert(mapKeyType) { + return nil, nil + } + fieldNameValue = fieldNameValue.Convert(mapKeyType) + + val := r.MapIndex(fieldNameValue) if val.IsValid() { property := val.Interface() if val.Type().Kind() == reflect.Func { diff --git a/executor_test.go b/executor_test.go index 856aadf3e..f2cee54f4 100644 --- a/executor_test.go +++ b/executor_test.go @@ -15,6 +15,17 @@ import ( "github.com/graphql-go/graphql/testutil" ) +func TestDefaultResolveFn(t *testing.T) { + type Key string + type Source map[Key]interface{} + source := Source{ + "foo": "bar", + } + graphql.DefaultResolveFn(graphql.ResolveParams{ + Source: source, + }) +} + func TestExecutesArbitraryCode(t *testing.T) { deepData := map[string]interface{}{}