aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/celobj32.cpp
diff options
context:
space:
mode:
authorColin Snover2016-08-28 16:23:48 -0500
committerColin Snover2016-09-29 19:39:16 -0500
commit240b0ca3488231e0cfb9c56b1c21ccdd309f0908 (patch)
tree729dbbd0a526f39f8963557e96b9e4f3c999ef97 /engines/sci/graphics/celobj32.cpp
parent1de74fa514a59fbc41fa9024d91b94ee2cc1ebb7 (diff)
downloadscummvm-rg350-240b0ca3488231e0cfb9c56b1c21ccdd309f0908.tar.gz
scummvm-rg350-240b0ca3488231e0cfb9c56b1c21ccdd309f0908.tar.bz2
scummvm-rg350-240b0ca3488231e0cfb9c56b1c21ccdd309f0908.zip
SCI32: Add a trap for invalid calls to kNumCels
Diffstat (limited to 'engines/sci/graphics/celobj32.cpp')
-rw-r--r--engines/sci/graphics/celobj32.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp
index d67a4dc03c..9019517aa5 100644
--- a/engines/sci/graphics/celobj32.cpp
+++ b/engines/sci/graphics/celobj32.cpp
@@ -812,7 +812,21 @@ int16 CelObjView::getNumCels(const GuiResourceId viewId, const int16 loopNo) {
const byte *const data = resource->data;
const uint16 loopCount = data[2];
- if (loopNo >= loopCount || loopNo < 0) {
+
+ // Every version of SCI32 has a logic error in this function that causes
+ // random memory to be read if a script requests the cel count for one
+ // past the maximum loop index. At least GK1 room 800 does this, and gets
+ // stuck in an infinite loop because the game script expects this method
+ // to return a non-zero value.
+ // The scope of this bug means it is likely to pop up in other games, so we
+ // explicitly trap the bad condition here and report it so that any other
+ // game scripts relying on this broken behavior can be fixed as well
+ if (loopNo == loopCount) {
+ const SciCallOrigin origin = g_sci->getEngineState()->getCurrentCallOrigin();
+ error("[CelObjView::getNumCels]: loop number is equal to loop count in method %s::%s (room %d, script %d, localCall %x)", origin.objectName.c_str(), origin.methodName.c_str(), origin.roomNr, origin.scriptNr, origin.localCallOffset);
+ }
+
+ if (loopNo > loopCount || loopNo < 0) {
return 0;
}