aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2010-09-05 14:59:09 +0000
committerJohannes Schickel2010-09-05 14:59:09 +0000
commit2a08124f0f9274dd442b7154e3b72dd981a7e2e7 (patch)
tree25ccf96b4d27797f99903b14217e59221cf8846f
parent4766cc5bb5c872e7ba7e787ec512bc16388e3b24 (diff)
downloadscummvm-rg350-2a08124f0f9274dd442b7154e3b72dd981a7e2e7.tar.gz
scummvm-rg350-2a08124f0f9274dd442b7154e3b72dd981a7e2e7.tar.bz2
scummvm-rg350-2a08124f0f9274dd442b7154e3b72dd981a7e2e7.zip
SCI: Fix bugs #3035650 and #3039566, crash in PEPPER demo and LAURABOW2.
The actual names for the bug reports are: #3035650 "PEPPER non-interactive demo: Crash" #3039566 "LAURABOW2: Crash during introduction" Those crashes were caused by an invalid memory dereference in kClone. This in turn was happening, because the parent object pointer might have been invalidated in cases where the parent object is also a clone. svn-id: r52561
-rw-r--r--engines/sci/engine/kscripts.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index d99302b3d4..7cc677cd3a 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -145,6 +145,7 @@ reg_t kResCheck(EngineState *s, int argc, reg_t *argv) {
reg_t kClone(EngineState *s, int argc, reg_t *argv) {
reg_t parent_addr = argv[0];
const Object *parent_obj = s->_segMan->getObject(parent_addr);
+ const bool parentIsClone = parent_obj->isClone();
reg_t clone_addr;
Clone *clone_obj; // same as Object*
@@ -162,6 +163,18 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
+ // In case the parent object is a clone itself we need to refresh our
+ // pointer to it here. This is because calling allocateClone might
+ // invalidate all pointers, references and iterators to data in the clones
+ // segment.
+ //
+ // The reason why it might invalidate those is, that the segement code
+ // (Table) uses Common::Array for internal storage. Common::Array now
+ // might invalidate references to its contained data, when it has to
+ // extend the internal storage size.
+ if (parentIsClone)
+ parent_obj = s->_segMan->getObject(parent_addr);
+
*clone_obj = *parent_obj;
// Mark as clone