[Scummvm-git-logs] scummvm master -> 2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760
sev-
noreply at scummvm.org
Mon Jun 1 15:58:11 UTC 2026
This automated email contains information about 14 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
8f552fa4ef DM: Fix floor sensors failing to open closed door in Hall of Champions
72b3ad705a DM: Fix crash on save dialog selection highlight
d18af2b285 DM: Implement EventManager::highlightScreenBox()
7bce6e9e88 DM: Fix in-game save loading failing on first attempt
92a8dc48ed DM: Fix stairs transition crash in Hall of Champions
1f57def68f DM: Fix null pointer dereference when rendering creature groups
182c24df56 DM: Correct bitfield masks and sensor data setter
6aeb6b5b32 DM: Fix debugger crash on wrong spelling in 'gimme' command
7238392ca2 DM: Fix crash by correcting the order of values in CLIP
dc8e5ad33b DM: Correct evaluation order for footprint scent checks. PVS-Studio V501
3f611279e0 DM: Fix out-of-bounds read. PVS-Studio V781
22841aa24c DM: Correct sign mismatch using explicit cast. PVS-Studio V1112
e59edaa25d DM: Fix out-of-bounds pointer arithmetic. PVS-Studio V557
2f5bbc4c20 DM: Fix out-of-bounds map data access. PVS-Studio V781
Commit: 8f552fa4efbfa76203ccc229c66a2f7d4b36addc
https://github.com/scummvm/scummvm/commit/8f552fa4efbfa76203ccc229c66a2f7d4b36addc
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix floor sensors failing to open closed door in Hall of Champions
Previously, checking both open and closed door states under the kDMSensorEffectSet caused incorrect early return.
Changed paths:
engines/dm/timeline.cpp
diff --git a/engines/dm/timeline.cpp b/engines/dm/timeline.cpp
index 42cc84dea34..324de237264 100644
--- a/engines/dm/timeline.cpp
+++ b/engines/dm/timeline.cpp
@@ -482,11 +482,16 @@ void Timeline::processEventSquareDoor(TimelineEvent *event) {
if (doorState == kDMDoorStateDestroyed)
return;
- if (event->_Cu.A._effect == kDMSensorEffectToggle)
+ if (event->_Cu.A._effect == kDMSensorEffectToggle) {
event->_Cu.A._effect = (doorState == kDMDoorStateOpen) ? kDMSensorEffectClear : kDMSensorEffectSet;
- else if (event->_Cu.A._effect == kDMSensorEffectSet) {
- if ((doorState == kDMDoorStateOpen) || (doorState == kDMDoorStateClosed))
- return;
+ } else {
+ if (event->_Cu.A._effect == kDMSensorEffectSet) {
+ if (doorState == kDMDoorStateOpen)
+ return;
+ } else if (event->_Cu.A._effect == kDMSensorEffectClear) {
+ if (doorState == kDMDoorStateClosed)
+ return;
+ }
}
event->_type = kDMEventTypeDoorAnimation;
addEventGetEventIndex(event);
Commit: 72b3ad705a5e274255357b8ca00607ad84f83ce6
https://github.com/scummvm/scummvm/commit/72b3ad705a5e274255357b8ca00607ad84f83ce6
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix crash on save dialog selection highlight
Correct the order of parameter in the Box constructor
Changed paths:
engines/dm/dialog.cpp
diff --git a/engines/dm/dialog.cpp b/engines/dm/dialog.cpp
index d6478fe681f..839eaed1c02 100644
--- a/engines/dm/dialog.cpp
+++ b/engines/dm/dialog.cpp
@@ -206,7 +206,7 @@ int16 DialogMan::getChoice(uint16 choiceCount, uint16 dialogSetIndex, int16 driv
boxA._rect.bottom += 4;
evtMan.showMouse();
displMan._drawFloorAndCeilingRequested = true;
- Box boxB(0, 0, boxA._rect.right - boxA._rect.left + 3, boxA._rect.bottom - boxA._rect.top + 3);
+ Box boxB(0, boxA._rect.right - boxA._rect.left + 3, 0, boxA._rect.bottom - boxA._rect.top + 3);
displMan.blitToBitmap(displMan._bitmapScreen, displMan._bitmapViewport,
boxB, boxA._rect.left, boxA._rect.top, k160_byteWidthScreen, k160_byteWidthScreen, kDMColorNoTransparency, 200, 25);
_vm->delay(1);
Commit: d18af2b285ea1e2cdb12452ac957d154f223ed63
https://github.com/scummvm/scummvm/commit/d18af2b285ea1e2cdb12452ac957d154f223ed63
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Implement EventManager::highlightScreenBox()
This enablers move indicator highlight in game UI.
Changed paths:
engines/dm/eventman.cpp
engines/dm/eventman.h
diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp
index 03e418f6776..9a0377cc39b 100644
--- a/engines/dm/eventman.cpp
+++ b/engines/dm/eventman.cpp
@@ -1678,4 +1678,20 @@ void EventManager::highlightBoxDisable() {
}
}
+void EventManager::highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2) {
+ x1 = CLIP<int16>(x1, 0, _vm->_displayMan->_screenWidth - 1);
+ x2 = CLIP<int16>(x2, 0, _vm->_displayMan->_screenWidth - 1);
+ y1 = CLIP<int16>(y1, 0, _vm->_displayMan->_screenHeight - 1);
+ y2 = CLIP<int16>(y2, 0, _vm->_displayMan->_screenHeight - 1);
+
+ byte *screen = _vm->_displayMan->_bitmapScreen;
+ uint16 pitch = _vm->_displayMan->_screenWidth;
+
+ for (int16 y = y1; y <= y2; ++y) {
+ for (int16 x = x1; x <= x2; ++x) {
+ screen[y * pitch + x] ^= 0x0F;
+ }
+ }
+}
+
} // end of namespace DM
diff --git a/engines/dm/eventman.h b/engines/dm/eventman.h
index 2f81ce82fee..4fde15d62a6 100644
--- a/engines/dm/eventman.h
+++ b/engines/dm/eventman.h
@@ -286,7 +286,7 @@ public:
void waitForMouseOrKeyActivity(); // @ F0541_INPUT_WaitForMouseOrKeyboardActivity
void commandHighlightBoxEnable(int16 x1, int16 x2, int16 y1, int16 y2); // @ F0362_COMMAND_HighlightBoxEnable
void highlightBoxDisable(); // @ F0363_COMMAND_HighlightBoxDisable
- void highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2) { warning("STUB METHOD: highlightScreenBox"); } // @ F0006_MAIN_HighlightScreenBox
+ void highlightScreenBox(int16 x1, int16 x2, int16 y1, int16 y2); // @ F0006_MAIN_HighlightScreenBox
KeyboardInput _primaryKeyboardInputInterface[7]; // @ G0458_as_Graphic561_PrimaryKeyboardInput_Interface
KeyboardInput _secondaryKeyboardInputMovement[19]; // @ G0459_as_Graphic561_SecondaryKeyboardInput_Movement
Commit: 7bce6e9e883e12f40e6c7d0bbf8beaab1249f49a
https://github.com/scummvm/scummvm/commit/7bce6e9e883e12f40e6c7d0bbf8beaab1249f49a
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix in-game save loading failing on first attempt
Set _gameMode to kDMModeLoadSavedGame when a valid slot is loaded.
Changed paths:
engines/dm/loadsave.cpp
diff --git a/engines/dm/loadsave.cpp b/engines/dm/loadsave.cpp
index bd177faf5af..3b567325058 100644
--- a/engines/dm/loadsave.cpp
+++ b/engines/dm/loadsave.cpp
@@ -42,6 +42,9 @@
namespace DM {
LoadgameResult DMEngine::loadgame(int16 slot) {
+ if (slot >= 0)
+ _gameMode = kDMModeLoadSavedGame;
+
if (slot == -1 && _gameMode == kDMModeLoadSavedGame)
return kDMLoadgameFailure;
Commit: 92a8dc48ed958a77ef46563af53989e82c86db6d
https://github.com/scummvm/scummvm/commit/92a8dc48ed958a77ef46563af53989e82c86db6d
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix stairs transition crash in Hall of Champions
Make CreatureType strictly a 16-bit enum to prevent C++ struct padding and over-read.
Changed paths:
engines/dm/group.h
diff --git a/engines/dm/group.h b/engines/dm/group.h
index 7fd95bdb43a..cc96c8d8c70 100644
--- a/engines/dm/group.h
+++ b/engines/dm/group.h
@@ -37,7 +37,7 @@ namespace DM {
class CreatureInfo;
/* Creature types */
-enum CreatureType {
+enum CreatureType : uint16 {
kDMCreatureTypeGiantScorpion = 0, // @ C00_CREATURE_GIANT_SCORPION_SCORPION
kDMCreatureTypeSwampSlime = 1, // @ C01_CREATURE_SWAMP_SLIME_SLIME_DEVIL
kDMCreatureTypeGiggler = 2, // @ C02_CREATURE_GIGGLER
Commit: 1f57def68f9d85ce0cd5a50cadae5c6602065b07
https://github.com/scummvm/scummvm/commit/1f57def68f9d85ce0cd5a50cadae5c6602065b07
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix null pointer dereference when rendering creature groups
Changed paths:
engines/dm/gfx.cpp
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 8f4894cd016..cd0a4428ad7 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -3368,12 +3368,12 @@ T0115015_DrawProjectileAsObject:
if (group == nullptr) { /* If all creature data and info has not already been gathered */
group = (Group *)dungeon.getThingData(groupThing);
- activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()];
CreatureInfo *creatureInfo = &dungeon._creatureInfos[group->_type];
creatureAspectStruct = &_creatureAspects219[creatureInfo->_creatureAspectIndex];
creatureSize = getFlag(creatureInfo->_attributes, kDMCreatureMaskSize);
creatureGraphicInfoGreen = creatureInfo->_graphicInfo;
}
+ activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()];
objectAspect = (ObjectAspect *)creatureAspectStruct;
AL_0_creatureIndexRed = _vm->_groupMan->getCreatureOrdinalInCell(group, cellYellowBear);
Commit: 182c24df56619e8ee151e0e181db770d6c115991
https://github.com/scummvm/scummvm/commit/182c24df56619e8ee151e0e181db770d6c115991
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Correct bitfield masks and sensor data setter
Fix Sensor::setData & some getters to use correct bit masks matching the original.
Changed paths:
engines/dm/dungeonman.h
diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h
index 66ca67c61a3..59df5773c2a 100644
--- a/engines/dm/dungeonman.h
+++ b/engines/dm/dungeonman.h
@@ -354,11 +354,11 @@ public:
explicit Teleporter(uint16 *rawDat) : _nextThing(rawDat[0]), _attributes(rawDat[1]), _destMapIndex(rawDat[2]) {}
Thing getNextThing() { return _nextThing; }
bool isAudible() { return (_attributes >> 15) & 1; }
- TeleporterScope getScope() { return (TeleporterScope)((_attributes >> 13) & 1); }
+ TeleporterScope getScope() { return (TeleporterScope)((_attributes >> 13) & 3); }
bool getAbsoluteRotation() { return (_attributes >> 12) & 1; }
- Direction getRotation() { return (Direction)((_attributes >> 10) & 1); }
- byte getTargetMapY() { return (_attributes >> 5) & 0xF; }
- byte getTargetMapX() { return _attributes & 0xF; }
+ Direction getRotation() { return (Direction)((_attributes >> 10) & 3); }
+ byte getTargetMapY() { return (_attributes >> 5) & 0x1F; }
+ byte getTargetMapX() { return _attributes & 0x1F; }
uint16 getTargetMapIndex() { return _destMapIndex >> 8; }
}; // @ TELEPORTER
@@ -388,7 +388,7 @@ public:
uint16 getData() { return (_datAndType >> 7) & 0x1FF; } // @ M40_DATA
static uint16 getDataMask1(uint16 data) { return (data >> 7) & 0xF; } // @ M42_MASK1
static uint16 getDataMask2(uint16 data) { return (data >> 11) & 0xF; } // @ M43_MASK2
- void setData(uint16 dat) { _datAndType = dat; } // @ M41_SET_DATA
+ void setData(uint16 dat) { _datAndType = (_datAndType & 0x7F) | (dat << 7); } // @ M41_SET_DATA
void setTypeDisabled() { _datAndType &= 0xFF80; } // @ M44_SET_TYPE_DISABLED
bool getAttrOnlyOnce() { return (_attributes >> 2) & 1; }
Commit: 6aeb6b5b3272c3f8e8e03269f616140098391832
https://github.com/scummvm/scummvm/commit/6aeb6b5b3272c3f8e8e03269f616140098391832
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix debugger crash on wrong spelling in 'gimme' command
Changed paths:
engines/dm/console.cpp
diff --git a/engines/dm/console.cpp b/engines/dm/console.cpp
index 8d7dcfa8dfc..7372da0bb18 100644
--- a/engines/dm/console.cpp
+++ b/engines/dm/console.cpp
@@ -264,7 +264,7 @@ bool Console::Cmd_gimme(int argc, const char** argv) {
for (int16 thingIndex = 0; thingIndex < thingCount; ++thingIndex) {
dummyThing.setIndex(thingIndex);
int16 iconIndex = _vm->_objectMan->getIconIndex(dummyThing);
- if (iconIndex != -1) {
+ if (iconIndex >= 0 && iconIndex < kDMObjectNameCount) {
const char *displayName = _vm->_objectMan->_objectNames[iconIndex];
if (cstrEquals(displayName, requestedItemName.c_str())) {
uint16 *newThingData = new uint16[(thingCount + 1) * thingTypeSize];
Commit: 7238392ca2926771a81aa428e3fb51fc42d2631e
https://github.com/scummvm/scummvm/commit/7238392ca2926771a81aa428e3fb51fc42d2631e
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix crash by correcting the order of values in CLIP
Changed paths:
engines/dm/champion.cpp
engines/dm/gfx.cpp
engines/dm/menus.cpp
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index 1d2c8b518e7..21fb97016f2 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -661,7 +661,7 @@ uint16 ChampionMan::getStrength(int16 champIndex, int16 slotIndex) {
if (getFlag(curChampion->_wounds, (slotIndex == kDMSlotReadyHand) ? kDMWoundReadHand : kDMWoundActionHand))
strength >>= 1;
- return CLIP(0, strength >> 1, 100);
+ return CLIP(strength >> 1, 0, 100);
}
Thing ChampionMan::getObjectRemovedFromSlot(uint16 champIndex, uint16 slotIndex) {
@@ -883,7 +883,7 @@ int16 ChampionMan::getWoundDefense(int16 champIndex, uint16 woundIndex) {
if (_partyIsSleeping)
woundDefense >>= 1;
- return CLIP(0, woundDefense >> 1, 100);
+ return CLIP(woundDefense >> 1, 0, 100);
}
uint16 ChampionMan::getStatisticAdjustedAttack(Champion *champ, uint16 statIndex, uint16 attack) {
@@ -920,7 +920,7 @@ void ChampionMan::wakeUp() {
int16 ChampionMan::getThrowingStaminaCost(Thing thing) {
int16 weight = _vm->_dungeonMan->getObjectWeight(thing) >> 1;
- int16 staminaCost = CLIP<int16>(1, weight, 10);
+ int16 staminaCost = CLIP<int16>(weight, 1, 10);
while ((weight -= 10) > 0)
staminaCost += weight >> 1;
@@ -979,7 +979,7 @@ void ChampionMan::addSkillExperience(uint16 champIndex, uint16 skillIndex, uint1
Skill *curSkill = &curChampion->_skills[skillIndex];
curSkill->_experience += exp;
if (curSkill->_temporaryExperience < 32000)
- curSkill->_temporaryExperience += CLIP(1, exp >> 3, 100);
+ curSkill->_temporaryExperience += CLIP(exp >> 3, 1, 100);
curSkill = &curChampion->_skills[baseSkillIndex];
if (skillIndex >= kDMSkillSwing)
@@ -1121,7 +1121,7 @@ bool ChampionMan::isLucky(Champion *champ, uint16 percentage) {
unsigned char *curStat = champ->_statistics[kDMStatLuck];
bool retVal = (_vm->getRandomNumber(curStat[kDMStatCurrent]) > percentage);
- curStat[kDMStatCurrent] = CLIP<unsigned char>(curStat[kDMStatMinimum], curStat[kDMStatCurrent] + (retVal ? -2 : 2), curStat[kDMStatMaximum]);
+ curStat[kDMStatCurrent] = CLIP<unsigned char>(curStat[kDMStatCurrent] + (retVal ? -2 : 2), curStat[kDMStatMinimum], curStat[kDMStatMaximum]);
return retVal;
}
@@ -1660,7 +1660,7 @@ void ChampionMan::applyTimeEffects() {
staminaGainCycleCount += 2;
int16 staminaLoss = 0;
- int16 staminaAmount = CLIP(1, (championPtr->_maxStamina >> 8) - 1, 6);
+ int16 staminaAmount = CLIP((championPtr->_maxStamina >> 8) - 1, 1, 6);
if (_partyIsSleeping)
staminaAmount <<= 1;
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index cd0a4428ad7..41b6f422c55 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -3580,12 +3580,12 @@ T0115077_DrawSecondHalfSquareCreature:
else if (viewLane != kDMViewLaneCenter) /* Lane right */
AL_4_xPos += 100;
- boxByteGreen._rect.right = CLIP(0, AL_4_xPos + byteWidth, 223);
+ boxByteGreen._rect.right = CLIP(AL_4_xPos + byteWidth, 0, 223);
if (!boxByteGreen._rect.right)
goto T0115126_CreatureNotVisible;
int16 AL_0_creaturePosX;
- boxByteGreen._rect.left = CLIP(0, AL_4_xPos - byteWidth + 1, 223);
+ boxByteGreen._rect.left = CLIP(AL_4_xPos - byteWidth + 1, 0, 223);
if (boxByteGreen._rect.left) {
if (boxByteGreen._rect.left == 223)
goto T0115126_CreatureNotVisible;
@@ -3845,7 +3845,7 @@ T0115200_DrawExplosion:
continue;
boxByteGreen._rect.right = AL_4_xPos;
AL_4_xPos = explosionCoordinates[0];
- boxByteGreen._rect.left = CLIP(0, AL_4_xPos - byteWidth + 1, 223);
+ boxByteGreen._rect.left = CLIP(AL_4_xPos - byteWidth + 1, 0, 223);
if (boxByteGreen._rect.left)
AL_4_xPos = paddingPixelCount;
diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp
index 8747273341b..7fca0f08134 100644
--- a/engines/dm/menus.cpp
+++ b/engines/dm/menus.cpp
@@ -589,7 +589,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) {
if (curSpell->getType() == kDMSpellTypeProjectileOpenDoor)
skillLevel <<= 1;
- championMan.isProjectileSpellCast(champIndex, Thing(curSpell->getType() + _vm->_thingFirstExplosion.toUint16()), CLIP(21, (powerSymbolOrdinal + 2) * (4 + (skillLevel << 1)), 255), 0);
+ championMan.isProjectileSpellCast(champIndex, Thing(curSpell->getType() + _vm->_thingFirstExplosion.toUint16()), CLIP((powerSymbolOrdinal + 2) * (4 + (skillLevel << 1)), 21, 255), 0);
break;
case kDMSpellKindOther: {
TimelineEvent newEvent;
Commit: dc8e5ad33b3b1154fb73807c62f302281d826180
https://github.com/scummvm/scummvm/commit/dc8e5ad33b3b1154fb73807c62f302281d826180
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Correct evaluation order for footprint scent checks. PVS-Studio V501
Check footprints-allowed before assigning scent ordinal to avoid overwriting their shared memory too early, matching the original.
Changed paths:
engines/dm/dungeonman.cpp
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index b585ca68733..a989070b636 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -962,8 +962,7 @@ T0172010_ClosedFakeWall:
curThing = getNextThing(curThing);
}
- AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY);
- if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex))
+ if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY)) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex))
setFlag(aspectArray[kDMSquareAspectFloorOrn], kDMMaskFootprints);
break;
@@ -987,8 +986,7 @@ T0172010_ClosedFakeWall:
while ((curThing != _vm->_thingEndOfList) && (curThing.getType() <= kDMThingTypeSensor))
curThing = getNextThing(curThing);
- AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY);
- if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex))
+ if (AL0307_uc_FootprintsAllowed && (AL0307_uc_ScentOrdinal = championMan.getScentOrdinal(mapX, mapY)) && (--AL0307_uc_ScentOrdinal >= championMan._party._firstScentIndex) && (AL0307_uc_ScentOrdinal < championMan._party._lastScentIndex))
setFlag(aspectArray[kDMSquareAspectFloorOrn], kDMMaskFootprints);
break;
default:
Commit: 3f611279e0bc389acb00f81a51a1267ccb785674
https://github.com/scummvm/scummvm/commit/3f611279e0bc389acb00f81a51a1267ccb785674
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix out-of-bounds read. PVS-Studio V781
Move coordinates bounds checks before accessing map data to prevent crashes
Changed paths:
engines/dm/dungeonman.cpp
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index a989070b636..f6e6ea312a8 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -831,8 +831,11 @@ Square DungeonMan::getRelSquare(Direction dir, int16 stepsForward, int16 stepsRi
}
int16 DungeonMan::getSquareFirstThingIndex(int16 mapX, int16 mapY) {
+ if ((mapX < 0) || (mapX >= _currMapWidth) || (mapY < 0) || (mapY >= _currMapHeight))
+ return -1;
+
unsigned char *curSquare = _currMapData[mapX];
- if ((mapX < 0) || (mapX >= _currMapWidth) || (mapY < 0) || (mapY >= _currMapHeight) || !getFlag(curSquare[mapY], kDMSquareMaskThingListPresent))
+ if (!getFlag(curSquare[mapY], kDMSquareMaskThingListPresent))
return -1;
int16 curMapY = 0;
Commit: 22841aa24c85be7c35dc12efb783899949d3b874
https://github.com/scummvm/scummvm/commit/22841aa24c85be7c35dc12efb783899949d3b874
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Correct sign mismatch using explicit cast. PVS-Studio V1112
Changed paths:
engines/dm/champion.cpp
engines/dm/eventman.cpp
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index 21fb97016f2..436a529dae2 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -1604,7 +1604,7 @@ void ChampionMan::unpoison(int16 champIndex) {
TimelineEvent *eventPtr = _vm->_timeline->_events;
for (uint16 eventIndex = 0; eventIndex < _vm->_timeline->_eventMaxCount; eventPtr++, eventIndex++) {
- if ((eventPtr->_type == kDMEventTypePoisonChampion) && (eventPtr->_priority == champIndex))
+ if ((eventPtr->_type == kDMEventTypePoisonChampion) && ((int16)eventPtr->_priority == champIndex))
_vm->_timeline->deleteEvent(eventIndex);
}
_champions[champIndex]._poisonEventCount = 0;
diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp
index 9a0377cc39b..7515380d0df 100644
--- a/engines/dm/eventman.cpp
+++ b/engines/dm/eventman.cpp
@@ -530,7 +530,7 @@ void EventManager::buildpointerScreenArea(int16 mousePosX, int16 mousePosY) {
_mousePointerType = k4_pointerTypeAutoselect;
else {
championIdx++;
- if (championIdx == _vm->_inventoryMan->_inventoryChampionOrdinal)
+ if (championIdx == (uint16)_vm->_inventoryMan->_inventoryChampionOrdinal)
_mousePointerType = k0_pointerTypeArrow;
else if (mousePosY <= 6)
_mousePointerType = k0_pointerTypeArrow;
Commit: e59edaa25dc38e778775b95dc3980484510bc833
https://github.com/scummvm/scummvm/commit/e59edaa25dc38e778775b95dc3980484510bc833
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix out-of-bounds pointer arithmetic. PVS-Studio V557
Use row-pointer incrementing to traverse _doorButtonCoordSets safely, avoiding out-of-bounds warnings when traversing to the next sub-array in contiguous memory.
Changed paths:
engines/dm/gfx.cpp
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index 41b6f422c55..13c9c31a5c5 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -2642,10 +2642,10 @@ void DisplayMan::loadCurrentMapGraphics() {
}
for (uint16 index = kDMDerivedBitmapFirstDoorButton, counter = 0; counter < k1_DoorButtonCount; counter++) {
- uint16 *coords = _doorButtonCoordSets[_doorButtonCoordSet[counter]][1];
- _derivedBitmapByteCount[index++] = coords[4] * coords[5];
- coords += 6;
- _derivedBitmapByteCount[index++] = coords[4] * coords[5];
+ uint16 (*rowPtr)[6] = _doorButtonCoordSets[_doorButtonCoordSet[counter]] + 1;
+ _derivedBitmapByteCount[index++] = (*rowPtr)[4] * (*rowPtr)[5];
+ rowPtr++;
+ _derivedBitmapByteCount[index++] = (*rowPtr)[4] * (*rowPtr)[5];
}
applyCreatureReplColors(9, 8);
Commit: 2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760
https://github.com/scummvm/scummvm/commit/2f5bbc4c20dc1a2e6f7bbd0291dee480dd2ec760
Author: Mohit Bankar (mohitbankar1212 at gmail.com)
Date: 2026-06-01T17:57:59+02:00
Commit Message:
DM: Fix out-of-bounds map data access. PVS-Studio V781
Move the map coordinate boundary check to run before indexing dungeon._currMapData array.
Changed paths:
engines/dm/group.cpp
diff --git a/engines/dm/group.cpp b/engines/dm/group.cpp
index e268cb1028f..84bda38c9db 100644
--- a/engines/dm/group.cpp
+++ b/engines/dm/group.cpp
@@ -1105,12 +1105,14 @@ bool GroupMan::isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16
dungeon.mapCoordsAfterRelMovement((Direction)dir, 1, 0, mapX, mapY);
+ if ((mapX < 0) || (mapX >= dungeon._currMapWidth) || (mapY < 0) || (mapY >= dungeon._currMapHeight)) {
+ _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter = true;
+ return false;
+ }
uint16 curSquare = dungeon._currMapData[mapX][mapY];
int16 curSquareType = Square(curSquare).getType();
_groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter =
- !(((mapX >= 0) && (mapX < dungeon._currMapWidth)) &&
- ((mapY >= 0) && (mapY < dungeon._currMapHeight)) &&
- (curSquareType != kDMElementTypeWall) &&
+ !((curSquareType != kDMElementTypeWall) &&
(curSquareType != kDMElementTypeStairs) &&
((curSquareType != kDMElementTypePit) || (getFlag(curSquare, kDMSquareMaskPitImaginary) && allowMovementOverImaginaryPitsAndFakeWalls) || !getFlag(curSquare, kDMSquareMaskPitOpen) || getFlag(creatureInfo->_attributes, kDMCreatureMaskLevitation)) &&
((curSquareType != kDMElementTypeFakeWall) || getFlag(curSquare, kDMSquareMaskFakeWallOpen) || (getFlag(curSquare, kDMSquareMaskFakeWallImaginary) && allowMovementOverImaginaryPitsAndFakeWalls)));
More information about the Scummvm-git-logs
mailing list