hst/config: identity bounds check early
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m12s
Test / Hakurei (push) Successful in 3m4s
Test / Hpkg (push) Successful in 3m53s
Test / Sandbox (race detector) (push) Successful in 4m28s
Test / Hakurei (race detector) (push) Successful in 5m16s
Test / Flake checks (push) Successful in 1m30s

This makes sense to do here instead of in internal/app.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-10-07 17:58:28 +09:00
parent 9e48d7f562
commit 2489766efe
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
3 changed files with 22 additions and 9 deletions

View File

@ -2,6 +2,7 @@ package hst
import ( import (
"errors" "errors"
"strconv"
"time" "time"
"hakurei.app/container" "hakurei.app/container"
@ -118,15 +119,28 @@ type (
} }
) )
// ErrConfigNull is returned by [Config.Validate] for an invalid configuration that contains a null value for any var (
// field that must not be null. // ErrConfigNull is returned by [Config.Validate] for an invalid configuration that contains a null value for any
var ErrConfigNull = errors.New("unexpected null in config") // field that must not be null.
ErrConfigNull = errors.New("unexpected null in config")
// ErrIdentityBounds is returned by [Config.Validate] for an out of bounds [Config.Identity] value.
ErrIdentityBounds = errors.New("identity out of bounds")
)
// Validate checks [Config] and returns [AppError] if an invalid value is encountered.
func (config *Config) Validate() error { func (config *Config) Validate() error {
if config == nil { if config == nil {
return &AppError{Step: "validate configuration", Err: ErrConfigNull, return &AppError{Step: "validate configuration", Err: ErrConfigNull,
Msg: "invalid configuration"} Msg: "invalid configuration"}
} }
// this is checked again in hsu
if config.Identity < IdentityMin || config.Identity > IdentityMax {
return &AppError{Step: "validate configuration", Err: ErrIdentityBounds,
Msg: "identity " + strconv.Itoa(config.Identity) + " out of range"}
}
if config.Container == nil { if config.Container == nil {
return &AppError{Step: "validate configuration", Err: ErrConfigNull, return &AppError{Step: "validate configuration", Err: ErrConfigNull,
Msg: "configuration missing container state"} Msg: "configuration missing container state"}

View File

@ -16,6 +16,10 @@ func TestConfigValidate(t *testing.T) {
}{ }{
{"nil", nil, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull, {"nil", nil, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
Msg: "invalid configuration"}}, Msg: "invalid configuration"}},
{"identity lower", &hst.Config{Identity: -1}, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
Msg: "identity -1 out of range"}},
{"identity upper", &hst.Config{Identity: 10000}, &hst.AppError{Step: "validate configuration", Err: hst.ErrIdentityBounds,
Msg: "identity 10000 out of range"}},
{"container", &hst.Config{}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull, {"container", &hst.Config{}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,
Msg: "configuration missing container state"}}, Msg: "configuration missing container state"}},
{"home", &hst.Config{Container: &hst.ContainerConfig{}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull, {"home", &hst.Config{Container: &hst.ContainerConfig{}}, &hst.AppError{Step: "validate configuration", Err: hst.ErrConfigNull,

View File

@ -79,11 +79,6 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
k.ct = ct k.ct = ct
} }
// this is checked again in hsu
if config.Identity < hst.IdentityMin || config.Identity > hst.IdentityMax {
return newWithMessage(fmt.Sprintf("identity %d out of range", config.Identity))
}
kp.supp = make([]string, len(config.Groups)) kp.supp = make([]string, len(config.Groups))
for i, name := range config.Groups { for i, name := range config.Groups {
if gid, err := k.lookupGroupId(name); err != nil { if gid, err := k.lookupGroupId(name); err != nil {
@ -98,7 +93,7 @@ func (k *outcome) finalise(ctx context.Context, msg container.Msg, id *state.ID,
} }
} }
// validation complete at this point // early validation complete at this point
s := outcomeState{ s := outcomeState{
ID: id, ID: id,
Identity: config.Identity, Identity: config.Identity,