joi icon indicating copy to clipboard operation
joi copied to clipboard

Joi.string().isoDate() accepts iso strings that have invalid values, but have valid iso string formats

Open Toltar opened this issue 2 years ago • 4 comments

Context

  • node version: 14.18.3
  • module version with issue: 17.5.0
  • last module version without issue: N/A
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): standalone
  • any other relevant information:

What are you trying to achieve or the steps to reproduce?

I gave isoDate() an invalid date of 2022-02-30T07:45:10.179Z here, but errors is undefined.

import * as Joi from 'joi';

export const iso8601StringValidation = Joi.string().isoDate();

const isoString = '2022-02-30T07:45:10.179Z';
const result = iso8601StringValidation.validate(isoString); // errors are undefined and this is considered valid by joi

I know this seems kind of a niche bug, but I would think this would give an error at lease saying the user provided a ISO date that is simply just invalid. I notice in the code that we check if it is a valid date by checking if getTime() is NaN. But apparently, javascript just says that date is just March 1st of 2020.

What was the result you got?

The iso date is valid for JOI even though there is no 30th of February.

What result did you expect?

I expected joi to catch this and give an error message saying that this is not a valid date at all.

Toltar avatar Jan 27 '22 18:01 Toltar

Hmm, in my opinion, joi.isoDate() scope is to only make sure that the date string conforms to ISO 8601 date time format. Value validation is the responsibility of javascript language or if you apply your own date-time value validation using library such as date-fns.

Without any other dependency, I believe that joi's value validation shouldn't be any different from javascript's implementation.

Kanosakl avatar Feb 02 '22 04:02 Kanosakl

In this case, I think it wouldn't be this hard to compare an ISO string to what JavaScript gives back as ISO string once converted to Date. Thoughts @hueniverse?

Marsup avatar Feb 22 '22 18:02 Marsup

Seems reasonable.

hueniverse avatar Mar 23 '22 00:03 hueniverse

If this is implemented, I think it needs to be optional, something like Joi.date().iso().strict() as the date constructor tolerates ISO strings with values that are out of range, but interprets them rationally as though they were the result of arithmetic without overflow.

e.g. ```

new Date('1973-11-31T21:33:09.000Z').toISOString() '1973-12-01T21:33:09.000Z'```

JonCookeEurostar avatar Jun 08 '23 13:06 JonCookeEurostar