fix(read): prevent panic on negative slice index in a key path

GetValue and Exists validated only the upper bound of a numeric key-path
segment, so a negative index such as "arr.-1" passed the check and indexed
the slice with -1, causing an index-out-of-range panic. Add a lower-bound
check (i < 0) to the []int, []string and []any cases in both functions.
This commit is contained in:
dualfroz committed 2026-09-06 00:44:38 +02:00
1 parent d54d79012b
commit cb6b9f9456
3 files changed
+29 -8

No files matched your search

+6 -6
View File
@@ -63,19 +63,19 @@ func (c *Config) Exists(key string, findByPath ...bool) (ok bool) {
}
case []int: // is array(is from Set)
i, err := strconv.Atoi(k)
if err != nil || i >= len(typeData) {
if err != nil || i < 0 || i >= len(typeData) {
return false
}
item = typeData[i]
case []string: // is array(is from Set)
i, err := strconv.Atoi(k)
if err != nil || i >= len(typeData) {
if err != nil || i < 0 || i >= len(typeData) {
return false
}
item = typeData[i]
case []any: // is array(load from file)
i, err := strconv.Atoi(k)
if err != nil || i >= len(typeData) {
if err != nil || i < 0 || i >= len(typeData) {
return false
}
item = typeData[i]
@@ -214,7 +214,7 @@ func (c *Config) GetValue(key string, findByPath ...bool) (value any, ok bool) {
i, err := strconv.Atoi(k)
// check slice index
if err != nil || len(typeData) <= i {
if err != nil || i < 0 || len(typeData) <= i {
ok = false
c.addError(err)
return
@@ -223,7 +223,7 @@ func (c *Config) GetValue(key string, findByPath ...bool) (value any, ok bool) {
item = typeData[i]
case []string: // is array(is from Set)
i, err := strconv.Atoi(k)
if err != nil || len(typeData) <= i {
if err != nil || i < 0 || len(typeData) <= i {
ok = false
c.addError(err)
return
@@ -232,7 +232,7 @@ func (c *Config) GetValue(key string, findByPath ...bool) (value any, ok bool) {
item = typeData[i]
case []any: // is array(load from file)
i, err := strconv.Atoi(k)
if err != nil || len(typeData) <= i {
if err != nil || i < 0 || len(typeData) <= i {
ok = false
c.addError(err)
return
+21
View File
@@ -499,3 +499,24 @@ func TestConfig_Duration_getter(t *testing.T) {
is.Eq(7*time.Second, c.Duration("missing", 7*time.Second))
is.Eq(time.Duration(0), c.Duration("missing"))
}
func TestConfig_GetValue_negativeIndex(t *testing.T) {
is := assert.New(t)
c := New("test-neg")
err := c.LoadData(map[string]any{
"arr": []any{"a", "b", "c"},
})
is.NoErr(err)
// A negative slice index must not panic; it is simply not found.
is.NotPanics(func() {
v, ok := c.GetValue("arr.-1")
is.False(ok)
is.Nil(v)
})
is.NotPanics(func() {
is.False(c.Exists("arr.-1"))
})
}
+2 -2
View File
@@ -1,4 +1,4 @@
; exported at 2025-08-20 14:11:56
; exported at 2026-09-06 00:43:11
age = 123
baseKey = value
@@ -9,8 +9,8 @@ multiWords = hello world
name = app
[map1]
key = val
key1 = val1
key2 = val2
key = val