From f8491489e782254de3570c733b4782332e13f76f Mon Sep 17 00:00:00 2001 From: Pavel Zeman Date: Thu, 19 Mar 2026 22:51:16 +0000 Subject: [PATCH] fix: prevent index out of range panic in createProfileImage for empty usernames Add bounds checking for empty/whitespace-only usernames in createProfileImage to prevent 'runtime error: index out of range [0] with length 0' panic. Uses strings.TrimSpace + length check before indexing, with "?" fallback. Also uses []rune conversion for correct Unicode handling. Sentry: MATTERMOST-SERVER-W1 https://mattermost-mr.sentry.io/issues/7267161420/ Co-authored-by: Claude --- server/channels/app/users/profile_picture.go | 9 ++++++++- .../channels/app/users/profile_picture_test.go | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/server/channels/app/users/profile_picture.go b/server/channels/app/users/profile_picture.go index 63c0c556127..13e1b9bcdbd 100644 --- a/server/channels/app/users/profile_picture.go +++ b/server/channels/app/users/profile_picture.go @@ -135,7 +135,14 @@ func createProfileImage(username string, userID string, initialFont string) ([]b h.Write([]byte(userID)) seed := h.Sum32() - initial := string(strings.ToUpper(username)[0]) + // Guard against empty/whitespace-only usernames which can occur when user records + // bypass model validation (e.g. LDAP/SAML sync, direct DB inserts, data migrations). + // See: api4.getProfileImage → app.GetProfileImage → GetDefaultProfileImage → createProfileImage + trimmedUsername := strings.TrimSpace(username) + initial := "?" + if trimmedUsername != "" { + initial = string([]rune(strings.ToUpper(trimmedUsername))[0]) + } font, err := getFont(initialFont) if err != nil { diff --git a/server/channels/app/users/profile_picture_test.go b/server/channels/app/users/profile_picture_test.go index 6d2bc40030c..3054c07949f 100644 --- a/server/channels/app/users/profile_picture_test.go +++ b/server/channels/app/users/profile_picture_test.go @@ -24,3 +24,21 @@ func TestCreateProfileImage(t *testing.T) { require.Equal(t, colorful, img.At(1, 1), "Failed to create correct color") } + +func TestCreateProfileImage_EmptyUsername(t *testing.T) { + t.Run("empty username should not panic", func(t *testing.T) { + require.NotPanics(t, func() { + b, err := createProfileImage("", "eo1zkdr96pdj98pjmq8zy35wba", "nunito-bold.ttf") + require.NoError(t, err) + require.NotEmpty(t, b) + }) + }) + + t.Run("whitespace-only username should not panic", func(t *testing.T) { + require.NotPanics(t, func() { + b, err := createProfileImage(" ", "eo1zkdr96pdj98pjmq8zy35wba", "nunito-bold.ttf") + require.NoError(t, err) + require.NotEmpty(t, b) + }) + }) +}