From 5146597751527a5b5f261aec27d6e6bc6a602966 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Wed, 27 Nov 2024 20:11:12 -0800 Subject: [PATCH] fix heap smash in birthday tracking --- docs/changelog.txt | 1 + plugins/timestream.cpp | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/changelog.txt b/docs/changelog.txt index d96475f0ee..b657c2b09a 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -61,6 +61,7 @@ Template for new versions: - `autobutcher`: don't run a scanning and marking cycle on the first tick of a fortress to allow for all custom configuration to be set first - `nestboxes`: don't consider eggs to be infertile just because the mother has left the nest; eggs can still hatch in this situation - `timestream`: adjust the incubation counter on fertile eggs so they hatch at the expected time +- `timestream`: fix potential crash in birthday tracking - `logistics`: don't ignore rotten items when applying stockpile logistics operations (e.g. autodump, autoclaim, etc.) ## Misc Improvements diff --git a/plugins/timestream.cpp b/plugins/timestream.cpp index 512e3c215c..c37e33ca35 100644 --- a/plugins/timestream.cpp +++ b/plugins/timestream.cpp @@ -121,13 +121,15 @@ static std::array tick_coverage; // only throttle due to tick_coverage at most once per season tick to avoid clustering static bool season_tick_throttled = false; +static const int32_t TICKS_PER_YEAR = 403200; + static void register_birthday(df::unit * unit) { - auto & btick = unit->birth_time; - if (btick < 0) + int32_t btick = unit->birth_time; + if (btick < 0 || btick > TICKS_PER_YEAR) return; - for (size_t tick=btick; tick >= 0; --tick) { - if (birthday_triggers.size() <= tick) - birthday_triggers.resize(btick-1, INT32_MAX); + if (birthday_triggers.size() <= (size_t)btick) + birthday_triggers.resize(btick+1, INT32_MAX); + for (int32_t tick=btick; tick >= 0; --tick) { if (birthday_triggers[tick] > btick) birthday_triggers[tick] = btick; else @@ -286,7 +288,7 @@ static int32_t get_next_trigger_year_tick(int32_t next_tick) { } static int32_t get_next_birthday(int32_t next_tick) { - if (next_tick >= (int32_t)birthday_triggers.size()) + if (next_tick < 0 || next_tick >= (int32_t)birthday_triggers.size()) return INT32_MAX; return birthday_triggers[next_tick]; }