Fix quest array off-by-ones and add QuestID bounds checks

Several quest-loading loops used <=N over arrays sized N (Variables,
Switches, Items, EpisodeVar, JobVar, PlanetVar, UnionVar), writing one
element past the end on every character load. Also guard STB_QUEST
table lookups with a rowcount bounds check before indexing by
QuestID, which could otherwise read out of bounds for stale/invalid
quest ids.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
ThomasandClaude Sonnet 5 committed 2026-07-09 06:35:11 +02:00
1 parent 725620e23c
commit f59158a95c
4 files changed
+13 -12

No files matched your search

+2 -2
View File
@@ -169,7 +169,7 @@ void CWorldServer::pakQuestData( CPlayer *thisclient )
//Log( MSG_DEBUG, "Initialized Time");
//Log( MSG_DEBUG, "This Quest quest id = %i",thisclient->quest.quests[i].QuestID);
//Log( MSG_DEBUG, "This Quest STB quest id = %i",STB_QUEST.rows[thisclient->quest.quests[i].QuestID][1]);
if (thisclient->quest.quests[i].QuestID > 0 && STB_QUEST.rows[thisclient->quest.quests[i].QuestID][1] > 0)
if (thisclient->quest.quests[i].QuestID > 0 && thisclient->quest.quests[i].QuestID < STB_QUEST.rowcount && STB_QUEST.rows[thisclient->quest.quests[i].QuestID][1] > 0)
{
//Log( MSG_DEBUG, "client has a timed quest");
Time += thisclient->quest.quests[i].StartTime; // Start time
@@ -187,7 +187,7 @@ void CWorldServer::pakQuestData( CPlayer *thisclient )
//Log( MSG_DEBUG, "added quest vars");
for(dword j = 0; j < 4; j++) pakout.AddByte(thisclient->quest.quests[i].Switches[j]);
//Log( MSG_DEBUG, "added quest switches");
for(dword j = 0; j < 6; j++)
for(dword j = 0; j < 5; j++)
{
if (thisclient->quest.quests[i].Items[j].itemnum != 0)
{