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
Panic Bad field type *int64, when using required_if and omitempty at the same time #907
Comments
This is happening because validator is trying to run type SampleWithPointer struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity,omitempty" validate:"required_if=Type special,omitempty,gte=2"`
} Adding |
This workaround seems to be fixing the issue, but we should probably fix this, so it doesn't panic. |
@zemzale I think adding this code block fixes the validation. But we need to add this block to every validation that panics with nil values. func isGte(fl FieldLevel) bool {
field := fl.Field()
param := fl.Param()
switch field.Kind() {
case reflect.Pointer:
if field.IsNil() {
return false
}
field = field.Elem()
case reflect.String:
... Line 1815 in c7e0172
|
I don't think the omitempty tag is relevant in this case. It's actually the required_if tags that set the pointer to nil if fields aren't assigned a value during struct initialization. package main
import (
"log"
"github.com/go-playground/validator/v10"
)
type SamplPointerWithoutRequiredTag struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity" validate:"gte=2"`
}
type SamplPointerWithRequiredTag struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity" validate:"required_if=Type notspecial,eq=3"`
}
func main() {
_type := "special"
var q int64 = 3
s1 := &SamplPointerWithoutRequiredTag{Type: _type, Quantity: &q}
s2 := &SamplPointerWithoutRequiredTag{Type: _type}
s3 := &SamplPointerWithRequiredTag{Type: _type, Quantity: &q}
s4 := &SamplPointerWithRequiredTag{Type: _type}
validate := validator.New()
if err := validate.Struct(s1); err != nil {
log.Printf("Validate SamplPointerWithoutRequiredTag and given input for field, %v", err)
}
if err := validate.Struct(s2); err != nil {
log.Printf("Validate SamplPointerWithRequiredTag and without input for field, %v", err)
}
if err := validate.Struct(s3); err != nil {
log.Printf("Validate SamplPointerWithRequiredTag and given input for field, %v", err)
}
if err := validate.Struct(s4); err != nil {
log.Printf("Validate SamplPointerWithRequiredTag and without input for field, %v", err)
}
} Stack Trace:
|
Sorry for the delay in responding, stealing some time before the kids are up to comment. I don't believe there is an issue here and that the validations defined is missing accounting for the possibility of the nil value as mentioned by @berabulut. Adding of the using this below example, lets thinking about it step by step: type SampleWithPointer struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity,omitempty" validate:"required_if=Type special,gte=2"`
}
or to put this into pure Go code this is what's being done: type SampleWithPointer struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity,omitempty" validate:"required_if=Type special,gte=2"`
}
swp := &SampleWithPointer{Type: "notspecial"}
if swp.Type == "special" && swp.Quantity == nil {
fmt.Println("returning error required_if")
} else if swp.Quantity >= 2 { // doesn't even compile because pointer and integer cannot be compared in this way and why the validation panics as defined
fmt.Println("returning error gte")
} What's really desired is this, which is equivalent to type SampleWithPointer struct {
Type string `json:"type" validate:"required"`
Quantity *int64 `json:"quantity,omitempty" validate:"required_if=Type special,omitempty,gte=2"`
}
swp := &SampleWithPointer{Type: "notspecial"}
if swp.Type == "special" && swp.Quantity == nil {
fmt.Println("returning error required_if")
} else if swp.Quantity != nil && *swp.Quantity >= 2 {
fmt.Println("returning error gte")
} else {
fmt.Println("all good, wasn't required and ok if not set")
} Now arguably maybe But for the time being making such a change would be breaking and cause all sorts of undefined behaviour. I understand that this may seem suboptimal and that the design of the validation functions & signatures may seem inadequate but also please try to remember a lot has been added to this library over the years and things were designed before there were cross-field functions like I have been compiling a list with such things for the next major version to improve upon, given how widely used this current version is I'm waiting until there are a significant amount of these changes to warrant such a major version bump. |
Package version eg. v9, v10:
v10.10.0
Issue, Question or Enhancement:
When validating an int64 pointer with
required_if
andomitempty
at the same time, callingStruct()
leads to panic.Using
omitempty
merely is ok. Validating an int64 instead of an int64 pointer is ok.Similar to: Panic Bad field type *string, when using required_without and omitempty at the same time #654
Code sample, to showcase or reproduce:
stack trace:
The text was updated successfully, but these errors were encountered: