[Scummvm-git-logs] scummvm master -> 99c131b64bec5dac0801ec65f05118332fc5a81f
sev-
noreply at scummvm.org
Thu Jul 16 13:53:36 UTC 2026
This automated email contains information about 16 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
8a44ebe035 DM: Fix potential out-of-bounds write in printMessageAfterReplacements. CID 1499983
e2b5b0d02b DM: Clip sensor group generator creature count to valid array bounds. CID 1470680
739bd0af49 DM: Remove obsolete index scaling from _boxChampionIcons lookups. CID 1470604
9611819899 DM: Initialize TimelineEvent struct at various places
3b607857fe DM: Initialize all fields in Champion and Skill constructors to prevent uninitialized reads, CID 1370905
7f5a460139 DM: Change setMap signature to update mapTime in-place. CID 1363213
f607078faa DM: Initialize door native bitmap index arrays in DisplayMan constructor. CID 1362720
d8ae431257 DM: Restrict tainted map width loop boundary while loading. CID 1362699
79db54d1fb DM: Prevent unintended sign extension
55b33192fd DM: Guard objectNames array read against negative iconIndex. CID 1362684
3fc33dead4 DM: Prevent unsigned loop index underflow in ObjectMan icon drawing methods
cac6756796 DM: Prevent CloseInventory index from reaching drawChampionState. CID 1362659
96ac831724 DM: Ensure iconIndex is non-negative before accessing objectNames. CID 1362655
55ea61cf27 DM: Guard damage application against negative target champion indices. CID 1362651
fe60c74bc9 DM: Guard destination map index against negative returns in movement logic. CID 1362643
99c131b64b DM: Fix potential negative index and out-of-bounds array reads
Commit: 8a44ebe03528583d5e02a8118cc1643af396cd14
https://github.com/scummvm/scummvm/commit/8a44ebe03528583d5e02a8118cc1643af396cd14
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Fix potential out-of-bounds write in printMessageAfterReplacements. CID 1499983
Changed paths:
engines/dm/menus.cpp
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 77ee0274009..157ae8ac43e 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -1631,7 +1631,7 @@ void MenuMan::printMessageAfterReplacements(const char *str) {
*curCharacter = '\0';
size_t ln = Common::strlcat(outputString, replacementString, sizeof(outputString));
- if (ln >= sizeof(outputString)) {
+ if (ln >= sizeof(outputString) - 1) {
error("Not enough space in outputString");
}
curCharacter = outputString + ln;
Commit: e2b5b0d02b11094e3264fb49a94b4c0c440cf821
https://github.com/scummvm/scummvm/commit/e2b5b0d02b11094e3264fb49a94b4c0c440cf821
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Clip sensor group generator creature count to valid array bounds. CID 1470680
Changed paths:
engines/dm/timeline.cpp
diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp
index 388b5b62131..284ead690b6 100644
--- a/engines/dm/timeline.cpp
+++ b/engines/dm/timeline.cpp
@@ -747,6 +747,7 @@ void Timeline::processEventSquareCorridor(TimelineEvent *event) {
if (healthMultiplier == 0)
healthMultiplier = _vm->_dungeonMan->_currMap->_difficulty;
+ creatureCount = CLIP<int16>(creatureCount, 0, 3);
_vm->_groupMan->groupGetGenerated((CreatureType)curSensor->getData(), healthMultiplier, creatureCount, (Direction)_vm->getRandomNumber(4), mapX, mapY);
if (curSensor->getAttrAudibleA())
_vm->_sound->requestPlay(kDMSoundIndexBuzz, mapX, mapY, kDMSoundModePlayIfPrioritized);
Commit: 739bd0af494470e7e31a344d0911008e1f8bdbe7
https://github.com/scummvm/scummvm/commit/739bd0af494470e7e31a344d0911008e1f8bdbe7
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Remove obsolete index scaling from _boxChampionIcons lookups. CID 1470604
Changed paths:
engines/dm/eventman.cpp
diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp
index d2ac431f680..48e375f0a09 100644
--- a/engines/dm/eventman.cpp
+++ b/engines/dm/eventman.cpp
@@ -462,7 +462,7 @@ void EventManager::mouseDropChampionIcon() {
_useChampionIconOrdinalAsMousePointerBitmap = _vm->indexToOrdinal(kDMChampionNone);
_mousePointerBitmapUpdated = true;
bool useByteBoxCoordinatesBackup = displMan._useByteBoxCoordinates;
- displMan.blitToScreen(_mousePointerOriginalColorsChampionIcon, &_vm->_championMan->_boxChampionIcons[championIconIndex << 2], 16, kDMColorDarkestGray, 18);
+ displMan.blitToScreen(_mousePointerOriginalColorsChampionIcon, &_vm->_championMan->_boxChampionIcons[championIconIndex], 16, kDMColorDarkestGray, 18);
displMan._useByteBoxCoordinates = useByteBoxCoordinatesBackup;
_preventBuildPointerScreenArea = false;
}
@@ -1259,7 +1259,7 @@ void EventManager::commandProcessCommands160To162ClickInResurrectReincarnatePane
box._rect.right = box._rect.left + 66;
dispMan._useByteBoxCoordinates = false;
dispMan.fillScreenBox(box, kDMColorBlack);
- dispMan.fillScreenBox(_vm->_championMan->_boxChampionIcons[champMan.getChampionIconIndex(champ->_cell, dunMan._partyDir) * 2], kDMColorBlack);
+ dispMan.fillScreenBox(_vm->_championMan->_boxChampionIcons[champMan.getChampionIconIndex(champ->_cell, dunMan._partyDir)], kDMColorBlack);
_vm->_menuMan->drawEnabledMenus();
showMouse();
return;
Commit: 9611819899196e21a4869d983e8a55e9ef0b9e07
https://github.com/scummvm/scummvm/commit/9611819899196e21a4869d983e8a55e9ef0b9e07
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Initialize TimelineEvent struct at various places
CID 1470575, 1446535, 1446507, 1446506, 1446501, 1446499, 1446480, 1446462, 1446459,
Changed paths:
engines/dm/champion.cpp
engines/dm/group.cpp
engines/dm/inventory.cpp
engines/dm/menus.cpp
engines/dm/projexpl.cpp
engines/dm/timeline.cpp
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index ed64a76032e..ae9a095d1a9 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -930,7 +930,7 @@ void ChampionMan::disableAction(uint16 champIndex, uint16 ticks) {
Champion *curChampion = &_champions[champIndex];
int32 updatedEnableActionEventTime = _vm->_gameTime + ticks;
- TimelineEvent curEvent;
+ TimelineEvent curEvent = {};
curEvent._type = kDMEventTypeEnableChampionAction;
curEvent._priority = champIndex;
curEvent._Bu._slotOrdinal = 0;
@@ -1136,7 +1136,7 @@ void ChampionMan::championPoison(int16 champIndex, uint16 attack) {
if (--attack) {
curChampion->_poisonEventCount++;
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypePoisonChampion;
newEvent._priority = champIndex;
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + 36);
@@ -1464,7 +1464,7 @@ void ChampionMan::applyAndDrawPendingDamageAndWounds() {
int16 eventIndex = championPtr->_hideDamageReceivedIndex;
if (eventIndex == -1) {
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypeHideDamageReceived;
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + 5);
newEvent._priority = championIndex;
diff --git a/engines/dm/group.cpp b/engines/dm/group.cpp
index 24b7970f87b..d987e327bc6 100644
--- a/engines/dm/group.cpp
+++ b/engines/dm/group.cpp
@@ -387,7 +387,7 @@ bool GroupMan::groupIsDoorDestoryedByAttack(uint16 mapX, uint16 mapY, int16 atta
byte *curSquare = &dungeon._currMapData[mapX][mapY];
if (Square(*curSquare).getDoorState() == kDMDoorStateClosed) {
if (ticks) {
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, _vm->_gameTime + ticks);
newEvent._type = kDMEventTypeDoorDestruction;
newEvent._priority = 0;
@@ -633,7 +633,7 @@ void GroupMan::processEvents29to41(int16 eventMapX, int16 eventMapY, TimelineEve
Group *curGroup = dungeon.getGroup(groupThing);
CreatureInfo creatureInfo = dungeon._creatureInfos[curGroup->_type];
/* Update the event */
- TimelineEvent nextEvent;
+ TimelineEvent nextEvent = {};
nextEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, _vm->_gameTime);
nextEvent._priority = kDMMovementTicksImmobile - creatureInfo._movementTicks; /* The fastest creatures (with small MovementTicks value) get higher event priority */
nextEvent._Bu._location._mapX = eventMapX;
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index 0326e9445e9..1c0006ff1f0 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -977,7 +977,7 @@ void InventoryMan::clickOnMouth() {
adjustedPotionPower >>= 2;
curChampion->_shieldDefense += adjustedPotionPower;
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypeChampionShield;
newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + (adjustedPotionPower * adjustedPotionPower));
newEvent._priority = championIndex;
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 157ae8ac43e..8c865f6e78e 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -592,7 +592,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) {
championMan.isProjectileSpellCast(champIndex, Thing(curSpell->getType() + _vm->_thingFirstExplosion.toUint16()), CLIP((powerSymbolOrdinal + 2) * (4 + (skillLevel << 1)), 21, 255), 0);
break;
case kDMSpellKindOther: {
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._priority = 0;
uint16 spellPower = (powerSymbolOrdinal + 1) << 2;
uint16 ticks;
@@ -830,7 +830,7 @@ Potion *MenuMan::getEmptyFlaskInHand(Champion *champ, Thing *potionThing) {
}
void MenuMan::createEvent70_light(int16 lightPower, int16 ticks) {
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypeLight;
newEvent._Bu._lightPower = lightPower;
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + ticks);
@@ -854,7 +854,7 @@ bool MenuMan::isPartySpellOrFireShieldSuccessful(Champion *champ, bool spellShie
}
ChampionMan &championMan = *_vm->_championMan;
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._Bu._defense = ticks >> 5;
if (spellShield) {
newEvent._type = kDMEventTypeSpellShield;
@@ -1300,7 +1300,7 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) {
break;
case kDMActionWindow: {
int16 windowTicks = _vm->getRandomNumber(championMan.getSkillLevel(champIndex, actionSkillIndex) + 8) + 5;
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._priority = 0;
newEvent._type = kDMEventTypeThievesEye;
newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + windowTicks);
diff --git a/engines/dm/projexpl.cpp b/engines/dm/projexpl.cpp
index 06b91401581..119e2ecc10b 100644
--- a/engines/dm/projexpl.cpp
+++ b/engines/dm/projexpl.cpp
@@ -55,7 +55,7 @@ void ProjExpl::createProjectile(Thing thing, int16 mapX, int16 mapY, uint16 cell
projectilePtr->_kineticEnergy = MIN((int16)kineticEnergy, (int16)255);
projectilePtr->_attack = attack;
_vm->_dungeonMan->linkThingToList(projectileThing, Thing(0xFFFF), mapX, mapY); /* Projectiles are added on the square and not 'moved' onto the square. In the case of a projectile launcher sensor, this means that the new projectile traverses the square in front of the launcher without any trouble: there is no impact if it is a wall, the projectile direction is not changed if it is a teleporter. Impacts with creatures and champions are still processed */
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, _vm->_gameTime + 1);
if (_createLauncherProjectile)
newEvent._type = kDMEventTypeMoveProjectile; /* Launcher projectiles can impact immediately */
diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp
index 284ead690b6..fc7dc66da8a 100644
--- a/engines/dm/timeline.cpp
+++ b/engines/dm/timeline.cpp
@@ -761,7 +761,7 @@ void Timeline::processEventSquareCorridor(TimelineEvent *event) {
if (actionTicks > 127)
actionTicks = (actionTicks - 126) << 6;
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypeEnableGroupGenerator;
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, _vm->_gameTime + actionTicks);
newEvent._priority = 0;
@@ -914,7 +914,7 @@ void Timeline::processEventLight(TimelineEvent *event) {
}
_vm->_championMan->_party._magicalLightAmount += lightAmount;
if (weakerLightPower) {
- TimelineEvent newEvent;
+ TimelineEvent newEvent = {};
newEvent._type = kDMEventTypeLight;
newEvent._Bu._lightPower = weakerLightPower;
newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + 4);
Commit: 3b607857fe9a15927b703179600c748b23b6117a
https://github.com/scummvm/scummvm/commit/3b607857fe9a15927b703179600c748b23b6117a
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Initialize all fields in Champion and Skill constructors to prevent uninitialized reads, CID 1370905
Changed paths:
engines/dm/champion.h
diff --git a/engines/dm/champion.h b/engines/dm/champion.h
index 00eaee597a4..bf076e692af 100644
--- a/engines/dm/champion.h
+++ b/engines/dm/champion.h
@@ -392,6 +392,7 @@ public:
int16 _temporaryExperience;
int32 _experience;
+ Skill() : _temporaryExperience(0), _experience(0) {}
void resetToZero() { _temporaryExperience = _experience = 0; }
}; // @ SKILL
@@ -430,7 +431,18 @@ public:
int16 _shieldDefense;
byte _portrait[928]; // 32 x 29 pixel portrait
- Champion() {}
+ Champion() : _vm(nullptr), _attributes(0), _wounds(0), _dir(kDMDirNorth), _cell(kDMViewCellFronLeft),
+ _actionIndex(kDMActionN), _symbolStep(0), _directionMaximumDamageReceived(0),
+ _maximumDamageReceived(0), _poisonEventCount(0), _enableActionEventIndex(0),
+ _hideDamageReceivedIndex(0), _currHealth(0), _maxHealth(0), _currStamina(0),
+ _maxStamina(0), _currMana(0), _maxMana(0), _actionDefense(0), _food(0), _water(0),
+ _load(0), _shieldDefense(0) {
+ memset(_statistics, 0, sizeof(_statistics));
+ memset(_name, '\0', sizeof(_name));
+ memset(_title, '\0', sizeof(_title));
+ memset(_symbols, '\0', sizeof(_symbols));
+ memset(_portrait, 0, sizeof(_portrait));
+ }
void setVm(DMEngine *vm) { _vm = vm; }
Thing &getSlot(ChampionSlot slot) { return _slots[slot]; }
Commit: 7f5a46013924b633d91179574bd055433ff22608
https://github.com/scummvm/scummvm/commit/7f5a46013924b633d91179574bd055433ff22608
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Change setMap signature to update mapTime in-place. CID 1363213
The code called setMap to update the event's _mapTime, but the return value was ignored; changed the signature to update it in-place to match the original macro behavior.
Changed paths:
engines/dm/dm.cpp
engines/dm/dm.h
diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp
index 5f2bcf7e8fd..7e057a4b4b1 100644
--- a/engines/dm/dm.cpp
+++ b/engines/dm/dm.cpp
@@ -105,8 +105,9 @@ uint16 DMEngine::getMap(int32 mapTime) {
return ((uint16)(mapTime >> 24));
}
-int32 DMEngine::setMap(int32 mapTime, uint32 map) {
- return ((mapTime & 0x00FFFFFF) | (map << 24));
+int32 DMEngine::setMap(int32 &mapTime, uint32 map) {
+ mapTime = ((mapTime & 0x00FFFFFF) | (map << 24));
+ return mapTime;
}
Thing DMEngine::thingWithNewCell(Thing thing, int16 cell) {
diff --git a/engines/dm/dm.h b/engines/dm/dm.h
index de874d2de87..431da797a27 100644
--- a/engines/dm/dm.h
+++ b/engines/dm/dm.h
@@ -221,7 +221,7 @@ public:
uint16 getMap(int32 mapTime); // @ M29_MAP
Thing thingWithNewCell(Thing thing, int16 cell); // @ M15_THING_WITH_NEW_CELL
int16 getDistance(int16 mapx1, int16 mapy1, int16 mapx2, int16 mapy2); // @ M38_DISTANCE
- int32 setMap(int32 mapTime, uint32 map); // @ M31_setMap
+ int32 setMap(int32 &mapTime, uint32 map); // @ M31_setMap
private:
Commit: f607078faadc29a6c8f0b27aedde2ec806c34554
https://github.com/scummvm/scummvm/commit/f607078faadc29a6c8f0b27aedde2ec806c34554
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Initialize door native bitmap index arrays in DisplayMan constructor. CID 1362720
Changed paths:
engines/dm/gfx.cpp
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index c98d4019290..92300180143 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -151,6 +151,27 @@ DisplayMan::DisplayMan(DMEngine *dmEngine) : _vm(dmEngine) {
_paletteSwitchingEnabled = false;
_dungeonViewPaletteIndex = 0;
+ _stairsNativeBitmapIndexUpFrontD3L = 0;
+ _stairsNativeBitmapIndexUpFrontD3C = 0;
+ _stairsNativeBitmapIndexUpFrontD2L = 0;
+ _stairsNativeBitmapIndexUpFrontD2C = 0;
+ _stairsNativeBitmapIndexUpFrontD1L = 0;
+ _stairsNativeBitmapIndexUpFrontD1C = 0;
+ _stairsNativeBitmapIndexUpFrontD0CLeft = 0;
+ _stairsNativeBitmapIndexDownFrontD3L = 0;
+ _stairsNativeBitmapIndexDownFrontD3C = 0;
+ _stairsNativeBitmapIndexDownFrontD2L = 0;
+ _stairsNativeBitmapIndexDownFrontD2C = 0;
+ _stairsNativeBitmapIndexDownFrontD1L = 0;
+ _stairsNativeBitmapIndexDownFrontD1C = 0;
+ _stairsNativeBitmapIndexDownFrontD0CLeft = 0;
+ _stairsNativeBitmapIndexSideD2L = 0;
+ _stairsNativeBitmapIndexUpSideD1L = 0;
+ _stairsNativeBitmapIndexDownSideD1L = 0;
+ _stairsNativeBitmapIndexSideD0L = 0;
+
+ _useFlippedWallAndFootprintsBitmap = false;
+
for (uint16 i = 0; i < 16; ++i) {
_paletteTopAndBottomScreen[i] = 0;
_paletteMiddleScreen[i] = 0;
Commit: d8ae431257dd746c449f5ab28393b3258fd982be
https://github.com/scummvm/scummvm/commit/d8ae431257dd746c449f5ab28393b3258fd982be
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Restrict tainted map width loop boundary while loading. CID 1362699
Changed paths:
engines/dm/dungeonman.cpp
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index baccc88c882..212056de1b3 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -924,7 +924,10 @@ void DungeonMan::loadDungeonFile(Common::SeekableReadStream *file) {
_dungeonMapData[i] = colFirstSquares;
byte *square = _dungeonRawMapData + _dungeonMaps[i]._rawDunDataOffset;
*colFirstSquares++ = square;
- for (uint16 w = 1; w <= _dungeonMaps[i]._width; ++w) {
+ uint16 mapWidth = _dungeonMaps[i]._width;
+ if (mapWidth > 32)
+ mapWidth = 32;
+ for (uint16 w = 1; w <= mapWidth; ++w) {
square += _dungeonMaps[i]._height + 1;
*colFirstSquares++ = square;
}
Commit: 79db54d1fbf80fbad9381d01c95b74bf30e55546
https://github.com/scummvm/scummvm/commit/79db54d1fbf80fbad9381d01c95b74bf30e55546
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Prevent unintended sign extension
CID 1362688, 1362685
Changed paths:
engines/dm/gfx.cpp
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 92300180143..58d4a6d7404 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -693,10 +693,10 @@ void DisplayMan::setUpScreens(uint16 width, uint16 height) {
_screenHeight = height;
delete[] _tmpBitmap;
delete[] _bitmapScreen;
- _bitmapScreen = new byte[_screenWidth * _screenHeight];
+ _bitmapScreen = new byte[(uint32)_screenWidth * _screenHeight];
fillScreen(kDMColorBlack);
- _tmpBitmap = new byte[_screenWidth * _screenHeight];
+ _tmpBitmap = new byte[(uint32)_screenWidth * _screenHeight];
}
@@ -1234,7 +1234,7 @@ uint16 DisplayMan::getPixelHeight(uint16 index) {
}
void DisplayMan::copyBitmapAndFlipHorizontal(byte *srcBitmap, byte *destBitmap, uint16 byteWidth, uint16 height) {
- memmove(destBitmap, srcBitmap, byteWidth * 2 * height * sizeof(byte));
+ memmove(destBitmap, srcBitmap, (size_t)byteWidth * 2 * height * sizeof(byte));
flipBitmapHorizontal(destBitmap, byteWidth, height);
}
Commit: 55b33192fd7e5e0d0229e78299d1a3366aa1b10b
https://github.com/scummvm/scummvm/commit/55b33192fd7e5e0d0229e78299d1a3366aa1b10b
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Guard objectNames array read against negative iconIndex. CID 1362684
Changed paths:
engines/dm/inventory.cpp
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index 1c0006ff1f0..ff46cf584d8 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -528,7 +528,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) {
str += " ";
str += objMan._objectNames[iconIndex];
descString = str;
- } else {
+ } else if (iconIndex >= 0) {
descString = objMan._objectNames[iconIndex];
}
Commit: 3fc33dead49e950098820b0e4bafdddc4c71d6b1
https://github.com/scummvm/scummvm/commit/3fc33dead49e950098820b0e4bafdddc4c71d6b1
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Prevent unsigned loop index underflow in ObjectMan icon drawing methods
CID 1362676,1362675. 1362671, 1362668
Changed paths:
engines/dm/objectman.cpp
diff --git a/engines/dm/objectman.cpp b/engines/dm/objectman.cpp
index acd4b9eb155..f910d3435fd 100644
--- a/engines/dm/objectman.cpp
+++ b/engines/dm/objectman.cpp
@@ -190,7 +190,8 @@ void ObjectMan::extractIconFromBitmap(uint16 iconIndex, byte *destBitmap) {
if (_iconGraphicFirstIndex[counter] > iconIndex)
break;
}
- --counter;
+ if (counter > 0)
+ --counter;
byte *iconBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(kDMGraphicIdxObjectIcons000To031 + counter);
iconIndex -= _iconGraphicFirstIndex[counter];
_vm->_displayMan->_useByteBoxCoordinates = true;
@@ -215,7 +216,8 @@ void ObjectMan::drawIconInSlotBox(uint16 slotBoxIndex, int16 iconIndex) {
if (_iconGraphicFirstIndex[iconGraphicIndex] > iconIndex)
break;
}
- iconGraphicIndex--;
+ if (iconGraphicIndex > 0)
+ iconGraphicIndex--;
byte *iconBitmap = _vm->_displayMan->getNativeBitmapOrGraphic(iconGraphicIndex + kDMGraphicIdxObjectIcons000To031);
iconIndex -= _iconGraphicFirstIndex[iconGraphicIndex];
int16 byteWidth;
Commit: cac6756796b797137297147cd710fe356216fed0
https://github.com/scummvm/scummvm/commit/cac6756796b797137297147cd710fe356216fed0
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Prevent CloseInventory index from reaching drawChampionState. CID 1362659
Changed paths:
engines/dm/inventory.cpp
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index ff46cf584d8..f6e292dca9a 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -124,6 +124,10 @@ void InventoryMan::toggleInventory(ChampionIndex championIndex) {
return;
}
}
+
+ if (championIndex == kDMChampionCloseInventory)
+ return;
+
display._useByteBoxCoordinates = false;
_inventoryChampionOrdinal = _vm->indexToOrdinal(championIndex);
if (!inventoryChampionOrdinal)
Commit: 96ac83172482d5332938f806db7ba07bfa424e9f
https://github.com/scummvm/scummvm/commit/96ac83172482d5332938f806db7ba07bfa424e9f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Ensure iconIndex is non-negative before accessing objectNames. CID 1362655
Changed paths:
engines/dm/inventory.cpp
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index f6e292dca9a..fd29a85f51e 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -526,6 +526,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) {
descString = str;
} else if ((thingType == kDMThingTypePotion)
+ && (iconIndex >= 0)
&& (iconIndex != kDMIconIndicePotionWaterFlask)
&& (champMan.getSkillLevel((ChampionIndex)_vm->ordinalToIndex(_inventoryChampionOrdinal), kDMSkillPriest) > 1)) {
str = ('_' + dungeon.getPotion(thingToDraw)->getPower() / 40);
Commit: 55ea61cf27481f365a4286ca5d7a2134951f45a6
https://github.com/scummvm/scummvm/commit/55ea61cf27481f365a4286ca5d7a2134951f45a6
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Guard damage application against negative target champion indices. CID 1362651
Changed paths:
engines/dm/eventman.cpp
diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp
index 48e375f0a09..52222f5fa4b 100644
--- a/engines/dm/eventman.cpp
+++ b/engines/dm/eventman.cpp
@@ -1021,8 +1021,10 @@ void EventManager::commandMoveParty(CommandType cmdType) {
movementArrowIdx += (_vm->_dungeonMan->_partyDir + 2);
int16 firstDamagedChampionIndex = _vm->_championMan->getTargetChampionIndex(partyMapX, partyMapY, _vm->normalizeModulo4(movementArrowIdx));
int16 secondDamagedChampionIndex = _vm->_championMan->getTargetChampionIndex(partyMapX, partyMapY, _vm->turnDirRight(movementArrowIdx));
- int16 damage = _vm->_championMan->addPendingDamageAndWounds_getDamage(firstDamagedChampionIndex, 1, kDMWoundTorso | kDMWoundLegs, kDMAttackTypeSelf);
- if (firstDamagedChampionIndex != secondDamagedChampionIndex)
+ int16 damage = 0;
+ if (firstDamagedChampionIndex >= 0)
+ damage = _vm->_championMan->addPendingDamageAndWounds_getDamage(firstDamagedChampionIndex, 1, kDMWoundTorso | kDMWoundLegs, kDMAttackTypeSelf);
+ if (secondDamagedChampionIndex >= 0 && firstDamagedChampionIndex != secondDamagedChampionIndex)
damage |= _vm->_championMan->addPendingDamageAndWounds_getDamage(secondDamagedChampionIndex, 1, kDMWoundTorso | kDMWoundLegs, kDMAttackTypeSelf);
if (damage)
Commit: fe60c74bc902d3242940d13b42c72c434e5e25ad
https://github.com/scummvm/scummvm/commit/fe60c74bc902d3242940d13b42c72c434e5e25ad
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Guard destination map index against negative returns in movement logic. CID 1362643
Changed paths:
engines/dm/movesens.cpp
diff --git a/engines/dm/movesens.cpp b/engines/dm/movesens.cpp
index b30f9df7059..228fa145f5e 100644
--- a/engines/dm/movesens.cpp
+++ b/engines/dm/movesens.cpp
@@ -228,8 +228,8 @@ bool MovesensMan::getMoveResult(Thing thing, int16 mapX, int16 mapY, int16 destM
return true; /* The specified group thing cannot be moved because it was killed by a projectile impact */
}
- uint16 mapIndexSource = 0;
- uint16 mapIndexDestination = 0;
+ int16 mapIndexSource = 0;
+ int16 mapIndexDestination = 0;
bool groupOnPartyMap = false;
bool partySquare = false;
bool audibleTeleporter = false;
@@ -317,6 +317,8 @@ bool MovesensMan::getMoveResult(Thing thing, int16 mapX, int16 mapY, int16 destM
/* BUG0_01 While drawing creatures the engine will read invalid ACTIVE_GROUP data in _vm->_groupMan->_g375_activeGroups because the data is for the creatures on the source map and not the map being drawn. The only consequence is that creatures may be drawn with incorrect bitmaps and/or directions */
}
mapIndexDestination = dungeon.getLocationAfterLevelChange(mapIndexDestination, 1, &destMapX, &destMapY);
+ if (mapIndexDestination < 0)
+ break;
dungeon.setCurrentMap(mapIndexDestination);
if (thing == _vm->_thingParty) {
dungeon._partyMapX = destMapX;
@@ -346,6 +348,8 @@ bool MovesensMan::getMoveResult(Thing thing, int16 mapX, int16 mapY, int16 destM
} else if ((destinationSquareType == (int)kDMElementTypeStairs) && (thing != _vm->_thingParty) && (thingType != kDMThingTypeProjectile)) {
if (!getFlag(destinationSquareData, kDMSquareMaskStairsUp)) {
mapIndexDestination = dungeon.getLocationAfterLevelChange(mapIndexDestination, 1, &destMapX, &destMapY);
+ if (mapIndexDestination < 0)
+ break;
dungeon.setCurrentMap(mapIndexDestination);
}
direction = dungeon.getStairsExitDirection(destMapX, destMapY);
Commit: 99c131b64bec5dac0801ec65f05118332fc5a81f
https://github.com/scummvm/scummvm/commit/99c131b64bec5dac0801ec65f05118332fc5a81f
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-07-16T15:53:24+02:00
Commit Message:
DM: Fix potential negative index and out-of-bounds array reads
CID 1470661, 1362648, 1470654, 1362633, 1470612, 1362653, 1470607, 1362638, 1470587, 1470515, 1470465, 1362646, 1362638, 1362635
Changed paths:
engines/dm/champion.cpp
engines/dm/eventman.cpp
engines/dm/inventory.cpp
engines/dm/menus.cpp
engines/dm/objectman.cpp
engines/dm/projexpl.cpp
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index ae9a095d1a9..131077e9fae 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -1348,8 +1348,11 @@ void ChampionMan::clickOnSlotBox(uint16 slotBoxIndex) {
if ((slotThing == _vm->_thingNone) && (leaderHandObject == _vm->_thingNone))
return;
- if ((leaderHandObject != _vm->_thingNone) && (!(dungeon._objectInfos[dungeon.getObjectInfoIndex(leaderHandObject)]._allowedSlots & _slotMasks[slotIndex])))
- return;
+ if (leaderHandObject != _vm->_thingNone) {
+ int16 infoIndex = dungeon.getObjectInfoIndex(leaderHandObject);
+ if (infoIndex < 0 || infoIndex >= 180 || !(dungeon._objectInfos[infoIndex]._allowedSlots & _slotMasks[slotIndex]))
+ return;
+ }
EventManager &evtMan = *_vm->_eventMan;
evtMan.showMouse();
@@ -2018,7 +2021,10 @@ void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
while (curThing != _vm->_thingEndOfList) {
ThingType thingType = curThing.getType();
if ((thingType > kDMThingTypeSensor) && (curThing.getCell() == championObjectsCell)) {
- int16 objectAllowedSlots = dungeon._objectInfos[dungeon.getObjectInfoIndex(curThing)]._allowedSlots;
+ int16 objectAllowedSlots = 0;
+ int16 infoIndex = dungeon.getObjectInfoIndex(curThing);
+ if (infoIndex >= 0 && infoIndex < 180)
+ objectAllowedSlots = dungeon._objectInfos[infoIndex]._allowedSlots;
uint16 curSlotIndex = kDMSlotReadyHand;
switch (thingType) {
case kDMThingTypeArmour: {
diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp
index 52222f5fa4b..ab20c3bdaf8 100644
--- a/engines/dm/eventman.cpp
+++ b/engines/dm/eventman.cpp
@@ -1509,9 +1509,11 @@ void EventManager::mouseProcessCommands125To128_clickOnChampionIcon(uint16 champ
} else
displMan.fillScreenBox(_vm->_championMan->_boxChampionIcons[championIconIndex], kDMColorBlack);
- _vm->_championMan->_champions[championCellIndex]._cell = (ViewCell)_vm->normalizeModulo4(champIconIndex + _vm->_dungeonMan->_partyDir);
- setFlag(_vm->_championMan->_champions[championCellIndex]._attributes, kDMAttributeIcon);
- _vm->_championMan->drawChampionState((ChampionIndex)championCellIndex);
+ if (championCellIndex >= 0) {
+ _vm->_championMan->_champions[championCellIndex]._cell = (ViewCell)_vm->normalizeModulo4(champIconIndex + _vm->_dungeonMan->_partyDir);
+ setFlag(_vm->_championMan->_champions[championCellIndex]._attributes, kDMAttributeIcon);
+ _vm->_championMan->drawChampionState((ChampionIndex)championCellIndex);
+ }
}
}
_preventBuildPointerScreenArea = false;
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index fd29a85f51e..623e7158df6 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -924,7 +924,8 @@ void InventoryMan::clickOnMouth() {
return;
Thing handThing = championMan._leaderHandObject;
- if (!getFlag(dungeon._objectInfos[dungeon.getObjectInfoIndex(handThing)]._allowedSlots, kDMMaskMouth))
+ int16 infoIndex = dungeon.getObjectInfoIndex(handThing);
+ if (infoIndex < 0 || infoIndex >= 180 || !getFlag(dungeon._objectInfos[infoIndex]._allowedSlots, kDMMaskMouth))
return;
uint16 iconIndex = _vm->_objectMan->getIconIndex(handThing);
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 8c865f6e78e..f43b6063f89 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -207,11 +207,14 @@ void MenuMan::drawActionIcon(ChampionIndex championIndex) {
IconIndice iconIndex;
if (thing == _vm->_thingNone) {
iconIndex = kDMIconIndiceActionEmptyHand;
- } else if (dungeon._objectInfos[dungeon.getObjectInfoIndex(thing)]._actionSetIndex) {
- iconIndex = _vm->_objectMan->getIconIndex(thing);
} else {
- dm.fillBitmap(bitmapIcon, kDMColorCyan, 16, 16);
- goto T0386006;
+ int16 infoIndex = dungeon.getObjectInfoIndex(thing);
+ if (infoIndex >= 0 && infoIndex < 180 && dungeon._objectInfos[infoIndex]._actionSetIndex) {
+ iconIndex = _vm->_objectMan->getIconIndex(thing);
+ } else {
+ dm.fillBitmap(bitmapIcon, kDMColorCyan, 16, 16);
+ goto T0386006;
+ }
}
_vm->_objectMan->extractIconFromBitmap(iconIndex, bitmapIcon);
dm.blitToBitmapShrinkWithPalChange(bitmapIcon, bitmapIcon, 16, 16, 16, 16, palChangesActionAreaObjectIcon);
@@ -1702,13 +1705,15 @@ void MenuMan::processCommands116To119_setActingChampion(uint16 champIndex) {
DungeonMan &dungeon = *_vm->_dungeonMan;
- uint16 actionSetIndex;
+ uint16 actionSetIndex = 0;
Thing slotActionThing = curChampion->_slots[kDMSlotActionHand];
if (slotActionThing == _vm->_thingNone)
actionSetIndex = 2; /* Actions Punch, Kick and War Cry */
else {
- actionSetIndex = dungeon._objectInfos[dungeon.getObjectInfoIndex(slotActionThing)]._actionSetIndex;
+ int16 infoIndex = dungeon.getObjectInfoIndex(slotActionThing);
+ if (infoIndex >= 0 && infoIndex < 180)
+ actionSetIndex = dungeon._objectInfos[infoIndex]._actionSetIndex;
if (actionSetIndex == 0)
return;
}
diff --git a/engines/dm/objectman.cpp b/engines/dm/objectman.cpp
index f910d3435fd..c07d4de5279 100644
--- a/engines/dm/objectman.cpp
+++ b/engines/dm/objectman.cpp
@@ -135,8 +135,10 @@ IconIndice ObjectMan::getObjectType(Thing thing) {
return kDMIconIndiceNone;
int16 objectInfoIndex = _vm->_dungeonMan->getObjectInfoIndex(thing);
- if (objectInfoIndex != -1)
+ if (objectInfoIndex >= 0 && objectInfoIndex < 180)
objectInfoIndex = _vm->_dungeonMan->_objectInfos[objectInfoIndex]._type;
+ else
+ objectInfoIndex = kDMIconIndiceNone;
return (IconIndice)objectInfoIndex;
}
@@ -239,6 +241,9 @@ void ObjectMan::drawIconInSlotBox(uint16 slotBoxIndex, int16 iconIndex) {
void ObjectMan::drawLeaderObjectName(Thing thing) {
Common::String objectName;
int16 iconIndex = getIconIndex(thing);
+ if (iconIndex < 0)
+ return;
+
if (iconIndex == kDMIconIndiceJunkChampionBones) {
Junk *junk = _vm->_dungeonMan->getJunk(thing);
Common::String champBonesName;
diff --git a/engines/dm/projexpl.cpp b/engines/dm/projexpl.cpp
index 119e2ecc10b..fcf787a1099 100644
--- a/engines/dm/projexpl.cpp
+++ b/engines/dm/projexpl.cpp
@@ -133,7 +133,9 @@ bool ProjExpl::hasProjectileImpactOccurred(int16 impactType, int16 mapXCombo, in
return false;
} else {
int16 associatedThingIndex = _vm->_dungeonMan->getObjectInfoIndex(projectileAssociatedThing);
- uint16 associatedAllowedSlots = _vm->_dungeonMan->_objectInfos[associatedThingIndex].getAllowedSlots();
+ uint16 associatedAllowedSlots = 0;
+ if (associatedThingIndex >= 0 && associatedThingIndex < 180)
+ associatedAllowedSlots = _vm->_dungeonMan->_objectInfos[associatedThingIndex].getAllowedSlots();
int16 iconIndex = _vm->_objectMan->getIconIndex(projectileAssociatedThing);
if ((projectileThingData->_attack > _vm->getRandomNumber(128))
More information about the Scummvm-git-logs
mailing list