Skip to content

Reject non-ASCII case equivalents in country and currency codes - #551

Open
Enesuygurs wants to merge 1 commit into
python-validators:masterfrom
Enesuygurs:fix/country-code-currency-ascii-case
Open

Enesuygurs wants to merge 1 commit into
python-validators:masterfrom
Enesuygurs:fix/country-code-currency-ascii-case

Conversation

@Enesuygurs

Copy link
Copy Markdown

With ignore_case=True, country_code() and currency() compare value.upper() against the ISO 3166 / ISO 4217 lists. str.upper() maps some non-ASCII letters onto ASCII ones, so values that are not ISO codes are accepted:

  • currency("uſd", ignore_case=True) returns True (long s, becomes USD)
  • currency("ıls", ignore_case=True) returns True (dotless i, becomes ILS)
  • country_code("ıt", ignore_case=True) returns True (becomes IT)
  • country_code("ıta", ignore_case=True) returns True (becomes ITA)
  • country_code("fiN", iso_format="alpha3", ignore_case=True) returns True (the 2-character value becomes FIN)

This is the same class of issue that was fixed for IBANs in #512. The fix requires ASCII input before the case-insensitive lookup. ASCII codes in any case, and the currency symbol check (skip_symbols=False), behave as before.

The new parametrized test cases fail before this change and pass after it. The full suite passes (1522 tests, plus 58 doctests), and ruff check, ruff format --check and pyright are clean on the changed files.

With ignore_case=True, country_code() and currency() compared
value.upper() against the ISO lists. str.upper() maps letters such as
dotless i (U+0131), long s (U+017F) and the fi ligature (U+FB01) onto
ASCII, so "ıt", "ıta", "fiN" and "uſd" were accepted as
IT, ITA, FIN and USD. Require ASCII input before case-insensitive
matching.

@agammann agammann left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the country and currency lookup guards at f63135a. They reject Unicode letters that uppercase into ASCII ISO codes while keeping ASCII mixed-case inputs valid; the existing currency-symbol branch still runs before the ASCII guard. The country/currency test module passes locally (37 tests on Python 3.14.8). I did not run the full suite or platform matrix.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants