Commit 132441b6f5

132441b6f5658d47482dc3c499c428638f4097da

parent: 0cd2b3a8ac

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-29 02:28 UTC

control: webhook add trims a CRLF from the secret; --secret - counts as stdin

Ref #284

Layout: unified · split

internal/control/control_test.go +2 −1
@@ -180,7 +180,8 @@ func TestStdinCommandsReadStdin(t *testing.T) {
180180 for _, cmd := range Commands() {
181181 u := cmd.Usage
182182 wants := strings.Contains(u, "--file -") || strings.Contains(u, "< ") ||
183 strings.Contains(u, "stdin") || strings.Contains(u, "--key -")
183 strings.Contains(u, "stdin") || strings.Contains(u, "--key -") ||
184 strings.Contains(u, "--secret -")
184185 if wants && !cmd.ReadsStdin {
185186 t.Errorf("%s: usage %q reads stdin but ReadsStdin is not set", strings.Join(cmd.Path, " "), u)
186187 }
internal/control/webhook.go +1 −1
@@ -87,7 +87,7 @@ func runWebhookAdd(c *Ctx, args []string) int {
8787 if err != nil {
8888 return c.fail(protocol.ExitFailure, "reading secret: %v", err)
8989 }
90 secret = strings.TrimRight(string(raw), "\n")
90 secret = strings.TrimRight(string(raw), "\r\n")
9191 if secret == "" {
9292 return c.fail(protocol.ExitUsage, "no secret on stdin (pipe it: printf %%s SECRET | ... --secret -)")
9393 }
internal/control/webhook_test.go +7 −3
@@ -70,11 +70,15 @@ func TestWebhookAddSecretFromStdin(t *testing.T) {
7070 if msg, code := run("not a secret\n", "webhook", "add", repo.Path(), "http://127.0.0.1/other"); code != protocol.ExitOK {
7171 t.Fatalf("no secret: exit %d, %q", code, msg)
7272 }
73 // A secret from a file with CRLF line endings loses the \r too.
74 if msg, code := run("crlf\r\n", "webhook", "add", repo.Path(), "http://127.0.0.1/crlf", "--secret", "-"); code != protocol.ExitOK {
75 t.Fatalf("CRLF secret: exit %d, %q", code, msg)
76 }
7377 hooks, err := st.ListWebhooks(repo.ID)
74 if err != nil || len(hooks) != 2 {
78 if err != nil || len(hooks) != 3 {
7579 t.Fatalf("hooks: %+v %v", hooks, err)
7680 }
77 if hooks[0].Secret != "s3cret" || hooks[1].Secret != "" {
78 t.Fatalf("secrets: %q, %q", hooks[0].Secret, hooks[1].Secret)
81 if hooks[0].Secret != "s3cret" || hooks[1].Secret != "" || hooks[2].Secret != "crlf" {
82 t.Fatalf("secrets: %q, %q, %q", hooks[0].Secret, hooks[1].Secret, hooks[2].Secret)
7983 }
8084}