Skip to content
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

[Bug]: Nil pointer dereference in Arabic translations #1385

Closed
BlackSud0 opened this issue Feb 22, 2025 · 4 comments
Closed

[Bug]: Nil pointer dereference in Arabic translations #1385

BlackSud0 opened this issue Feb 22, 2025 · 4 comments
Labels

Comments

@BlackSud0
Copy link
Contributor

BlackSud0 commented Feb 22, 2025

What happened?

When using Arabic translations with the validator, a nil pointer dereference occurs in the translator. Line 177 (ar.go:177) C method during a struct validation especially (min or max) tags.

Error Stack Trace

runtime error: invalid memory address or nil pointer dereference
goroutine 16 [running]:
github.com/go-playground/universal-translator.(translator).C(0xc0004c0870, {0xc18a20, 0x11434d0}, 0x4020000000000000, 0x0, {0x1165f80, 0x1})
/home/blacksudo/go/pkg/mod/github.com/go-playground/universal-translator@v0.18.1/translator.go:335 +0xdf
github.com/go-playground/validator/v10/translations/ar.RegisterDefaultTranslations.func4({0x115a980, 0xc0004c0870}, {0x1150cb0, 0xc00044e510})

go/pkg/mod/github.com/go-playground/validator/v10@v10.15.4/translations/ar/ar.go:177 +0x3ac

Environment & Version

  • Go version: 1.24
  • echo web framework v4.13.3
  • validator version: v10.15.4
  • universal-translator version: v0.18.1

Steps to Reproduce

  1. Initialize a validator with Arabic language support
  2. Register default Arabic translations
  3. Attempt to validate a struct with validation tags eg. (min, max)

Example Code

Login struct {
		Username string `json:"username" validate:"required,min=3,max=50"`
		Password string `json:"password" validate:"required,min=8"`
	}
@BlackSud0 BlackSud0 added the bug label Feb 22, 2025
@nodivbyzero
Copy link
Contributor

I can confirm that the Arabic translation caused panic.

I was able to resolve it by adding ut.AddCardinal("len-string-character", "{0} حرف", locales.PluralRuleTwo, false); to the Arabic translation file, but I'm unsure if the translation is accurate.

Image

@BlackSud0 can you verify it?

@BlackSud0
Copy link
Contributor Author

BlackSud0 commented Feb 23, 2025

Hi @nodivbyzero

My Solution to Arabic Translation Panic

The panic was caused by using the cardinal number system (ut.AddCardinal() and ut.C()) which wasn't properly initialized for Arabic translations. Here's how to fix it by using simple singular/plural translations instead:

The Fix

Replace the cardinal number system with simple singular/plural translations. Here's an example for the "len" validation tag:

// Before (problematic code)
customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("len-string", "يجب أن يكون طول {0} مساويا ل {1}", false); err != nil {
return
}
if err = ut.AddCardinal("len-string-character", "{0} حرف", locales.PluralRuleOne, false); err != nil {
return
}
if err = ut.AddCardinal("len-string-character", "{0} أحرف", locales.PluralRuleOther, false); err != nil {
return
}
// ... more AddCardinal calls ...
}


// After (fixed code)
customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("len-string", "يجب أن يكون طول {0} مساويا ل {1}", false); err != nil {
return
}
if err = ut.Add("len-string-character-one", "{0} حرف", false); err != nil {
return
}
if err = ut.Add("len-string-character-other", "{0} أحرف", false); err != nil {
return
}
// ... more simple Add calls ...
}

And in the translation function:

// Before (problematic code)
c, err = ut.C("len-string-character", f64, digits, ut.FmtNumber(f64, digits))

// After (fixed code)
if f64 == 1 {
c, err = ut.T("len-string-character-one", ut.FmtNumber(f64, digits))
} else {
c, err = ut.T("len-string-character-other", ut.FmtNumber(f64, digits))
}

Why This Works

  1. Avoids the nil pointer dereference by not using the cardinal number system
  2. Still maintains proper Arabic plural forms using simple singular/plural logic
  3. More reliable as it doesn't depend on complex plural rules initialization

Implementation Notes

  • Apply this pattern to all validation tags that use numbers (len, min, max, lt, lte, etc.)
  • Use -one suffix for singular form and -other suffix for plural form
  • Keep the same Arabic translations, just change how they're registered and accessed

The complete solution can be found in this gist ar.go.

@BlackSud0
Copy link
Contributor Author

Testing the implementation

Code:
Image

Result:
Image

@nodivbyzero
Copy link
Contributor

Hey @BlackSud0

Could you please create a new PR with the changes you’re suggesting?

nodivbyzero pushed a commit that referenced this issue Mar 5, 2025
## Fixes or Enhances
**Make sure that you've checked the boxes below before you submit PR:**
- [x] Tests exist or have been written that cover this particular
change.

### Description
This PR fixes [Bug #1385]: Nil pointer dereference in Arabic
translations and adds comprehensive Arabic (ar) translations for the
go-playground/validator package. The implementation provides Arabic
error messages for all common validation tags, making the validator more
valuable to Arabic-speaking developers.

### Features
- Fixes nil pointer dereference bug in Arabic translations
- Complete Arabic translations for all standard validation tags
- Comprehensive test suite to verify translation accuracy
- Follows the same pattern as existing language translations
- Properly handles Arabic text direction and grammar

### Implementation Details
- The implementation follows the established pattern in the validator
package:
- Registers translations for each validation tag
- Provides appropriate Arabic phrasing for validation errors
- Handles parameter substitution in error messages
- Includes tests for all validation scenarios

### Testing
- A comprehensive test suite is included that verifies:
- Basic validations (required, email, etc.)
- Length validations (min, max, len)
- Comparison validations (lt, lte, gt, gte, eq, ne)
- Field comparison validations (eqfield, nefield, gtefield)
- Content validations (alpha, alphanum, contains, etc.)
- Special validations (oneof, datetime)
- All tests pass and confirm that the translations are correctly
applied.

### Usage Example
```go
validate := validator.New()
arabic := ar.New()
uni := ut.New(arabic, arabic)
trans, _ := uni.GetTranslator("ar")

// Register Arabic translations
ar.RegisterDefaultTranslations(validate, trans)

// Now validation errors will be in Arabic
err := validate.Struct(myStruct)
if err != nil {
    errs := err.(validator.ValidationErrors)
    for _, e := range errs {
        // This will be in Arabic
        fmt.Println(e.Translate(trans))
    }
}
```

@nodivbyzero
@go-playground/validator-maintainers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants