Skip to content

Treat out-of-range slice indexes in struct paths as missing - #352

Merged
inhere merged 1 commit into
gookit:masterfrom
youdie006:struct-slice-index-bounds
Oct 29, 2026
Merged

inhere merged 1 commit into
gookit:masterfrom
youdie006:struct-slice-index-bounds

Conversation

@youdie006

Copy link
Copy Markdown
Contributor

#351 made the map arm of StructData's path walker treat a missing entry as missing. The slice/array arm of the same loops (tryGetRV and Set) still calls fv.Index(index) without a bounds check, so a path into an empty slice, or a negative index, panics. That is also reachable from a struct tag alone:

                                              before                                   after
map source, Items.0.Name required, empty      required error                           required error
struct source, Items.0.Name required, empty   PANIC: reflect: slice index out of range  required error
struct tag requiredIf:Items.0.Name, empty     PANIC: reflect: slice index out of range  valid
struct source, Get("Items.-1.Name")           PANIC: reflect: slice index out of range  nil, exist=false

tryGetRV now reports an out-of-range index as missing, the same way the map source does. Set returns ErrNoField when an index that resolved earlier no longer exists, like the "entry removed before write" case #351 added for maps. Only inputs that used to panic change. A non-numeric segment still resolves to element 0 as before. I added a CHANGELOG line next to #351's.

go test ./... (under UTC and Asia/Seoul), go vet ./... and gofmt pass on Go 1.26.3. golangci-lint reports the same findings as on master.

Written with AI assistance (Claude); I have reviewed the change.

gookit#351 made the map arm of StructData's path walker treat a missing entry
as missing. The slice/array arm still called fv.Index without a bounds
check, so Items.0.Name on an empty slice, or a negative index, panicked
in TryGet, Get and Set, including through a requiredIf tag.
@inhere
inhere merged commit 111eb23 into gookit:master Oct 29, 2026
10 of 11 checks passed
inhere added a commit that referenced this pull request Oct 29, 2026
tryGetRV treats a negative index as missing since #352, and Set keeps the same
bound check now for its own walk. Set cannot reach that branch today: HasField
rejects any path the field walker did not register, and a negative index is never
registered, so the guard keeps the two walkers in sync if that gate ever widens.

Tests: Set("Items.-1.Name") and Set("Fixed.-1.Name") return ErrNoField and leave
the element untouched.
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