-
Notifications
You must be signed in to change notification settings - Fork 173
Description
Describe the bug
The function posflag.FlagVal uses a type switch to get a flag's value in the correct type, but then casts each signed integer to int64
and each unsigned integer to uint64
.
With the following configuration, this behavior will result in an unexpected error:
- Use
koanf.Conf.StrictMerge: true
to prevent the case where e.g. abool
overwrites anint
. - Load the initial config via another provider, e.g.
confmap
that sets anint
value. - Use the posflag provider to map an
int
flag to theint
config value viaposflag.ProviderWithFlag
. Useposflag.FlagVal
to get the value.
Even though the initial config uses int
and the flag is defined as an int
, loading the values via the posflag provider results in the following error when koanf tries to merge both values:
incorrect types at key , type int != int64
To Reproduce
package main
import (
"fmt"
"github.com/knadh/koanf/providers/confmap"
"github.com/knadh/koanf/providers/posflag"
"github.com/knadh/koanf/v2"
"github.com/spf13/pflag"
)
func main() {
k := koanf.NewWithConf(koanf.Conf{
Delim: ".",
// Setting it to false won't trigger the bug, but it would also allow
// overwriting a bool with an int, which I want to prevent.
StrictMerge: true,
})
// Making "1" an int64 also "fixes" the issue.
confmapProvider := confmap.Provider(map[string]any{"a": int(1)}, "")
if err := k.Load(confmapProvider, nil); err != nil {
panic(err)
}
// Output: 1 (int)
fmt.Printf("%v (%T)\n", k.Get("a"), k.Get("a"))
fs := pflag.NewFlagSet("", pflag.PanicOnError)
fs.Int("a-flag", 0, "")
if err := fs.Set("a-flag", "2"); err != nil {
panic(err)
}
flagNameToConfig := map[string]string{"a-flag": "a"}
posflagProvider := posflag.ProviderWithFlag(fs, ".", nil, func(f *pflag.Flag) (string, any) {
posflagVal := posflag.FlagVal(fs, f)
// Output: 2 (int64)
fmt.Printf("%v (%T)\n", posflagVal, posflagVal)
return flagNameToConfig[f.Name], posflagVal
})
if err := k.Load(posflagProvider, nil); err != nil {
// Results in error: incorrect types at key , type int != int64
panic(err)
}
}
Expected behavior
I expected that posflag.FlagVal
returns the value with the same type that the flag is defined with and therefore for no error to occur.
Making posflag.FlagVal
assign i
directly to val
instead of casting it to int64
/uint64
and then assigning it to val
fixes the issue; but I don't know if I'm missing the reason why the casts are there.
Please provide the following information):
- OS: linux
- Koanf Version v2.2.0