Skip to content

Moldova (MD) postcode pattern rejects valid codes and accepts invalid ones #73

Description

@vadviktor

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:

\d{4}

— 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions