From 534d723e58f08ec702be4e1aa558b0852867592e Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 7 Jul 2024 18:58:47 -0400 Subject: [PATCH] Fix: holiday calculation failed on last day of Islamic leap year 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. --- src/hacklib.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hacklib.c b/src/hacklib.c index c09774c117..2f58aba49e 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -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,6 +1476,8 @@ 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; @@ -1479,7 +1485,7 @@ current_holidays(void) } 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) {