Skip to content

fix(es,ca): guard to_currency() cents-part for integer inputs#659

Open
fbindakheel wants to merge 1 commit into
savoirfairelinux:masterfrom
fbindakheel:fix/es-ca-currency-integer-crash
Open

fix(es,ca): guard to_currency() cents-part for integer inputs#659
fbindakheel wants to merge 1 commit into
savoirfairelinux:masterfrom
fbindakheel:fix/es-ca-currency-integer-crash

Conversation

@fbindakheel
Copy link
Copy Markdown

Bug

to_currency() crashes with IndexError for Spanish (es) and Catalan (ca) when the input is an integer that resolves to a whole currency unit (zero cents). For example:

num2words(100, lang='es', to='currency')  # → IndexError: list index out of range
num2words(0,   lang='es', to='currency')  # → IndexError: list index out of range

This affects all whole-unit integer inputs — 0, 100 (1 euro), 200, 2100, etc.

Root cause

Both lang_ES.py and lang_CA.py override to_currency() by calling the base implementation, then splitting the result on the separator (con / amb) to get [dollars_part, cents_part]. They then unconditionally apply grammar fixes to list_result[1].

However, the base to_currency() omits the cents segment entirely when the input has no cents (i.e. integer input where right == 0 and has_decimal is False). This leaves list_result with only one element, so list_result[1] raises IndexError.

The existing tests only used float inputs like 1.00, 21.00 — floats always produce a cents segment (con cero céntimos), so the integer path was never exercised.

Fix

Guard the cents-part post-processing with if len(list_result) > 1: in both files. The dollars-part handling is unaffected.

Tests

Added regression tests in tests/test_es.py and tests/test_ca.py covering integer whole-unit amounts and feminine currencies. Verified the new tests fail on the original code and pass with the fix. All 1495 tests pass.

num2words(0,    lang='es', to='currency')  # → 'cero euros'
num2words(100,  lang='es', to='currency')  # → 'un euro'
num2words(2100, lang='es', to='currency')  # → 'veintiún euros'
num2words(100,  lang='es', to='currency', currency='GBP')  # → 'una libra'

Integer inputs with no cents cause the base to_currency() to omit
the cents segment, leaving list_result with a single element.
The ES and CA overrides unconditionally accessed list_result[1],
raising IndexError for any whole-unit amount (e.g. num2words(100,
lang='es', to='currency')).

Guard the cents-part processing with len(list_result) > 1.
Add regression tests for both languages.
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.

1 participant