Repository: go-playground/validator (go)

Issue:
country_code alias panics on invalid iso3166_1_alpha2 and iso3166_1_alpha3
- [x] I have looked at the documentation [here](https://pkg.go.dev/github.com/go-playground/validator/v10#section-documentation) first?
- [x] I have looked at the examples provided that may showcase my question [here](/_examples)?

### Package version eg. v9, v10: v10

### Issue, Question or Enhancement:
In #615 the `country_code` alias is introduced which calls 3 validators `iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric`. 

If you use the `country_code` to validate a string which has an invalid value you will receive a panic with the message `Bad field type string`. This is caused by the `iso3166_1_alpha_numeric` validation here https://github.com/go-playground/validator/blob/ce34f361cca51e25715399ab801c5e1c01d02d89/baked_in.go#L2359 .

### Code sample, to showcase or reproduce:

This is a test I wrote to confirm the issue, you will receive a panic on `"1"`.

```go
func TestCountryCodeValidation(t *testing.T) {
	tests := []struct {
		value    interface{}
		expected bool
	}{
		{248, true},
		{0, false},
		{1, false},
		{"NO", true},
		{"1", false},
		{"0", false},
	}

	validate := New()

	for i, test := range tests {

		errs := validate.Var(test.value, "country_code")

		if test.expected {
			if !IsEqual(errs, nil) {
				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
			}
		} else {
			if IsEqual(errs, nil) {
				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
			}
		}
	}
}
```

### Expected behaviour

I would expect that the alias should not panic here but instead return false.

### Fix

I was planning to make a PR for this issue but the fix may require some big changes and I thought it may be good to discuss them before making any kind of changes.

A simple solution would be to catch any panic for an alias, this makes sense for `country_code` which can have multiple valid types.

An easier solution would be to just remove the panic in the `iso3166_1_alpha_numeric` function but then it would differ from the rest of the package. That raises another question of whether the package should be throwing panics in the first place?

I am not sure what the best way to solve this would be and would look for input from maintainers or perhaps @krhubert who added this functionality. 

Pull request:
Fixed country_code validation to properly handle strings
## Fixes Or Enhances

This PR fixes #860. I have modified existing tests and also added a test for `country_code` to ensure that my modifications have fixed the issue and improve upon the validation.

- [x] Tests exist or have been written that cover this particular change.

@go-playground/validator-maintainers

Patch:
diff --git a/baked_in.go b/baked_in.go
index f5fd239..51a224c 100644
--- a/baked_in.go
+++ b/baked_in.go
@@ -2351,6 +2351,12 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
 
 	var code int
 	switch field.Kind() {
+	case reflect.String:
+		i, err := strconv.Atoi(field.String())
+		if err != nil {
+			return false
+		}
+		code = i % 1000
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		code = int(field.Int() % 1000)
 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:


Test patch:
diff --git a/validator_test.go b/validator_test.go
index f694203..5064139 100644
--- a/validator_test.go
+++ b/validator_test.go
@@ -11053,12 +11053,15 @@ func TestIsIso3166Alpha3Validation(t *testing.T) {
 
 func TestIsIso3166AlphaNumericValidation(t *testing.T) {
 	tests := []struct {
-		value    int
+		value    interface{}
 		expected bool
 	}{
 		{248, true},
+		{"248", true},
 		{0, false},
 		{1, false},
+		{"1", false},
+		{"invalid_int", false},
 	}
 
 	validate := New()
@@ -11079,8 +11082,41 @@ func TestIsIso3166AlphaNumericValidation(t *testing.T) {
 	}
 
 	PanicMatches(t, func() {
-		_ = validate.Var("1", "iso3166_1_alpha_numeric")
-	}, "Bad field type string")
+		_ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric")
+	}, "Bad field type []string")
+}
+
+func TestCountryCodeValidation(t *testing.T) {
+	tests := []struct {
+		value    interface{}
+		expected bool
+	}{
+		{248, true},
+		{0, false},
+		{1, false},
+		{"POL", true},
+		{"NO", true},
+		{"248", true},
+		{"1", false},
+		{"0", false},
+	}
+
+	validate := New()
+
+	for i, test := range tests {
+
+		errs := validate.Var(test.value, "country_code")
+
+		if test.expected {
+			if !IsEqual(errs, nil) {
+				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
+			}
+		} else {
+			if IsEqual(errs, nil) {
+				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
+			}
+		}
+	}
 }
 
 func TestIsIso4217Validation(t *testing.T) {