Skip to content

Commit

Permalink
Fix: holiday calculation failed on last day of Islamic leap year
Browse files Browse the repository at this point in the history
On a leap year in the Islamic calendar, there are 355 days, and today
happens to have been the first 355th day of the year since this holiday
calculation was introduced. This exposed a condition triggering one of
the impossible() calls: the computation of which month it was did not
consider the possibility of extending the last month by an extra day.
Fix it by accounting for that, and also strengthen the error check in
case it winds up at an even more out-of-bounds month somehow.

There don't happen to be any holidays xNetHack recognizes on the last
day of the year, so this didn't have any impact beyond the error
message.
copperwater committed Jul 7, 2024
1 parent 308707c commit 534d723
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/hacklib.c
Original file line number Diff line number Diff line change
@@ -1452,18 +1452,22 @@ current_holidays(void)

/* There are 166 days in the partial year 622. Start with that. */
int date_delta = today_epoch - days_since_epoch(6220719);
int cycyear;

/* Now cut off as many 30-year periods as possible. */
date_delta = date_delta % 10631;
/* Then cut off year by year until we reach the current lunar year. */
for (i = 0; i < 30; ++i) {
int this_year_len = 354 + lunar_leap[i];
for (cycyear = 0; cycyear < 30; ++i) {
int this_year_len = 354 + lunar_leap[cycyear];
if (date_delta < this_year_len) {
break;
/* cycyear stays in scope so we can tell below if it is
* currently a leap year and need to adjust the last month
* accordingly */
}
date_delta -= this_year_len;
}
if (date_delta < 0 || i == 30) {
if (date_delta < 0 || cycyear == 30) {
impossible("holiday: bad math finding lunar year");
date_delta = 0;
}
@@ -1472,14 +1476,16 @@ current_holidays(void)
int islam_month = 0, islam_date = 0;
for (i = 0; i < 12; ++i) {
int month_len = (i % 2 == 1) ? 29 : 30;
if (i == 11)
month_len += lunar_leap[cycyear];
if (date_delta < month_len) {
islam_month = i + 1; /* convert back to human-readable */
islam_date = date_delta + 1;
break;
}
date_delta -= month_len;
}
if (date_delta < 0 || i == 12) {
if (date_delta < 0 || i >= 12) {
impossible("holiday: bad math finding lunar month/date");
}
if (islam_month == 9) {

0 comments on commit 534d723

Please sign in to comment.