diff --git a/src/validators/country.py b/src/validators/country.py index f220c77f..1d2c6508 100644 --- a/src/validators/country.py +++ b/src/validators/country.py @@ -299,7 +299,8 @@ def country_code(value: str, /, *, iso_format: str = "auto", ignore_case: bool = if not value: return False - if not (1 < len(value) < 4): + # str.upper() would map e.g. dotless i and long s onto ASCII letters + if not (1 < len(value) < 4) or not value.isascii(): return False if iso_format == "auto" and (iso_format := _get_code_type(value)) == "invalid": @@ -349,7 +350,8 @@ def currency(value: str, /, *, skip_symbols: bool = True, ignore_case: bool = Fa if not skip_symbols and value in _currency_symbols: return True - if len(value) != 3: + # str.upper() would map e.g. dotless i and long s onto ASCII letters + if len(value) != 3 or not value.isascii(): return False return value.upper() in _currency_iso4217 if ignore_case else value in _currency_iso4217 diff --git a/tests/test_country.py b/tests/test_country.py index 1485d265..58507013 100644 --- a/tests/test_country.py +++ b/tests/test_country.py @@ -55,6 +55,22 @@ def test_returns_failed_validation_on_invalid_country_code(value: str, iso_forma assert isinstance(country_code(value, iso_format=iso_format), ValidationError) +@pytest.mark.parametrize( + ("value", "iso_format"), + [ + ("\u0131t", "auto"), + ("\u017fe", "alpha2"), + ("\u0131ta", "auto"), + ("\ufb01N", "alpha3"), + ], +) +def test_returns_failed_validation_on_non_ascii_case_equivalent_country_code( + value: str, iso_format: str +): + """Test returns failed validation when Unicode case mapping yields an ASCII code.""" + assert isinstance(country_code(value, iso_format=iso_format, ignore_case=True), ValidationError) + + @pytest.mark.parametrize( ("value", "skip_symbols", "ignore_case"), [("$", False, False), ("⃀", False, False), ("৳", False, False), ("uSd", True, True)], @@ -73,6 +89,8 @@ def test_returns_true_on_valid_currency(value: str, skip_symbols: bool, ignore_c ("⃀৳", False, False), ("uSd", True, False), ("Bucks", True, True), + ("u\u017fd", True, True), + ("\u0131ls", True, True), ], ) def test_returns_failed_validation_invalid_currency(