Skip to content

isISO8601 misroutes signed ordinal dates #2860

Description

@uhop

Describe the bug

The ordinal-date branch in isValidDate matches with

const ordinalMatch = str.match(/^(\d{4})-?(\d{3})([ T]{1}\.*|$)/);

That pattern has no sign prefix, although the main isISO8601 regex accepts a
leading + or - on the year. A signed ordinal date therefore fails this
match and falls through to the calendar branch, where the generic
(\d{4})-?(\d{0,2})-?(\d*) split cuts the three-digit day-of-year into a
two-digit month and a one-digit day.

The result is that day-of-year is never validated for signed ordinal dates, and
some valid ones are rejected outright.

Examples

const validator = require('validator'); // 13.15.35

// Day 145 of 2009 exists, but the split reads month 14, day 5 and rejects it
validator.isISO8601('+2009-145', { strict: true }); // false, expected true

// Day 130 exists too; here the split reads month 13, day 0, the guard falls
// through, and it is accepted without any check
validator.isISO8601('+2009-130', { strict: true }); // true, unvalidated

// Unsigned ordinals take the intended branch and behave correctly
validator.isISO8601('2009-145', { strict: true });  // true

Reproductions

The Examples block above runs as-is on Node after
npm install validator@13.15.35; no harness or scaffolding needed.

Additional context

Adding [+-]? to the ordinal pattern would route these to the branch that
already handles them, including the leap-year bound on line 19.

Validator.js version: 13.15.35
Node.js version: v26.7.0
OS platform: Linux

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions