hapijs / joi

The most powerful data validation library for JS
Other
20.89k stars 1.51k forks source link

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

Open Toltar opened 2 years ago

Toltar commented 2 years ago

Context

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.

Kanosakl commented 2 years ago

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.

Marsup commented 2 years ago

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?

hueniverse commented 2 years ago

Seems reasonable.

JonCookeEurostar commented 1 year ago

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'```