diff --git a/stores/ini/store.go b/stores/ini/store.go index 350142d85..83605000e 100644 --- a/stores/ini/store.go +++ b/stores/ini/store.go @@ -24,7 +24,8 @@ func NewStore(c *config.INIStoreConfig) *Store { } func (store Store) encodeTree(branches sops.TreeBranches) ([]byte, error) { - iniFile := ini.Empty() + iniFile := ini.Empty(ini.LoadOptions{AllowNonUniqueSections: true}) + iniFile.DeleteSection(ini.DefaultSection) for _, branch := range branches { for _, item := range branch { if _, ok := item.Key.(sops.Comment); ok { @@ -95,7 +96,7 @@ func (store Store) iniFromTreeBranches(branches sops.TreeBranches) ([]byte, erro } func (store Store) treeBranchesFromIni(in []byte) (sops.TreeBranches, error) { - iniFile, err := ini.Load(in) + iniFile, err := ini.LoadSources(ini.LoadOptions{AllowNonUniqueSections: true}, in) if err != nil { return nil, err } @@ -143,7 +144,7 @@ func (store Store) treeItemFromSection(section *ini.Section) (sops.TreeItem, err // LoadEncryptedFile loads encrypted INI file's bytes onto a sops.Tree runtime object func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) { - iniFileOuter, err := ini.Load(in) + iniFileOuter, err := ini.LoadSources(ini.LoadOptions{AllowNonUniqueSections: true}, in) if err != nil { return sops.Tree{}, err } diff --git a/stores/ini/store_test.go b/stores/ini/store_test.go index 3e833b54c..b1aff6cf9 100644 --- a/stores/ini/store_test.go +++ b/stores/ini/store_test.go @@ -3,8 +3,8 @@ package ini import ( "testing" - "github.com/stretchr/testify/assert" "github.com/getsops/sops/v3" + "github.com/stretchr/testify/assert" ) func TestDecodeIni(t *testing.T) { @@ -127,6 +127,55 @@ func TestEncodeIniWithEscaping(t *testing.T) { assert.Equal(t, expected, branches) } +func TestEncodeIniWithDuplicateSections(t *testing.T) { + branches := sops.TreeBranches{ + sops.TreeBranch{ + sops.TreeItem{ + Key: "DEFAULT", + Value: interface{}(sops.TreeBranch(nil)), + }, + sops.TreeItem{ + Key: "foo", + Value: sops.TreeBranch{ + sops.TreeItem{ + Key: "foo", + Value: "bar", + }, + sops.TreeItem{ + Key: "baz", + Value: "3.0", + }, + sops.TreeItem{ + Key: "qux", + Value: "false", + }, + }, + }, + sops.TreeItem{ + Key: "foo", + Value: sops.TreeBranch{ + sops.TreeItem{ + Key: "foo", + Value: "bar", + }, + sops.TreeItem{ + Key: "baz", + Value: "3.0", + }, + sops.TreeItem{ + Key: "qux", + Value: "false", + }, + }, + }, + }, + } + out, err := Store{}.iniFromTreeBranches(branches) + assert.Nil(t, err) + expected, _ := Store{}.treeBranchesFromIni(out) + assert.Equal(t, expected, branches) +} + func TestUnmarshalMetadataFromNonSOPSFile(t *testing.T) { data := []byte(`hello=2`) store := Store{}