Skip to content

Commit 7f3e4c1

Browse files
authored
Merge commit from fork
[v10] fix(gantt): limit loop if excluding all dates
2 parents 11d6dc4 + a59ea56 commit 7f3e4c1

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

packages/mermaid/src/diagrams/gantt/ganttDb.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,21 +231,28 @@ const checkTaskDates = function (task, dateFormat, excludes, includes) {
231231
* @param {dayjs.Dayjs} startTime - The start time.
232232
* @param {dayjs.Dayjs} endTime - The original end time (will return a different end time if it's invalid).
233233
* @param {string} dateFormat - Dayjs date format string.
234-
* @param {*} excludes
235-
* @param {*} includes
234+
* @param {string[]} excludes - Dates or days to exclude.
235+
* @param {string[]} includes - Dates to always include, even if they match the excludes.
236236
* @returns {[endTime: dayjs.Dayjs, renderEndTime: Date | null]} The new `endTime`, and the end time to render.
237237
* `renderEndTime` may be `null` if `startTime` is newer than `endTime`.
238+
* @throws {Error} If a valid end time cannot be found after 10,000 iterations.
238239
*/
239240
const fixTaskDates = function (startTime, endTime, dateFormat, excludes, includes) {
240241
let invalid = false;
241242
let renderEndTime = null;
243+
const maxEndTime = endTime.add(10000, 'd');
242244
while (startTime <= endTime) {
243245
if (!invalid) {
244246
renderEndTime = endTime.toDate();
245247
}
246248
invalid = isInvalidDate(startTime, dateFormat, excludes, includes);
247249
if (invalid) {
248250
endTime = endTime.add(1, 'd');
251+
if (endTime > maxEndTime) {
252+
throw new Error(
253+
'Failed to find a valid date that was not excluded by `excludes` after 10,000 iterations.'
254+
);
255+
}
249256
}
250257
startTime = startTime.add(1, 'd');
251258
}

packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,19 @@ describe('when using the ganttDb', function () {
267267
expect(tasks[6].task).toEqual('test7');
268268
});
269269

270+
it('should not infinite loop when excluding everything', function () {
271+
ganttDb.setDateFormat('YYYY-MM-DD');
272+
ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday,friday');
273+
ganttDb.addSection('weekends skip test');
274+
ganttDb.addTask('test1', 'id1,2019-02-01,7d');
275+
276+
expect(() => ganttDb.getTasks()).toThrowError('Failed to find a valid date');
277+
278+
// Fridays are now allowed, so it should not throw an error
279+
ganttDb.setExcludes('weekends,monday,tuesday,wednesday,thursday');
280+
expect(() => ganttDb.getTasks()).not.toThrow();
281+
});
282+
270283
it('should maintain the order in which tasks are created', function () {
271284
ganttDb.setAccTitle('Project Execution');
272285
ganttDb.setDateFormat('YYYY-MM-DD');

0 commit comments

Comments
 (0)