Skip to content

Commit

Permalink
Try again before avoiding death by recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
darktrojan authored and kewisch committed Apr 15, 2024
1 parent eaf5b23 commit 4620888
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
9 changes: 5 additions & 4 deletions lib/ical/recur.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ class Recur {

if (ucname in partDesign) {
let partArr = value.split(',');
let partArrIdx = 0;
let partArrLen = partArr.length;
let partSet = new Set();

for (; partArrIdx < partArrLen; partArrIdx++) {
partArr[partArrIdx] = partDesign[ucname](partArr[partArrIdx]);
for (let part of partArr) {
partSet.add(partDesign[ucname](part));
}
partArr = [...partSet];

dict[name] = (partArr.length == 1 ? partArr[0] : partArr);
} else if (ucname in optionDesign) {
optionDesign[ucname](value, dict, fmtIcal);
Expand Down
9 changes: 5 additions & 4 deletions lib/ical/recur_iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class RecurIterator {
* Retrieve the next occurrence from the iterator.
* @return {ICAL.Time}
*/
next() {
next(again = false) {
let before = (this.last ? this.last.clone() : null);

if ((this.rule.count && this.occurrence_number >= this.rule.count) ||
Expand Down Expand Up @@ -395,10 +395,11 @@ class RecurIterator {
this.last.compare(this.dtstart) < 0 ||
!valid);

// TODO is this valid?
if (this.last.compare(before) == 0) {
throw new Error("Same occurrence found twice, protecting " +
"you from death by recursion");
if (again) {
throw new Error("Same occurrence found twice, protecting you from death by recursion");
}
this.next(true);
}

if (this.rule.until && this.last.compare(this.rule.until) > 0) {
Expand Down
29 changes: 29 additions & 0 deletions test/recur_iterator_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,35 @@ suite('recur_iterator', function() {
]
});

// Last day and 31st day of the month. The last day could be the 31st,
// and this shouldn't throw an error.
testRRULE('FREQ=MONTHLY;BYMONTHDAY=-1,31', {
dtStart: '2022-01-01T08:00:00',
dates: [
'2022-01-31T08:00:00',
'2022-02-28T08:00:00',
'2022-03-31T08:00:00',
'2022-04-30T08:00:00',
'2022-05-31T08:00:00',
'2022-06-30T08:00:00'
]
});

// 31st day of the month, specified more than once. The repeated values
// should be collapsed to one.
testRRULE('FREQ=MONTHLY;BYMONTHDAY=31,31,31,31', {
dtStart: '2022-01-01T08:00:00',
dates: [
'2022-01-31T08:00:00',
'2022-03-31T08:00:00',
'2022-05-31T08:00:00',
'2022-07-31T08:00:00',
'2022-08-31T08:00:00',
'2022-10-31T08:00:00',
'2022-12-31T08:00:00',
]
});

// Last day of the month, monthly.
testRRULE('FREQ=MONTHLY;BYMONTHDAY=-1', {
dtStart: '2015-01-01T08:00:00',
Expand Down

0 comments on commit 4620888

Please sign in to comment.