diff --git a/coderd/httpapi/httpapi.go b/coderd/httpapi/httpapi.go index 942419182dfc1..e0f510b372276 100644 --- a/coderd/httpapi/httpapi.go +++ b/coderd/httpapi/httpapi.go @@ -182,7 +182,7 @@ func WebsocketCloseSprintf(format string, vars ...any) string { if len(msg) > websocketCloseMaxLen { // Trim the string to 123 bytes. If we accidentally cut in the middle of // a UTF-8 character, remove it from the string. - return strings.ToValidUTF8(string(msg[123]), "") + return strings.ToValidUTF8(msg[:websocketCloseMaxLen], "") } return msg diff --git a/coderd/httpapi/httpapi_test.go b/coderd/httpapi/httpapi_test.go index 77ff9cdca6fd6..ea6d5a92ea5be 100644 --- a/coderd/httpapi/httpapi_test.go +++ b/coderd/httpapi/httpapi_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "net/http" "net/http/httptest" "strings" @@ -122,15 +123,28 @@ func TestRead(t *testing.T) { }) } -func WebsocketCloseMsg(t *testing.T) { +func TestWebsocketCloseMsg(t *testing.T) { t.Parallel() + t.Run("Sprintf", func(t *testing.T) { + t.Parallel() + + var ( + msg = "this is my message %q %q" + opts = []any{"colin", "kyle"} + ) + + expected := fmt.Sprintf(msg, opts...) + got := httpapi.WebsocketCloseSprintf(msg, opts...) + assert.Equal(t, expected, got) + }) + t.Run("TruncateSingleByteCharacters", func(t *testing.T) { t.Parallel() msg := strings.Repeat("d", 255) trunc := httpapi.WebsocketCloseSprintf(msg) - assert.LessOrEqual(t, len(trunc), 123) + assert.Equal(t, len(trunc), 123) }) t.Run("TruncateMultiByteCharacters", func(t *testing.T) { @@ -138,6 +152,6 @@ func WebsocketCloseMsg(t *testing.T) { msg := strings.Repeat("こんにちは", 10) trunc := httpapi.WebsocketCloseSprintf(msg) - assert.LessOrEqual(t, len(trunc), 123) + assert.Equal(t, len(trunc), 123) }) }