Commit 92e025a4f6

92e025a4f688baf87e197921b1f99c3bb76659b4

parent: f3f7422f62

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-12 02:20 UTC

config: refuse a negative max_snippets_per_user

The load-time check that rejects a negative max_repos_per_user or
max_bytes_per_user now covers max_snippets_per_user, which otherwise
read as unlimited. gofmt realigns the two fields after it.

Closes #214
internal/config/config.go +4 −4
@@ -180,8 +180,8 @@ type Limits struct {
180180 // MaxSnippetsPerUser caps snippets an account may own. 0 means
181181 // unlimited, like MaxReposPerUser.
182182 MaxSnippetsPerUser int `toml:"max_snippets_per_user"`
183 CloneTimeoutSec int `toml:"clone_timeout"`
184 SSHAuthRate int `toml:"ssh_auth_rate"`
183 CloneTimeoutSec int `toml:"clone_timeout"`
184 SSHAuthRate int `toml:"ssh_auth_rate"`
185185 // APIRate is sustained JSON-API requests per minute per caller; writes
186186 // draw on a tenth of it. 0 uses the default.
187187 APIRate int `toml:"api_rate"`
@@ -277,8 +277,8 @@ func (c Config) Validate() error {
277277 errs = append(errs, fmt.Errorf("registration.pending_expiry %q must be a positive duration such as 168h", c.Registration.PendingExpiry))
278278 }
279279 }
280 if c.Limits.MaxReposPerUser < 0 || c.Limits.MaxBytesPerUser < 0 {
281 errs = append(errs, errors.New("limits.max_repos_per_user and max_bytes_per_user must not be negative"))
280 if c.Limits.MaxReposPerUser < 0 || c.Limits.MaxBytesPerUser < 0 || c.Limits.MaxSnippetsPerUser < 0 {
281 errs = append(errs, errors.New("limits.max_repos_per_user, max_bytes_per_user and max_snippets_per_user must not be negative"))
282282 }
283283 if c.SSH.Port < 1 || c.SSH.Port > 65535 {
284284 errs = append(errs, fmt.Errorf("ssh.port %d out of range", c.SSH.Port))
internal/config/config_test.go +10
@@ -80,6 +80,16 @@ func TestContradictions(t *testing.T) {
8080 "[server]\nroot = \"/var/lib/gitbay\"\n",
8181 "site_url",
8282 },
83 {
84 "negative repo limit",
85 minimal + "\n[limits]\nmax_repos_per_user = -1\n",
86 "must not be negative",
87 },
88 {
89 "negative snippet limit",
90 minimal + "\n[limits]\nmax_snippets_per_user = -1\n",
91 "max_snippets_per_user",
92 },
8393 }
8494 for _, tc := range cases {
8595 t.Run(tc.name, func(t *testing.T) {