Skip to content

fix(isCreditCard): fix Mastercard regex anchoring bug#2739

Open
algojogacor wants to merge 1 commit into
validatorjs:masterfrom
algojogacor:fix/mastercard-regex-anchoring
Open

fix(isCreditCard): fix Mastercard regex anchoring bug#2739
algojogacor wants to merge 1 commit into
validatorjs:masterfrom
algojogacor:fix/mastercard-regex-anchoring

Conversation

@algojogacor
Copy link
Copy Markdown

This is an independent contribution submitted as part of an open-source contribution practice. It is not affiliated with any hackathon or competition.

Summary

The Mastercard regex pattern in isCreditCard has a regex operator precedence bug that causes it to accept partial strings like "5108" as valid credit card numbers.

Root Cause

The original regex:

/^5[1-5][0-9]{2}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/

Due to | having lower precedence than ^ and $, this parsed as two unanchored alternatives:

  1. ^5[1-5][0-9]{2} — start-anchored only, matches any string beginning with 51XX–55XX regardless of length
  2. (222[1-9]|...)[0-9]{12}$ — end-anchored only

This allowed inputs such as "5108" (4 digits) to pass the format check.

Fix

Wrapped the alternation in a non-capturing group so both anchors bind to all branches:

-  /^5[1-5][0-9]{2}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/
+  /^(?:5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12})$/

Also fixed the 51-55 branch which was missing its trailing digit quantifier [0-9]{12}.

Testing

  • All 318 existing tests pass (100% statement/function/line coverage)
  • Manually verified "5108" now correctly returns false
  • Manually verified valid Mastercard numbers like "5398228707871527" continue to return `true"

Closes #2717

The Mastercard regex had a regex operator precedence bug due to unanchored
alternation. The pattern:
  /^5[1-5][0-9]{2}|(222[1-9]|...)[0-9]{12}$/

Due to | having lower precedence than ^ and $, this parsed as:
1. ^5[1-5][0-9]{2}  (start-anchored only — matches any string starting
   with 51XX-55XX regardless of length)
2. (222[1-9]|...)[0-9]{12}$ (end-anchored only)

This caused isCreditCard to return true for partial strings like '5108'
and short 4-digit inputs.

Fixed by wrapping the alternation in a non-capturing group with both
anchors outside: ^(?:5[1-5][0-9]{14}|...)$

Closes validatorjs#2717
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (7fdc788) to head (7ff658b).

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #2739   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          114       114           
  Lines         2587      2587           
  Branches       656       656           
=========================================
  Hits          2587      2587           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

isCreditCard: Mastercard regex anchoring bug accepts 4-digit and partial strings

1 participant