Skip to content

fix: panics when private field is validated #1423

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

ykalchevskiy
Copy link

Fixes Or Enhances

dive, omitnil and time-related validations panic by themselves.
panic inside panic happens for most of the checks in case of bad type.

(reflect.Value).Interface() can't be used if a field is private. getValue must be used instead.
In case of casting to string, fmt is smart enough by itself.
In case of getting type with %T, (reflect.Value).Type() can be safely used.

Without these changes tests fail with this error:

panic: reflect.Value.Interface: cannot return value obtained from unexported field or method [recovered]
        panic: reflect.Value.Interface: cannot return value obtained from unexported field or method

goroutine 22 [running]:
testing.tRunner.func1.2({0x10137e740, 0x101416580})
        /Users/yan/.go/src/testing/testing.go:1734 +0x1ac
testing.tRunner.func1()
        /Users/yan/.go/src/testing/testing.go:1737 +0x334
panic({0x10137e740?, 0x101416580?})
        /Users/yan/.go/src/runtime/panic.go:792 +0x124
reflect.valueInterface({0x10137e740?, 0x140002183a0?, 0x10141c850?}, 0xa0?)
        /Users/yan/.go/src/reflect/value.go:1495 +0xc8
reflect.Value.Interface(...)
        /Users/yan/.go/src/reflect/value.go:1484
github.com/go-playground/validator/v10.(*validate).traverseField(0x140001805a0, {0x10141a610, 0x1016cd0a0}, {0x1013ba060?, 0x1400008f550?, 0x17?}, {0x1013a7500?, 0x1400008f550?, 0x10137e980?}, {0x14000190340, ...}, ...)
        /Users/yan/projects/validator/validator.go:315 +0x222c
github.com/go-playground/validator/v10.(*validate).validateStruct(0x140001805a0, {0x10141a610, 0x1016cd0a0}, {0x101377bc0?, 0x1400008f550?, 0x101?}, {0x1013ba060?, 0x1400008f550?, 0x10137e980?}, {0x10141fd28, ...}, ...)
        /Users/yan/projects/validator/validator.go:72 +0x50c
github.com/go-playground/validator/v10.(*Validate).StructCtx(0x140000d03f0, {0x10141a610, 0x1016cd0a0}, {0x101377bc0, 0x1400008f550})
        /Users/yan/projects/validator/validator_instance.go:372 +0x324
github.com/go-playground/validator/v10.(*Validate).Struct(...)
        /Users/yan/projects/validator/validator_instance.go:346
github.com/go-playground/validator/v10.TestPrivateFieldsStruct(0x14000082fc0)
        /Users/yan/projects/validator/validator_test.go:14181 +0x368
testing.tRunner(0x14000082fc0, 0x101413400)
        /Users/yan/.go/src/testing/testing.go:1792 +0xe4
created by testing.(*T).Run in goroutine 1
        /Users/yan/.go/src/testing/testing.go:1851 +0x374
FAIL    github.com/go-playground/validator/v10  1.197s

Make sure that you've checked the boxes below before you submit PR:

  • Tests exist or have been written that cover this particular change.

@go-playground/validator-maintainers

@coveralls
Copy link

coveralls commented Apr 30, 2025

Coverage Status

coverage: 73.661% (+0.006%) from 73.655%
when pulling a230cca on ykalchevskiy:master
into 5b31512 on go-playground:master.

@ykalchevskiy ykalchevskiy marked this pull request as ready for review April 30, 2025 21:03
@ykalchevskiy ykalchevskiy requested a review from a team as a code owner April 30, 2025 21:03
@ykalchevskiy ykalchevskiy marked this pull request as draft April 30, 2025 21:05
@ykalchevskiy ykalchevskiy marked this pull request as ready for review April 30, 2025 21:06
@ykalchevskiy
Copy link
Author

@deankarn , @nodivbyzero , can you please take a look?

@nodivbyzero
Copy link
Contributor

Hello,

What issue does your PR address?
Based on the provided panic call stack, could you share a specific example that triggers this panic?

@ykalchevskiy
Copy link
Author

Hi @nodivbyzero ,

Here you go https://go.dev/play/p/D5c3QKQlnWt
The first and second should simply work.
The 3rd should still panic, but because of the bad type.
I've already added tests for these cases.

There are other cases, basically, (reflect.Value).Interface() is not safe to use with private fields. I've changed all the usages. getValue would just work everywhere, but in some cases there are easier ways, as I've explained in the PR's description.

I'll just keep it for myself. util.go#299
`// return regex.MatchString(fmt.Sprintf("%s", fl.Field())) // should be enoungh, add tests to check separately`
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.

3 participants