[Bug]: `validate: omitempty,numeric, gt=0` is checking for string len. Instead of strconv.Atoi(param.Field) > p
What happened?
Hi if you use the following tag:
type ABC struct {
intValue string validate: omitempty, numeric, gt=0
}
The validation run on this are as follows:
- omitempty
- numeric.
- gt=0 => this should ideally be run on the numeric equivalent of the intValue. But current implementation is checkin for the length of the Rune. Here is the code which is executed:
case reflect.String:
p := asInt(param)
return int64(utf8.RuneCountInString(field.String())) > p
Expected validation should be:
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asIntFromType(field.Type(), param)
return field.Int() > p
Version
v10.26.0
Example Code
package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
// Port struct with validation tags
type Port struct {
PortNum string `json:"port" validate:"omitempty,numeric,gt=0,lt=65536"`
}
func main() {
// Initialize validator
validate := validator.New()
// Test a few port values
testPorts := []string{
"8080", // Valid port
"", // Empty (valid due to omitempty)
"0", // Invalid - zero
"65536", // Invalid - too large
"abc", // Invalid - not numeric
}
fmt.Println("Port Validation Results:")
fmt.Println("=======================")
for _, portValue := range testPorts {
port := Port{PortNum: portValue}
err := validate.Struct(port)
if err != nil {
fmt.Printf("Port %q: INVALID - %v\n", portValue, err)
} else {
fmt.Printf("Port %q: VALID\n", portValue)
}
}
}
It's not a bug.
The validation behavior you're seeing is due to the fact that rules are applied based on the actual type defined in your struct, not the type implied by the validation tag.
Since intValue is declared as a string, the gt=0 rule applies to the length of the string - not its numeric value.
Even though you've added numeric in the tag, that only checks if the string contains numeric characters; it doesn't convert the field to a numeric type for the gt rule.
One option in your case could be using the isPort validator, if that fits your use case.
Hope this helps!