Skip to content

Commit 2b0dfca

Browse files
committed
escape all user text and provide pretty-printing utility functions
PR titles, comments, etc. should all be escaped.
1 parent 098411e commit 2b0dfca

File tree

1 file changed

+48
-55
lines changed

1 file changed

+48
-55
lines changed

lib/slack.ml

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ let show_labels = function
3434

3535
let pluralize name num suffix = if num = 1 then sprintf "%s" name else String.concat [ name; suffix ]
3636

37+
let escape = Mrkdwn.escape_mrkdwn
38+
39+
let pp_link url text = sprintf "<%s|%s>" url (escape text)
40+
41+
let pp_repo (repo : repository) = sprintf "[%s]" repo.full_name
42+
43+
let pp_repo_mrkdwn (repo : repository) = pp_link repo.url @@ pp_repo repo
44+
3745
let generate_pull_request_notification notification channel =
3846
let { action; number; sender; pull_request; repository } = notification in
3947
let ({ body; title; html_url; labels; _ } : pull_request) = pull_request in
@@ -50,11 +58,11 @@ let generate_pull_request_notification notification channel =
5058
in
5159
let summary =
5260
Some
53-
(sprintf "<%s|[%s]> Pull request #%d <%s|%s> %s by *%s*" repository.url repository.full_name number html_url title
54-
action sender.login)
61+
(sprintf "%s Pull request #%d %s %s by *%s*" (pp_repo_mrkdwn repository) number (pp_link html_url title) action
62+
sender.login)
5563
in
5664
let fallback =
57-
Some (sprintf "[%s] Pull request #%d %s %s by %s" repository.full_name number title action sender.login)
65+
Some (sprintf "%s Pull request #%d %s %s by %s" (pp_repo repository) number title action sender.login)
5866
in
5967
{
6068
channel;
@@ -93,10 +101,10 @@ let generate_pr_review_notification notification channel =
93101
in
94102
let summary =
95103
Some
96-
(sprintf "<%s|[%s]> *%s* <%s|%s> #%d <%s|%s>" repository.url repository.full_name sender.login review.html_url
97-
action_str number html_url title)
104+
(sprintf "%s *%s* %s #%d %s" (pp_repo_mrkdwn repository) sender.login (pp_link review.html_url action_str) number
105+
(pp_link html_url title))
98106
in
99-
let fallback = Some (sprintf "[%s] %s %s #%d %s" repository.full_name sender.login action_str number title) in
107+
let fallback = Some (sprintf "%s %s %s #%d %s" (pp_repo repository) sender.login action_str number title) in
100108
{
101109
channel;
102110
text = None;
@@ -128,14 +136,14 @@ let generate_pr_review_comment_notification notification channel =
128136
in
129137
let summary =
130138
Some
131-
(sprintf "<%s|[%s]> *%s* %s on #%d <%s|%s>" repository.url repository.full_name sender.login action_str number
132-
html_url title)
139+
(sprintf "%s *%s* %s on #%d %s" (pp_repo_mrkdwn repository) sender.login action_str number
140+
(pp_link html_url title))
133141
in
134-
let fallback = Some (sprintf "[%s] %s %s on #%d %s" repository.full_name sender.login action_str number title) in
142+
let fallback = Some (sprintf "%s %s %s on #%d %s" (pp_repo repository) sender.login action_str number title) in
135143
let file =
136144
match comment.path with
137145
| None -> None
138-
| Some a -> Some (sprintf "New comment by %s in <%s|%s>" sender.login comment.html_url a)
146+
| Some a -> Some (sprintf "New comment by %s in %s" sender.login (pp_link comment.html_url a))
139147
in
140148
{
141149
channel;
@@ -172,10 +180,10 @@ let generate_issue_notification notification channel =
172180
in
173181
let summary =
174182
Some
175-
(sprintf "<%s|[%s]> Issue #%d <%s|%s> %s by *%s*" repository.url repository.full_name number html_url title action
183+
(sprintf "%s Issue #%d %s %s by *%s*" (pp_repo_mrkdwn repository) number (pp_link html_url title) action
176184
sender.login)
177185
in
178-
let fallback = Some (sprintf "[%s] Issue #%d %s %s by %s" repository.full_name number title action sender.login) in
186+
let fallback = Some (sprintf "%s Issue #%d %s %s by %s" (pp_repo repository) number title action sender.login) in
179187
{
180188
channel;
181189
text = None;
@@ -208,10 +216,10 @@ let generate_issue_comment_notification notification channel =
208216
in
209217
let summary =
210218
Some
211-
(sprintf "<%s|[%s]> *%s* <%s|%s> on #%d <%s|%s>" repository.url repository.full_name sender.login comment.html_url
212-
action_str number issue.html_url title)
219+
(sprintf "%s *%s* %s on #%d %s" (pp_repo_mrkdwn repository) sender.login (pp_link comment.html_url action_str)
220+
number (pp_link issue.html_url title))
213221
in
214-
let fallback = Some (sprintf "[%s] %s %s on #%d %s" repository.full_name sender.login action_str number title) in
222+
let fallback = Some (sprintf "%s %s %s on #%d %s" (pp_repo repository) sender.login action_str number title) in
215223
{
216224
channel;
217225
text = None;
@@ -236,36 +244,24 @@ let generate_push_notification notification channel =
236244
let { sender; created; deleted; forced; compare; commits; repository; _ } = notification in
237245
let commits_branch = Github.commits_branch_of_ref notification.ref in
238246
let tree_url = String.concat ~sep:"/" [ repository.url; "tree"; Uri.pct_encode commits_branch ] in
247+
let repo_branch = sprintf "[%s:%s]" repository.name commits_branch in
248+
let num_commits = sprintf "%d %s" (List.length commits) (pluralize "commit" (List.length commits) "s") in
249+
let action = if forced then "force-pushed" else "pushed" in
250+
let dest = if created then "to new branch " else "" in
239251
let title =
240252
if deleted then
241-
sprintf "<%s|[%s]> %s deleted branch <%s|%s>" tree_url repository.name sender.login compare commits_branch
253+
sprintf "%s %s deleted branch %s" (pp_link tree_url repository.name) sender.login (pp_link compare commits_branch)
242254
else
243-
sprintf "<%s|[%s:%s]> <%s|%i commit%s> %spushed %sby %s" tree_url repository.name commits_branch compare
244-
(List.length commits)
245-
( match commits with
246-
| [ _ ] -> ""
247-
| _ -> "s"
248-
)
249-
(if forced then "force-" else "")
250-
(if created then "to new branch " else "")
251-
sender.login
255+
sprintf "%s %s %s %sby %s" (pp_link tree_url repo_branch) (pp_link compare num_commits) action dest sender.login
252256
in
253257
let fallback =
254-
if deleted then sprintf "[%s] %s deleted branch %s" repository.name sender.login commits_branch
255-
else
256-
sprintf "[%s:%s] %i commit%s %spushed %sby %s" repository.name commits_branch (List.length commits)
257-
( match commits with
258-
| [ _ ] -> ""
259-
| _ -> "s"
260-
)
261-
(if forced then "force-" else "")
262-
(if created then "to new branch " else "")
263-
sender.login
258+
if deleted then sprintf "%s %s deleted branch %s" (pp_repo repository) sender.login commits_branch
259+
else sprintf "%s %s %s %sby %s" repo_branch num_commits action dest sender.login
264260
in
265261
let commits =
266262
List.map commits ~f:(fun { url; id; message; author; _ } ->
267-
let title = first_line message in
268-
sprintf "`<%s|%s>` %s - %s" url (git_short_sha_hash id) title author.name)
263+
let title = escape @@ first_line message in
264+
sprintf "`%s` %s - %s" (pp_link url (git_short_sha_hash id)) title author.name)
269265
in
270266
{
271267
channel;
@@ -310,7 +306,12 @@ let generate_status_notification (cfg : Config_t.config) (notification : status_
310306
| Some s -> Some (sprintf "*Description*: %s." s)
311307
in
312308
let commit_info =
313-
[ sprintf "*Commit*: `<%s|%s>` %s - %s" html_url (git_short_sha_hash sha) (first_line message) author.login ]
309+
[
310+
sprintf "*Commit*: `%s` %s - %s"
311+
(pp_link html_url (git_short_sha_hash sha))
312+
(escape @@ first_line message)
313+
author.login;
314+
]
314315
in
315316
let branches_info =
316317
match List.map ~f:(fun { name } -> name) notification.branches with
@@ -326,21 +327,12 @@ let generate_status_notification (cfg : Config_t.config) (notification : status_
326327
[ sprintf "*%s*: %s" (pluralize "Branch" (List.length branches) "es") (String.concat ~sep:", " branches) ]
327328
in
328329
let summary =
329-
match target_url with
330-
| None ->
331-
Some (sprintf "<%s|[%s]> CI Build Status notification: %s" repository.url repository.full_name state_info)
332-
(* in case the CI run is not using buildkite *)
333-
| Some t ->
334-
Some
335-
(sprintf "<%s|[%s]> CI Build Status notification for <%s|%s>: %s" repository.url repository.full_name t context
336-
state_info)
330+
let target = Option.value_map target_url ~default:"" ~f:(fun url -> sprintf " for %s" (pp_link url context)) in
331+
Some (sprintf "%s CI Build Status notification%s: %s" (pp_repo_mrkdwn repository) target state_info)
337332
in
338333
let fallback =
339-
match target_url with
340-
| None ->
341-
Some (sprintf "[%s] CI Build Status notification: %s" repository.full_name state_info)
342-
(* in case the CI run is not using buildkite *)
343-
| Some _ -> Some (sprintf "[%s] CI Build Status notification for %s: %s" repository.full_name context state_info)
334+
let target = Option.value_map target_url ~default:"" ~f:(fun _ -> sprintf " for %s" context) in
335+
Some (sprintf "%s CI Build Status notification%s: %s" (pp_repo repository) target state_info)
344336
in
345337
let msg = String.concat ~sep:"\n" @@ List.concat [ commit_info; branches_info ] in
346338
let attachment =
@@ -366,18 +358,19 @@ let generate_commit_comment_notification api_commit notification channel =
366358
in
367359
let summary =
368360
Some
369-
(sprintf "<%s|[%s]> *%s* commented on `<%s|%s>` %s" repository.url repository.full_name sender.login
370-
comment.html_url (git_short_sha_hash commit_id) (first_line commit.message))
361+
(sprintf "%s *%s* commented on `%s` %s" (pp_repo_mrkdwn repository) sender.login
362+
(pp_link comment.html_url (git_short_sha_hash commit_id))
363+
(escape @@ first_line commit.message))
371364
in
372365
let fallback =
373366
Some
374-
(sprintf "[%s] %s commented on `%s` %s" repository.full_name sender.login (git_short_sha_hash commit_id)
367+
(sprintf "%s %s commented on `%s` %s" (pp_repo repository) sender.login (git_short_sha_hash commit_id)
375368
(first_line commit.message))
376369
in
377370
let path =
378371
match comment.path with
379372
| None -> None
380-
| Some p -> Some (sprintf "New comment by %s in <%s|%s>" sender.login comment.html_url p)
373+
| Some p -> Some (sprintf "New comment by %s in %s" sender.login (pp_link comment.html_url p))
381374
in
382375
let attachment =
383376
{

0 commit comments

Comments
 (0)