Hey @dgilperez , first of all, thank you for this gem. We use this in our app and a client has found an issue that we've patched internally, though I wish to contribute the fix upstream for the benefit of others.
The MD entry in ZIPCODES_REGEX is both too strict and too loose:
MD: /\A(([A-Z]){2})(|\s)\d{4}\z/i,
It requires any two letters followed by four digits (optionally separated by a space). That has two problems:
| Input |
Real status |
Gem result |
Correct? |
MD-2001 |
valid — canonical international form |
rejected (no hyphen allowed) |
❌ |
2001 |
valid — bare domestic form |
rejected (prefix required) |
❌ |
XY2001 |
not a Moldovan postcode |
accepted (any 2 letters pass) |
❌ |
MD2001 |
valid |
accepted |
✅ |
So a genuine address written MD-2001 fails validation, while a nonsense code like XY2001 passes.
Root cause
The gem cites CLDR's postalCodeData.xml as its source. CLDR's MD value was simply:
— four digits, no letter prefix at all. The current gem regex doesn't match its own cited source: a mandatory two-letter prefix was added that CLDR never specified, which is what lets any XY/ZZ prefix through and what blocks the bare 4-digit form.
CLDR's \d{4} alone is also incomplete today: it rejects the canonical international MD-#### form (e.g. MD-2001) used by the Universal Postal Union and Google's address metadata.
Proposed fix
MD: /\A(MD[- ]?)?\d{4}\z/i,
This is CLDR's \d{4}, extended to also accept the documented MD-#### / MD #### / MD#### prefix. It accepts every real Moldovan code and rejects non-MD prefixes:
- valid:
2001, MD2001, MD-2001, MD 2001 (case-insensitive)
- invalid:
XY2001, MD-202 (wrong digit count)
I verified it against the full UPU / GeoNames Moldovan postcode set (1,215 distinct codes, including the Transnistria region — Tiraspol MD-3300, Bender MD-3200); all pass, none falsely rejected.
Note on the existing test
spec/spec_helper.rb currently asserts MD-2100 is invalid, which mirrors the broken regex rather than reality. A fix needs to flip that to valid (and add 2001 / a non-MD prefix as the new regression cases).
PR
I have a small PR ready (regex + updated MD fixture + CHANGELOG) — happy to open it if this looks right to you.
Hey @dgilperez , first of all, thank you for this gem. We use this in our app and a client has found an issue that we've patched internally, though I wish to contribute the fix upstream for the benefit of others.
The MD entry in
ZIPCODES_REGEXis both too strict and too loose:It requires any two letters followed by four digits (optionally separated by a space). That has two problems:
MD-20012001XY2001MD2001So a genuine address written
MD-2001fails validation, while a nonsense code likeXY2001passes.Root cause
The gem cites CLDR's
postalCodeData.xmlas its source. CLDR's MD value was simply:— four digits, no letter prefix at all. The current gem regex doesn't match its own cited source: a mandatory two-letter prefix was added that CLDR never specified, which is what lets any
XY/ZZprefix through and what blocks the bare 4-digit form.CLDR's
\d{4}alone is also incomplete today: it rejects the canonical internationalMD-####form (e.g.MD-2001) used by the Universal Postal Union and Google's address metadata.Proposed fix
This is CLDR's
\d{4}, extended to also accept the documentedMD-####/MD ####/MD####prefix. It accepts every real Moldovan code and rejects non-MDprefixes:2001,MD2001,MD-2001,MD 2001(case-insensitive)XY2001,MD-202(wrong digit count)I verified it against the full UPU / GeoNames Moldovan postcode set (1,215 distinct codes, including the Transnistria region — Tiraspol
MD-3300, BenderMD-3200); all pass, none falsely rejected.Note on the existing test
spec/spec_helper.rbcurrently assertsMD-2100is invalid, which mirrors the broken regex rather than reality. A fix needs to flip that to valid (and add2001/ a non-MDprefix as the new regression cases).PR
I have a small PR ready (regex + updated MD fixture + CHANGELOG) — happy to open it if this looks right to you.