Repository: validatorjs/validator.js
Pull request #2443 (2024-08-25 11:52:25)

fix(isDate): fix thrown error on certain invalid cases
Fix for #2427 - isDate will not throw an Error anymore, but correctly return `false` for these invalid cases.

This is done, by changing the zip function to take the *max* not the *min* length -> if there is any discrepancy between input and dateFormat (i.e. input has only 2 parts, but dateFormat has 3), this then causes one of the values inside the `zippedArr` "tuple" to be undefined, which we then test for.
And if undefined -> we return `false`.

This avoids us running into the error described in #2427, where it then tried to read the length of "undefined".


As a bonus, this change also fixes some false positives (e.g. "2024-05-05-abc" was returning `true`, which it shouldn't have).
Generally speaking, the isDate function is in need of a proper refactoring, it kinda feels a bit strange in its current form -> but this is something for the future :-)

## Checklist

- [x] PR contains only changes related; no stray files, etc.
- [x] README updated (where applicable)
- [x] Tests written (where applicable)
- [x] References provided in PR (where applicable)



Patch:
diff --git a/src/lib/isDate.js b/src/lib/isDate.js
index dc69b3b..ede3e33 100644
--- a/src/lib/isDate.js
+++ b/src/lib/isDate.js
@@ -12,7 +12,7 @@ function isValidFormat(format) {
 
 function zip(date, format) {
   const zippedArr = [],
-    len = Math.min(date.length, format.length);
+    len = Math.max(date.length, format.length);
 
   for (let i = 0; i < len; i++) {
     zippedArr.push([date[i], format[i]]);
@@ -40,7 +40,7 @@ export default function isDate(input, options) {
     const dateObj = {};
 
     for (const [dateWord, formatWord] of dateAndFormat) {
-      if (dateWord.length !== formatWord.length) {
+      if (!dateWord || !formatWord || dateWord.length !== formatWord.length) {
         return false;
       }
 


Test patch:
diff --git a/test/testFunctions.js b/test/testFunctions.js
index bcd7c15..5fc133b 100644
--- a/test/testFunctions.js
+++ b/test/testFunctions.js
@@ -2,6 +2,10 @@ import assert from 'assert';
 import { format } from 'util';
 import validator from '../src/index';
 
+function stringifyArgs(argsArr) {
+  return argsArr.map(arg => JSON.stringify(arg)).join(', ');
+}
+
 export default function test(options) {
   const args = options.args || [];
 
@@ -16,7 +20,7 @@ export default function test(options) {
       } catch (err) {
         const warning = format(
           'validator.%s(%s) passed but should error',
-          options.validator, args.join(', ')
+          options.validator, stringifyArgs(args)
         );
 
         throw new Error(warning);
@@ -31,7 +35,7 @@ export default function test(options) {
       if (validator[options.validator](...args) !== true) {
         const warning = format(
           'validator.%s(%s) failed but should have passed',
-          options.validator, args.join(', ')
+          options.validator, stringifyArgs(args)
         );
 
         throw new Error(warning);
@@ -46,7 +50,7 @@ export default function test(options) {
       if (validator[options.validator](...args) !== false) {
         const warning = format(
           'validator.%s(%s) passed but should have failed',
-          options.validator, args.join(', ')
+          options.validator, stringifyArgs(args)
         );
 
         throw new Error(warning);
diff --git a/test/validators.test.js b/test/validators.test.js
index b77f04b..3b6ede6 100644
--- a/test/validators.test.js
+++ b/test/validators.test.js
@@ -13680,6 +13680,7 @@ describe('Validators', () => {
         new Date([2014, 2, 15]),
         new Date('2014-03-15'),
         '2020/02/29',
+        '2020-02-19',
       ],
       invalid: [
         '',
@@ -13695,6 +13696,18 @@ describe('Validators', () => {
         '2020/03-15', // mixed delimiter
         '-2020-04-19',
         '-2023/05/24',
+        'abc-2023/05/24',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
       ],
     });
     test({
@@ -13710,6 +13723,21 @@ describe('Validators', () => {
         '15/7/02',
         '15-7-02',
         '15-07/2002',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '15/',
+        '15/07',
+        '15/07/',
+        '15/07/2024/',
       ],
     });
     test({
@@ -13725,6 +13753,21 @@ describe('Validators', () => {
         '15/7/02',
         '15-7-02',
         '15-07/2002',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '15/',
+        '15/07',
+        '15/07/',
+        '15/07/2024/',
       ],
     });
     test({
@@ -13739,6 +13782,22 @@ describe('Validators', () => {
         '15-7-2002',
         '15/07-02',
         '30/04/--',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '15/',
+        '15/07',
+        '15/07/',
+        '15/07/2024/',
+        '15/07/24/',
       ],
     });
     test({
@@ -13754,6 +13813,16 @@ describe('Validators', () => {
         '15-7-02',
         '5/7-02',
         '3/4/aa',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '15/',
+        '15/07',
+        '15/07/',
+        '15/07/2024/',
+        '15/07/24/',
       ],
     });
     test({
@@ -13769,6 +13838,16 @@ describe('Validators', () => {
         '15/7/02',
         '15-7-02',
         '15-07/2002',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '15/',
+        '15/07',
+        '15/07/',
+        '15/07/2024/',
+        '15/07/24/',
       ],
     });
     test({
@@ -13787,6 +13866,20 @@ describe('Validators', () => {
         new Date(),
         new Date([2014, 2, 15]),
         new Date('2014-03-15'),
+        '-2020-04-19',
+        '-2023/05/24',
+        'abc-2023/05/24',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
       ],
     });
     test({
@@ -13812,6 +13905,21 @@ describe('Validators', () => {
         '2019/02/29',
         '2020/04/31',
         '2020/03-15',
+        '-2020-04-19',
+        '-2023/05/24',
+        'abc-2023/05/24',
+        '2024',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01-',
+        '2024-05-01-abc',
+        '2024/',
+        '2024/05',
+        '2024/05/',
+        '2024/05/01/',
+        '2024/05/01/abc',
+        '2024 05 01 abc',
       ],
     });
     test({
@@ -13831,6 +13939,16 @@ describe('Validators', () => {
         new Date([2014, 2, 15]),
         new Date('2014-03-15'),
         '29.02.2020',
+        '2024-',
+        '2024-05',
+        '2024-05-',
+        '2024-05-01',
+        '-2020-04-19',
+        '-2023/05/24',
+        'abc-2023/05/24',
+        '04.05.2024.',
+        '04.05.2024.abc',
+        'abc.04.05.2024',
       ],
     });
     // emulating Pacific time zone offset & time