From e794a2d85b084ae8a8f5a493d6030397151698f3 Mon Sep 17 00:00:00 2001 From: syf2211 Date: Sat, 27 Jun 2026 14:07:22 +0000 Subject: [PATCH 1/2] fix(issues): strip invisible characters from add_issue_comment body Filter BiDi and other invisible Unicode control characters from issue comment bodies before posting to GitHub. These characters can render as visible separators and break @mentions such as @dependabot rebase. Fixes #2714 --- pkg/github/issues.go | 4 ++++ pkg/github/issues_test.go | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/github/issues.go b/pkg/github/issues.go index 62db8d48d..d950652e3 100644 --- a/pkg/github/issues.go +++ b/pkg/github/issues.go @@ -1243,6 +1243,10 @@ func AddIssueComment(t translations.TranslationHelperFunc) inventory.ServerTool var commentResponse *MinimalResponse if hasBody { + body = sanitize.FilterInvisibleCharacters(body) + if body == "" { + return utils.NewToolResultError("body cannot be empty after removing invisible characters"), nil, nil + } comment := &github.IssueComment{ Body: github.Ptr(body), } diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index 3be4fe1b5..1dd0e023e 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -4154,6 +4154,21 @@ func TestAddIssueComment(t *testing.T) { "body": "This is a comment", }, }, + { + name: "strips invisible characters from comment body before posting", + mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{ + PostReposIssuesCommentsByOwnerByRepoByIssueNumber: expect(t, expectations{ + path: "/repos/owner/repo/issues/42/comments", + requestBody: map[string]any{"body": "@dependabot rebase"}, + }).andThen(mockResponse(t, http.StatusCreated, mockComment)), + }), + requestArgs: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(42), + "body": "\u2068@\u2069\u2068d\u2069ependabot rebase", + }, + }, { name: "successful reaction to issue", mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{ From 38a1158722ab84b4844e7acd3ef9d2ed0cc3ca1d Mon Sep 17 00:00:00 2001 From: syf2211 Date: Sat, 27 Jun 2026 14:09:13 +0000 Subject: [PATCH 2/2] test(issues): cover empty body after invisible character filtering --- pkg/github/issues_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index 1dd0e023e..a2ae1dde5 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -4169,6 +4169,17 @@ func TestAddIssueComment(t *testing.T) { "body": "\u2068@\u2069\u2068d\u2069ependabot rebase", }, }, + { + name: "rejects comment body that is only invisible characters", + requestArgs: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(42), + "body": "\u200B\u2068\u2069", + }, + expectToolError: true, + expectedToolErrMsg: "body cannot be empty after removing invisible characters", + }, { name: "successful reaction to issue", mockedClient: MockHTTPClientWithHandlers(map[string]http.HandlerFunc{