From 0bde96034c4659974aa8ec18b9fd6bc424e05583 Mon Sep 17 00:00:00 2001 From: Valentino Saputra Date: Fri, 7 Aug 2026 11:50:49 +0700 Subject: [PATCH] fix: reject unknown configuration fields --- internal/config/config_test.go | 18 ++++++++++++++++++ internal/config/load.go | 12 +++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/internal/config/config_test.go b/internal/config/config_test.go index ccbb483..4e6c256 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -63,6 +63,24 @@ func TestLoadUnknownSchemaVersion(t *testing.T) { } } +func TestLoadRejectsUnknownFields(t *testing.T) { + content := `{"version":1,"default":{"baseBranch":"main"}}` + f, err := os.CreateTemp("", "taskcapsule-*.json") + if err != nil { + t.Fatal(err) + } + defer os.Remove(f.Name()) + if _, err := f.Write([]byte(content)); err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + if _, err := Load(f.Name()); err == nil { + t.Fatal("expected unknown configuration field to be rejected") + } +} + func TestLoadDuplicateService(t *testing.T) { content := `{ "version": 1, diff --git a/internal/config/load.go b/internal/config/load.go index 78ffac0..5e8cc8b 100644 --- a/internal/config/load.go +++ b/internal/config/load.go @@ -1,8 +1,10 @@ package config import ( + "bytes" "encoding/json" "fmt" + "io" "os" ) @@ -13,7 +15,15 @@ func Load(path string) (*Config, error) { } var cfg Config - if err := json.Unmarshal(data, &cfg); err != nil { + decoder := json.NewDecoder(bytes.NewReader(data)) + decoder.DisallowUnknownFields() + if err := decoder.Decode(&cfg); err != nil { + return nil, fmt.Errorf("invalid configuration: %v", err) + } + if err := decoder.Decode(&struct{}{}); err != io.EOF { + if err == nil { + err = fmt.Errorf("multiple JSON values") + } return nil, fmt.Errorf("invalid configuration: %v", err) }