go-playground / validator

:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
MIT License
16.81k stars 1.32k forks source link

Nil pointer while translating min/gt in ru_RU locale #593

Open phpinfo opened 4 years ago

phpinfo commented 4 years ago

Package version eg. v8, v9:

github.com/go-playground/validator/v10 v10.2.0 github.com/go-playground/locales v0.13.0 github.com/go-playground/universal-translator v0.17.0

Issue, Question or Enhancement:

Trying to add validation with plurals in errors in ru_RU locale. Got nil pointer panic. What am I doing wrong?

Code sample, to showcase or reproduce:

This code leads to panic:

package main

import (
    "github.com/go-playground/locales/ru_RU"
    "github.com/go-playground/universal-translator"
    "github.com/go-playground/validator/v10"
    "github.com/go-playground/validator/v10/translations/ru"
    "log"
)

type S struct {
    Field string `validate:"gt=2"`
}

func main() {
    locale := ru_RU.New()
    uni := ut.New(locale, locale)
    trans, _ := uni.GetTranslator(locale.Locale())

    validate := validator.New()
    _ = ru.RegisterDefaultTranslations(validate, trans)

    a := &S{
        Field: "a",
    }

    err := validate.Struct(a)
    if err != nil {
        for _, e := range err.(validator.ValidationErrors) {
            log.Println(e.Translate(trans))
        }
    }
}

Panic:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x10c9cc2]

goroutine 1 [running]:
github.com/go-playground/universal-translator.(*translator).C(0xc0002440f0, 0x117da00, 0x11f04f0, 0x4000000000000000, 0x0, 0x12edcd2, 0x1, 0xc0002441e0, 0xc000252080, 0x1, ...)
    /Users/al.gromov/go/pkg/mod/github.com/go-playground/universal-translator@v0.17.0/translator.go:335 +0x112
github.com/go-playground/validator/v10/translations/ru.RegisterDefaultTranslations.func14(0x11f9c40, 0xc0002440f0, 0x11f6dc0, 0xc0000ca510, 0xc00024f708, 0x1190d01)
    /Users/al.gromov/go/pkg/mod/github.com/go-playground/validator/v10@v10.2.0/translations/ru/ru.go:648 +0x88c
github.com/go-playground/validator/v10.(*fieldError).Translate(0xc0000ca510, 0x11f9c40, 0xc0002440f0, 0x1174dc0, 0xc0001bfb20)
    /Users/al.gromov/go/pkg/mod/github.com/go-playground/validator/v10@v10.2.0/errors.go:271 +0xdc
main.main()
    /Users/al.gromov/projects/youla-store/cmd/youla-store/main.go:30 +0x206
exit status 2

The same code in en_GB locale works fine:

package main

import (
    "github.com/go-playground/locales/en_GB"
    "github.com/go-playground/universal-translator"
    "github.com/go-playground/validator/v10"
    "github.com/go-playground/validator/v10/translations/en"
    "log"
)

type S struct {
    Field string `validate:"gt=2"`
}

func main() {
    locale := en_GB.New()
    uni := ut.New(locale, locale)
    trans, _ := uni.GetTranslator(locale.Locale())

    validate := validator.New()
    _ = en.RegisterDefaultTranslations(validate, trans)

    a := &S{
        Field: "a",
    }

    err := validate.Struct(a)
    if err != nil {
        for _, e := range err.(validator.ValidationErrors) {
            log.Println(e.Translate(trans))
        }
    }
}

Result:

2020/03/20 10:27:43 Field must be greater than 2 characters in length
v0xpopuli commented 4 years ago

Face the same problem. Also when use FR locale, it translate to russian.

r := fr.New()
uni := ut.New(r, r)
trans,  _ := uni.GetTranslator(r.Locale())
ru_def.RegisterDefaultTranslations(v.validator, trans)

errs := v.validator.Struct(s).(validator.ValidationErrors)

fmt.Println(errs.Translate(trans))
return errs

Output: map[CreateUserRequest.Email:Email должен быть email адресом CreateUserRequest.PhoneNumber:PhoneNumber должен быть длиной в 12 символы]

deankarn commented 4 years ago

Thanks for reporting, will try to take a look this week, first time of heard of this issue.

phpinfo commented 4 years ago

Thank you!

bl0ck3man commented 4 years ago

same situation with ru locale

dmitrymatviets commented 4 years ago

@deankarn Could you check this issue up, please?

renato0307 commented 2 years ago

Hi,

I've tried to check the issue but could not replicate.

Tested it with en_GB, pt_PT, fr_FR and ru_RU.

The output of go test ./... -v is:

=== RUN   Test593
2022/01/14 22:33:08 Field deve conter mais de 2 caracteres
2022/01/14 22:33:08 Field must be greater than 2 characters in length
2022/01/14 22:33:08 Field должен быть длиннее 2 символов
2022/01/14 22:33:08 Field doit avoir une taille supérieur à 2 caractères
--- PASS: Test593 (0.00s)
PASS
ok      validator593    0.391s

Check code below.

main_test.go:

package main

import (
    "log"
    "testing"

    "github.com/go-playground/locales"
    "github.com/go-playground/locales/en_GB"
    "github.com/go-playground/locales/fr_FR"
    "github.com/go-playground/locales/pt_PT"
    "github.com/go-playground/locales/ru_RU"
    ut "github.com/go-playground/universal-translator"
    "github.com/go-playground/validator/v10"
    "github.com/go-playground/validator/v10/translations/en"
    "github.com/go-playground/validator/v10/translations/fr"
    "github.com/go-playground/validator/v10/translations/pt"
    "github.com/go-playground/validator/v10/translations/ru"
)

type S struct {
    Field string `validate:"gt=2"`
}

func Test593(t *testing.T) {

    testCases := []struct {
        Locale locales.Translator
        RT     func(v *validator.Validate, trans ut.Translator) (err error)
    }{
        {
            Locale: pt_PT.New(),
            RT:     pt.RegisterDefaultTranslations,
        },
        {
            Locale: en_GB.New(),
            RT:     en.RegisterDefaultTranslations,
        },
        {
            Locale: ru_RU.New(),
            RT:     ru.RegisterDefaultTranslations,
        },
        {
            Locale: fr_FR.New(),
            RT:     fr.RegisterDefaultTranslations,
        },
    }

    for _, tc := range testCases {
        locale := tc.Locale
        uni := ut.New(locale, locale)
        trans, _ := uni.GetTranslator(locale.Locale())

        validate := validator.New()
        _ = tc.RT(validate, trans)

        a := &S{
            Field: "a",
        }

        err := validate.Struct(a)
        if err != nil {
            for _, e := range err.(validator.ValidationErrors) {
                log.Println(e.Translate(trans))
            }
        }
    }
}

go.mod:

module validator593

go 1.17

require (
    github.com/go-playground/locales v0.14.0
    github.com/go-playground/universal-translator v0.18.0
    github.com/go-playground/validator/v10 v10.10.0
)

require (
    github.com/leodido/go-urn v1.2.1 // indirect
    golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
    golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
    golang.org/x/text v0.3.7 // indirect
)
sdillen commented 2 years ago

This was fixed in https://github.com/go-playground/validator/pull/814