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) { |
| 180 | 180 | for _, cmd := range Commands() { |
| 181 | 181 | u := cmd.Usage |
| 182 | 182 | 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 -") |
| 184 | 185 | if wants && !cmd.ReadsStdin { |
| 185 | 186 | t.Errorf("%s: usage %q reads stdin but ReadsStdin is not set", strings.Join(cmd.Path, " "), u) |
| 186 | 187 | } |
internal/control/webhook.go
+1 −1
| @@ -87,7 +87,7 @@ func runWebhookAdd(c *Ctx, args []string) int { |
| 87 | 87 | if err != nil { |
| 88 | 88 | return c.fail(protocol.ExitFailure, "reading secret: %v", err) |
| 89 | 89 | } |
| 90 | | secret = strings.TrimRight(string(raw), "\n") |
| 90 | secret = strings.TrimRight(string(raw), "\r\n") |
| 91 | 91 | if secret == "" { |
| 92 | 92 | return c.fail(protocol.ExitUsage, "no secret on stdin (pipe it: printf %%s SECRET | ... --secret -)") |
| 93 | 93 | } |
internal/control/webhook_test.go
+7 −3
| @@ -70,11 +70,15 @@ func TestWebhookAddSecretFromStdin(t *testing.T) { |
| 70 | 70 | if msg, code := run("not a secret\n", "webhook", "add", repo.Path(), "http://127.0.0.1/other"); code != protocol.ExitOK { |
| 71 | 71 | t.Fatalf("no secret: exit %d, %q", code, msg) |
| 72 | 72 | } |
| 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 | } |
| 73 | 77 | hooks, err := st.ListWebhooks(repo.ID) |
| 74 | | if err != nil || len(hooks) != 2 { |
| 78 | if err != nil || len(hooks) != 3 { |
| 75 | 79 | t.Fatalf("hooks: %+v %v", hooks, err) |
| 76 | 80 | } |
| 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) |
| 79 | 83 | } |
| 80 | 84 | } |