[Scummvm-git-logs] scummvm master -> a3c3a22c422b9baeb6fdfaaba4a1f5dc788758a0
neuromancer
noreply at scummvm.org
Mon Jun 29 08:19:55 UTC 2026
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
7131be79f2 SCUMM: RA2: avoid a potential memory corruption (CID 1660738)
af32cea4c9 SCUMM: RA2: avoid a potential integer overflow (CID 1660810)
2fbf4fdc98 SCUMM: RA2: fixed an uninitilized variable (CID 1660805)
eeda392320 SCUMM: RA2: added missing fork in the L7
efd3fe7f90 FREESCAPE: fixed potential oob memory access
fcab8348c3 FREESCAPE: fixed integer truncation (CID 1645205)
48399626a7 COLONY: fixed potential oob read (CID 1653437)
2983124637 COLONY: fixed potential oob read (CID 1653428)
8dd6e6f9fb EEM: fixed potential oob read (CID 1660808)
a3c3a22c42 EEM: fixed potential oob read (CID 1660817)
Commit: 7131be79f2f3227f85675fc4d2411f83e148315a
https://github.com/scummvm/scummvm/commit/7131be79f2f3227f85675fc4d2411f83e148315a
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:35+02:00
Commit Message:
SCUMM: RA2: avoid a potential memory corruption (CID 1660738)
Changed paths:
engines/scumm/insane/rebel2/iact.cpp
diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp
index 3e9b985f83e..a6e5c212e38 100644
--- a/engines/scumm/insane/rebel2/iact.cpp
+++ b/engines/scumm/insane/rebel2/iact.cpp
@@ -2078,12 +2078,17 @@ void InsaneRebel2::iactRebel2Opcode9(byte *renderBitmap, Common::SeekableReadStr
if (ch == '^' && i + 1 < srcLen) {
byte next = (byte)textStr[i + 1];
if (next == 'f' && i + 3 < srcLen) {
+ // Reserve room for the escape bytes plus the terminating NUL.
+ if (dstIdx + 4 > (int)sizeof(convertedText) - 1)
+ break;
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i];
continue;
} else if (next == 'c' && i + 4 < srcLen) {
+ if (dstIdx + 5 > (int)sizeof(convertedText) - 1)
+ break;
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i++];
@@ -2091,6 +2096,8 @@ void InsaneRebel2::iactRebel2Opcode9(byte *renderBitmap, Common::SeekableReadStr
convertedText[dstIdx++] = textStr[i];
continue;
} else if (next == 'l') {
+ if (dstIdx + 2 > (int)sizeof(convertedText) - 1)
+ break;
convertedText[dstIdx++] = textStr[i++];
convertedText[dstIdx++] = textStr[i];
continue;
Commit: af32cea4c9a7a7790911389d649fc86202d909cb
https://github.com/scummvm/scummvm/commit/af32cea4c9a7a7790911389d649fc86202d909cb
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:35+02:00
Commit Message:
SCUMM: RA2: avoid a potential integer overflow (CID 1660810)
Changed paths:
engines/scumm/smush/rebel/font_rebel2.cpp
diff --git a/engines/scumm/smush/rebel/font_rebel2.cpp b/engines/scumm/smush/rebel/font_rebel2.cpp
index 97b5f29136f..77f2733eeaf 100644
--- a/engines/scumm/smush/rebel/font_rebel2.cpp
+++ b/engines/scumm/smush/rebel/font_rebel2.cpp
@@ -365,7 +365,12 @@ void Rebel2NutRenderer::loadRebel2Font(const char *filename) {
offset = (uint32)nextOffset;
int width = READ_LE_UINT16(dataSrc + offset + 14);
_fontHeight = READ_LE_UINT16(dataSrc + offset + 16);
- decodedLength += width * _fontHeight;
+ const uint64 pixels = (uint64)width * _fontHeight;
+ if (pixels > kRebel2MaxSpritePixels || decodedLength + pixels > kRebel2MaxDecodedSpriteBytes) {
+ warning("Rebel2NutRenderer::loadRebel2Font(%s) invalid glyph dimensions %dx%d at char %d, clamping", filename, width, _fontHeight, l);
+ break;
+ }
+ decodedLength += (uint32)pixels;
}
if (l < _numChars)
@@ -413,9 +418,10 @@ void Rebel2NutRenderer::loadRebel2Font(const char *filename) {
_chars[l].height = READ_LE_UINT16(dataSrc + offset + 16);
_chars[l].src = decodedPtr;
- decodedPtr += (_chars[l].width * _chars[l].height);
+ const uint32 pixels = (uint32)_chars[l].width * _chars[l].height;
+ decodedPtr += pixels;
- memset(_chars[l].src, kDefaultTransparentColor, _chars[l].width * _chars[l].height);
+ memset(_chars[l].src, kDefaultTransparentColor, pixels);
_chars[l].transparency = kDefaultTransparentColor;
const uint8 *fobjptr = dataSrc + offset + 22;
Commit: 2fbf4fdc98abafd0b3e228751d141c177b71e6e0
https://github.com/scummvm/scummvm/commit/2fbf4fdc98abafd0b3e228751d141c177b71e6e0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:35+02:00
Commit Message:
SCUMM: RA2: fixed an uninitilized variable (CID 1660805)
Changed paths:
engines/scumm/insane/rebel2/iact.cpp
diff --git a/engines/scumm/insane/rebel2/iact.cpp b/engines/scumm/insane/rebel2/iact.cpp
index a6e5c212e38..3e4eef11df8 100644
--- a/engines/scumm/insane/rebel2/iact.cpp
+++ b/engines/scumm/insane/rebel2/iact.cpp
@@ -2190,6 +2190,7 @@ void InsaneRebel2::initEnemyStruct(int id, int32 x, int32 y, int32 w, int32 h, b
e.active = active;
e.destroyed = destroyed;
e.explosionFrame = explosionFrame;
+ e.explosionComplete = false;
e.savedBackground = nullptr;
e.savedBgWidth = 0;
e.savedBgHeight = 0;
Commit: eeda392320acb3ff45eba21cc84578f53c2e44e8
https://github.com/scummvm/scummvm/commit/eeda392320acb3ff45eba21cc84578f53c2e44e8
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
SCUMM: RA2: added missing fork in the L7
Changed paths:
engines/scumm/insane/rebel2/rebel.cpp
engines/scumm/insane/rebel2/rebel.h
engines/scumm/insane/rebel2/render.cpp
engines/scumm/insane/rebel2/runlevels.cpp
diff --git a/engines/scumm/insane/rebel2/rebel.cpp b/engines/scumm/insane/rebel2/rebel.cpp
index 9ce4d44b269..3903f0b3f04 100644
--- a/engines/scumm/insane/rebel2/rebel.cpp
+++ b/engines/scumm/insane/rebel2/rebel.cpp
@@ -439,6 +439,8 @@ InsaneRebel2::InsaneRebel2(ScummEngine_v7 *scumm) {
_flyOverlayRepeatCount = 0;
_flyShipScreenX = 0xd4;
_flyShipScreenY = 0x82;
+ _level7ForkActive = false;
+ _level7TookRightFork = false;
_smoothedVelocity = 0;
_verticalInput = 0;
memset(_velocityHistory, 0, sizeof(_velocityHistory));
diff --git a/engines/scumm/insane/rebel2/rebel.h b/engines/scumm/insane/rebel2/rebel.h
index 804f06b2c00..f4ccbf1b8d1 100644
--- a/engines/scumm/insane/rebel2/rebel.h
+++ b/engines/scumm/insane/rebel2/rebel.h
@@ -639,6 +639,7 @@ public:
void checkHandler7RightBoundary(const CollisionZone &zone, int16 hMargin, int wallDamage);
void checkHandler7BoundaryZones(uint16 &warningMask);
void renderHandler7WarningCues(byte *renderBitmap, int pitch, int width, int height, int32 curFrame, uint16 warningMask);
+ void updateLevel7Fork(int32 curFrame);
int16 _playerDamage;
int16 _playerShield;
@@ -816,6 +817,10 @@ public:
int16 _flyShipScreenX;
int16 _flyShipScreenY;
+ // Level 7 (handler-7 flight) corridor fork: 07PLAY -> 07PLAYB right branch.
+ bool _level7ForkActive; // armed only while 07PLAY is playing
+ bool _level7TookRightFork; // sampled at frame 0x638: ship on the right half
+
int16 _smoothedVelocity;
int16 _verticalInput;
int16 _velocityHistory[25];
diff --git a/engines/scumm/insane/rebel2/render.cpp b/engines/scumm/insane/rebel2/render.cpp
index 5f4af086950..ddaa6bf2aa6 100644
--- a/engines/scumm/insane/rebel2/render.cpp
+++ b/engines/scumm/insane/rebel2/render.cpp
@@ -2110,6 +2110,22 @@ void InsaneRebel2::updatePostRenderDeath() {
}
}
+void InsaneRebel2::updateLevel7Fork(int32 curFrame) {
+ // Level 7 (TIE-fighter flight) forks at frame 0x638: if the ship is on the
+ // right half of the corridor (_flyShipScreenX past the 0xd4 center, matching
+ // the original's DAT_0047ab8c test), stop 07PLAY here so the alternate
+ // 07PLAYB segment can splice in. The left half plays 07PLAY through to its
+ // end. Sampled exactly once (the active flag is its own one-shot guard).
+ if (!_level7ForkActive || curFrame < 0x638)
+ return;
+
+ _level7ForkActive = false;
+ if (_flyShipScreenX > 0xd4) {
+ _level7TookRightFork = true;
+ _vm->_smushVideoShouldFinish = true;
+ }
+}
+
void InsaneRebel2::renderPostRenderMenuCursor(byte *renderBitmap, int pitch, int width, int height) {
static const byte kRa2MenuCursor[] = {
0, 0, 1, 1, 1, 1, 1,
@@ -2390,6 +2406,7 @@ void InsaneRebel2::procPostRendering(byte *renderBitmap, int32 codecparam, int32
updatePostRenderScroll(width, height);
updatePostRenderDeath();
+ updateLevel7Fork(curFrame);
// End the looping attack-run segment once the shield/reactor is destroyed.
if (_rebelShieldGateActive) {
diff --git a/engines/scumm/insane/rebel2/runlevels.cpp b/engines/scumm/insane/rebel2/runlevels.cpp
index 2fa6af8f705..e6aaec7d7a6 100644
--- a/engines/scumm/insane/rebel2/runlevels.cpp
+++ b/engines/scumm/insane/rebel2/runlevels.cpp
@@ -887,8 +887,6 @@ int InsaneRebel2::runLevel6() {
}
int InsaneRebel2::runLevel7() {
- bool reachedFork = false;
-
playCinematic("LEV07/07CUT.SAN");
if (_vm->shouldQuit())
return kLevelQuit;
@@ -903,25 +901,43 @@ int InsaneRebel2::runLevel7() {
_playerShield = 255;
_playerDamage = 0;
_deathFrame = 0;
- reachedFork = false;
+ _level7TookRightFork = false;
resetExplosions();
clearBit(0);
_rebelKillCounter = 0;
_rebelHitCounter = 0;
- if (!playLevelSegment("LEV07/07PLAY.SAN", 0x28))
+ // The corridor forks at frame 0x638. updateLevel7Fork() is armed only
+ // during 07PLAY: if the player is on the right half there, it stops this
+ // segment (so 07PLAYB can splice in) and sets _level7TookRightFork; the
+ // left half plays 07PLAY through to its end.
+ _level7ForkActive = true;
+ const bool playOk = playLevelSegment("LEV07/07PLAY.SAN", 0x28);
+ _level7ForkActive = false;
+ if (!playOk)
return kLevelQuit;
+ // Right fork: continue into the alternate corridor segment (0x40 =
+ // continuation, so the ship position carries over instead of recentering).
+ if (_level7TookRightFork && _playerShield > 0) {
+ if (!playLevelSegment("LEV07/07PLAYB.SAN", 0x68))
+ return kLevelQuit;
+ }
+
if (_playerShield > 0) {
- debugC(DEBUG_INSANE, "Level 7 completed!");
- playLevelEnd(7, -1, _rebelHitCounter, !reachedFork);
+ debugC(DEBUG_INSANE, "Level 7 completed! fork=%d", _level7TookRightFork);
+ playLevelEnd(7, -1, _rebelHitCounter, !_level7TookRightFork);
_levelUnlocked[7] = true;
return kLevelNextLevel;
}
- debugC(DEBUG_INSANE, "Level 7 death at frame %d, fork=%d", _deathFrame, reachedFork);
- if (reachedFork) {
+ // Death cinematic depends on which corridor side the player died on
+ // (the original keys 07DIE_B/07DIE_A on DAT_0047ab8c), independent of
+ // the fork frame; taking the right fork implies the right side.
+ const bool diedOnRight = _level7TookRightFork || (_flyShipScreenX > 0xd4);
+ debugC(DEBUG_INSANE, "Level 7 death at frame %d, right=%d", _deathFrame, diedOnRight);
+ if (diedOnRight) {
playCinematic("LEV07/07DIE_B.SAN");
} else {
playCinematic("LEV07/07DIE_A.SAN");
Commit: efd3fe7f903ae99b1a164581ecd4b6a1acdb7b69
https://github.com/scummvm/scummvm/commit/efd3fe7f903ae99b1a164581ecd4b6a1acdb7b69
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
FREESCAPE: fixed potential oob memory access
Changed paths:
engines/freescape/unpack.cpp
diff --git a/engines/freescape/unpack.cpp b/engines/freescape/unpack.cpp
index 31c177e8bbb..c22dd7cbeee 100644
--- a/engines/freescape/unpack.cpp
+++ b/engines/freescape/unpack.cpp
@@ -190,14 +190,15 @@ unsigned char *create_reloc_table(struct memstream *ms, struct dos_header *dh, s
if (msread(ms, &entry, sizeof(unsigned short)) != sizeof(unsigned short)) {
debug("msread failed");
}
- if (reloc_position >= *reloc_table_size) {
- debug("overflow");
+ // The relocation counts are read from the (untrusted) packed file,
+ // so their sum can exceed the header-derived table size. Stop before
+ // writing past the end of buf_reloc rather than overflowing it.
+ if (reloc_position + 2 * sizeof(unsigned short) > *reloc_table_size) {
+ debug("relocation table overflow, truncating");
+ break;
}
*(unsigned short*)(buf_reloc + reloc_position) = entry;
reloc_position += 2;
- if (reloc_position >= *reloc_table_size) {
- debug("overflow");
- }
*(unsigned short*)(buf_reloc + reloc_position) = (i * 0x1000) & 0xFFFF;
reloc_position += 2;
}
Commit: fcab8348c3e2da5662fae2155ad7da597606df53
https://github.com/scummvm/scummvm/commit/fcab8348c3e2da5662fae2155ad7da597606df53
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
FREESCAPE: fixed integer truncation (CID 1645205)
Changed paths:
engines/freescape/sound/amiga.cpp
diff --git a/engines/freescape/sound/amiga.cpp b/engines/freescape/sound/amiga.cpp
index 463c8ecb556..ee104b6b27b 100644
--- a/engines/freescape/sound/amiga.cpp
+++ b/engines/freescape/sound/amiga.cpp
@@ -309,7 +309,7 @@ private:
}
}
- double durationSec = (dmaCount + 1) * bufSize * _periodShadow[0] / Audio::Paula::kPalPaulaClock;
+ double durationSec = (double)(dmaCount + 1) * bufSize * _periodShadow[0] / Audio::Paula::kPalPaulaClock;
_dmaCounter = (int)(durationSec * 50.0) + 1;
_dmaAud0Active = true;
enableChannel(0);
Commit: 48399626a770be425cece978947ed065fb40d67e
https://github.com/scummvm/scummvm/commit/48399626a770be425cece978947ed065fb40d67e
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
COLONY: fixed potential oob read (CID 1653437)
Changed paths:
engines/colony/interaction.cpp
diff --git a/engines/colony/interaction.cpp b/engines/colony/interaction.cpp
index 57709656628..bd6ad01bd42 100644
--- a/engines/colony/interaction.cpp
+++ b/engines/colony/interaction.cpp
@@ -136,7 +136,7 @@ void ColonyEngine::interactWithObject(int objNum) {
_carryPatch[1].xloc = 1;
_carryPatch[1].yloc = 1;
_carryPatch[1].ang = 1;
- newPatch(kObjTeleport, from, _carryPatch[1], _mapData[from.xindex][from.yindex][4]);
+ newPatch(kObjTeleport, from, _carryPatch[1], _mapData[CLIP<int>(from.xindex, 0, 30)][CLIP<int>(from.yindex, 0, 30)][4]);
_carryType = kObjTeleport;
_robotArray[obj.where.xindex][obj.where.yindex] = 0;
_objects[objNum - 1].alive = 0;
@@ -230,7 +230,7 @@ void ColonyEngine::interactWithObject(int objNum) {
_carryPatch[0].xloc = 0;
_carryPatch[0].yloc = 0;
_carryPatch[0].ang = 0;
- newPatch(kObjForkLift, from, _carryPatch[0], _mapData[from.xindex][from.yindex][4]);
+ newPatch(kObjForkLift, from, _carryPatch[0], _mapData[CLIP<int>(from.xindex, 0, 30)][CLIP<int>(from.yindex, 0, 30)][4]);
_robotArray[obj.where.xindex][obj.where.yindex] = 0;
_objects[objNum - 1].alive = 0;
_me.look = _me.ang = obj.where.ang;
@@ -263,7 +263,7 @@ void ColonyEngine::interactWithObject(int objNum) {
_carryPatch[1].xloc = 1;
_carryPatch[1].yloc = 1;
_carryPatch[1].ang = 1;
- newPatch(obj.type, from, _carryPatch[1], _mapData[from.xindex][from.yindex][4]);
+ newPatch(obj.type, from, _carryPatch[1], _mapData[CLIP<int>(from.xindex, 0, 30)][CLIP<int>(from.yindex, 0, 30)][4]);
_carryType = obj.type;
_robotArray[obj.where.xindex][obj.where.yindex] = 0;
_objects[objNum - 1].alive = 0;
Commit: 29831246374ca836391e94db700f53c74cb2a5ad
https://github.com/scummvm/scummvm/commit/29831246374ca836391e94db700f53c74cb2a5ad
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
COLONY: fixed potential oob read (CID 1653428)
Changed paths:
engines/colony/think.cpp
diff --git a/engines/colony/think.cpp b/engines/colony/think.cpp
index 3c4233c0637..c7f75a1b038 100644
--- a/engines/colony/think.cpp
+++ b/engines/colony/think.cpp
@@ -586,7 +586,10 @@ void ColonyEngine::snoopThink(int num) {
}
case kOpcodeSnoop: {
- const int target = trailTargetAngle(_dirXY[obj.where.xindex][obj.where.yindex]);
+ int target = -1;
+ if (obj.where.xindex >= 0 && obj.where.xindex < 32 &&
+ obj.where.yindex >= 0 && obj.where.yindex < 32)
+ target = trailTargetAngle(_dirXY[obj.where.xindex][obj.where.yindex]);
if (target >= 0 && obj.where.ang != target) {
const int diff = (target - obj.where.ang) & 0xFF;
if (diff < 128)
Commit: 8dd6e6f9fb51ed3b0756a3ea5b8624a7791a6f47
https://github.com/scummvm/scummvm/commit/8dd6e6f9fb51ed3b0756a3ea5b8624a7791a6f47
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
EEM: fixed potential oob read (CID 1660808)
Changed paths:
engines/eem/mystery.cpp
diff --git a/engines/eem/mystery.cpp b/engines/eem/mystery.cpp
index 2d54b907286..f385635d29d 100644
--- a/engines/eem/mystery.cpp
+++ b/engines/eem/mystery.cpp
@@ -439,6 +439,8 @@ bool Mystery::load(uint num, Common::RandomSource *rng, bool macintosh) {
const byte *susSec = (_floppyGalleryOff < _data.size())
? _data.data() + _floppyGalleryOff : nullptr;
_numSites = sitesSec ? *sitesSec : 0;
+ if (_numSites > kVisitedSiteCap)
+ _numSites = kVisitedSiteCap;
_numSuspects = susSec ? *susSec : 0;
_numCONSITEs = 0;
_numCOFFSITEs = 0;
Commit: a3c3a22c422b9baeb6fdfaaba4a1f5dc788758a0
https://github.com/scummvm/scummvm/commit/a3c3a22c422b9baeb6fdfaaba4a1f5dc788758a0
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2026-06-29T10:15:36+02:00
Commit Message:
EEM: fixed potential oob read (CID 1660817)
Changed paths:
engines/eem/graphics.cpp
diff --git a/engines/eem/graphics.cpp b/engines/eem/graphics.cpp
index 343653921a1..f283765f3cd 100644
--- a/engines/eem/graphics.cpp
+++ b/engines/eem/graphics.cpp
@@ -490,6 +490,10 @@ void EEMEngine::doHelp() {
return;
}
const uint32 hsz = hf.size();
+ // An empty help file leaves hbuf.data() null below; bail before the
+ // hd[0] read so it cannot dereference null.
+ if (hsz == 0)
+ return;
Common::Array<byte> hbuf;
hbuf.resize(hsz);
if (hf.read(hbuf.data(), hsz) != hsz)
More information about the Scummvm-git-logs
mailing list