angular / angular/components

bug(LuxonDateAdapter): LuxonDateAdapter.parse() returns valid date even though none of the given input date formats is matched

Open
#25,590 7 comments 6 reactions 0 assignees View on GitHub
area: material/datepicker P3
Dominant language
TypeScript
Stars
25k
Forks
6.8k
Avg merge
1d 8h
Merged PRs (30d)
91

Description

### Is this a regression?

- [ ] Yes, this behavior used to work in the previous version

### The previous version in which this bug was not present was

_No response_

### Description

The "parse" function in the **LuxonDateAdapter** tries to parse any input as a **iso8601** date before it matches the given input formats.

For Example, if I declare ['d.L.yy', 'd-L-yy'] as valid input formats, I would expect that only dates using the separators "." and "-"
are valid input dates.
But due to the iso8601 parse a simple number input (eg. 12) will return a valid date, most times today.
You can see the iso8601 parse and return on line 162 of [luxon-date-.adapter.ts](https://github.com/angular/components/blob/main/src/material-luxon-adapter/adapter/luxon-date-adapter.ts)
Where as the formats are checked later on line 174.

```
parse(value: any, parseFormat: string | string[]): LuxonDateTime | null {
const options: LuxonDateTimeOptions = this._getOptions();

if (typeof value == 'string' && value.length > 0) {
const iso8601Date = LuxonDateTime.fromISO(value, options);

if (this.isValid(iso8601Date)) {
return iso8601Date; // This return is without any parseFormat check !!!!!!
}

const formats = Array.isArray(parseFormat) ? parseFormat : [parseFormat];

if (!parseFormat.length) {
throw Error('Formats array must not be empty.');
}

for (const format of formats) {
const fromFormat = LuxonDateTime.fromFormat(value, format, options); // Here are the formats checked

if (this.isValid(fromFormat)) {
return fromFormat;
}
}

return this.invalid();
} else if (typeof value === 'number') {
return LuxonDateTime.fromMillis(value, options);
} else if (value instanceof Date) {
return LuxonDateTime.fromJSDate(value, options);
} else if (value instanceof LuxonDateTime) {
return LuxonDateTime.fromMillis(value.toMillis(), options);
}

return null;
}
```

This parsing without any regard for the given input parseFormat seems to be incorrect.

### Reproduction

There is test in [luxon-date-adapter,spec.ts](https://github.com/angular/components/blob/main/src/material-luxon-adapter/adapter/luxon-date-adapter.spec.ts) on line 310 which shows the behaviour . The input format is LL/dd/yyyy, but just a number is given.

### Expected Behavior

The test mentioned above should return an invalid date, because the given parseFormat is not matched.

### Actual Behavior

The function returns a valid ISO date, based on the number.

### Environment

"@angular/animations": "12.2.16",
"@angular/cdk": "12.2.13",
"@angular/common": "12.2.16",
"@angular/compiler": "12.2.16",
"@angular/core": "12.2.16",
"@angular/forms": "12.2.16",
"@angular/material": "12.2.13",
"@angular/material-luxon-adapter": "12.2.13",
"@angular/platform-browser": "12.2.16",
"@angular/platform-browser-dynamic": "12.2.16",
"@angular/router": "12.2.16",
"luxon": "2.3.0",

Above are the versios we are using in our code, but the code pasted in the description is from the current @angular/material-luxon-adapter, so the bug is still there.

Contributor guide

Open the contributing guide

Research direction

Start in src/material-luxon-adapter/adapter/luxon-date-adapter.ts at LuxonDateAdapter.parse(), then read the reproduction around line 310 in luxon-date-adapter.spec.ts. Run the Luxon date adapter tests and verify that an input which does not match the supplied format returns an invalid date rather than a valid ISO date.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.