Skip to content

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

Merged
inhere merged 1 commit into
gookit:masterfrom
dualfroz:dualfroz/negative-index-panic
Sep 7, 2026
Merged

inhere merged 1 commit into
gookit:masterfrom
dualfroz:dualfroz/negative-index-panic

Conversation

@dualfroz

@dualfroz dualfroz commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Problem

Looking up a key whose path contains a negative array index panics instead of
reporting "not found":

c.LoadData(map[string]any{"arr": []any{"a", "b", "c"}})

c.GetValue("arr.-1") // panic: runtime error: index out of range [-1]
c.Exists("arr.-1")   // panic: runtime error: index out of range [-1]

Key paths frequently come from user input or configuration, so a stray
negative index crashes the caller.

Root cause

read.go, in both GetValue and Exists, the slice cases parse the path
segment with strconv.Atoi and validate only the upper bound:

case []any: // is array(load from file)
	i, err := strconv.Atoi(k)
	if err != nil || len(typeData) <= i { // no lower-bound check
		...
		return
	}
	item = typeData[i] // typeData[-1] panics

strconv.Atoi("-1") succeeds with i == -1, which passes len(typeData) <= i
(3 <= -1 is false), so typeData[-1] is evaluated and panics. This affects
the []int, []string and []any cases in both functions (six sites).

Fix

Add a lower-bound check (i < 0) to every slice-index guard so a negative
index is treated as not found:

if err != nil || i < 0 || len(typeData) <= i {   // GetValue
if err != nil || i < 0 || i >= len(typeData) {    // Exists

Test

Added TestConfig_GetValue_negativeIndex in read_test.go, asserting that both
GetValue("arr.-1") and Exists("arr.-1") do not panic and report not found.

  • Gate: go test ./... -> ok (PASS, exit 0, all packages)
  • go vet ./... -> exit 0
  • go build ./... -> exit 0
  • gofmt -l read.go read_test.go -> clean

Counterfactual: reverting read.go makes the test fail with
Panic value: runtime.boundsError{x:-1, y:3, ...}.

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.
@dualfroz
dualfroz force-pushed the dualfroz/negative-index-panic branch from 4ebbe6d to 8a81b3b Compare September 5, 2026 22:44
@inhere
inhere merged commit c3e2b83 into gookit:master Sep 7, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants