diff options
author | Colin Snover | 2017-01-05 14:34:55 -0600 |
---|---|---|
committer | Colin Snover | 2017-01-05 16:01:05 -0600 |
commit | 0c40d60d24e2b7419999c8c05bf00458dae3489e (patch) | |
tree | 8eb3860e3612f7929f3acb72ebd6a4dcacd1b3d1 /engines/sci | |
parent | 70d1edf615bf997261066b1601b7af823af9ca1e (diff) | |
download | scummvm-rg350-0c40d60d24e2b7419999c8c05bf00458dae3489e.tar.gz scummvm-rg350-0c40d60d24e2b7419999c8c05bf00458dae3489e.tar.bz2 scummvm-rg350-0c40d60d24e2b7419999c8c05bf00458dae3489e.zip |
SCI32: Fix off-by-one error in array resizing
This bug existed in SSCI and was pulled in carelessly during
initial implementation of SciArray. Closer examination of SCI3
reveals that this only happened to work in SSCI because it would
always allocate on the first resize, and would always allocate 25
extra elements per allocation.
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/segment.h | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index c5295c5523..538f31170d 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -542,7 +542,14 @@ public: */ reg_t getAsID(const uint16 index) { if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // SCI3 resizes arrays automatically when out-of-bounds indices are + // passed, but it has an off-by-one error, always passing the index + // instead of `index + 1` on a read. This happens to work in SSCI + // only because the resize method there actually allocates memory + // for `index + 25` elements when growing the array, and it always + // grows the array on its first resize because it decides whether to + // grow based on byte size including an extra array header. + resize(index + 1); } else { assert(index < _size); } @@ -573,7 +580,8 @@ public: */ void setFromID(const uint16 index, const reg_t value) { if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // This code is different from SSCI; see getAsID for an explanation + resize(index + 1); } else { assert(index < _size); } @@ -599,7 +607,8 @@ public: assert(_type == kArrayTypeInt16); if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // This code is different from SSCI; see getAsID for an explanation + resize(index + 1); } else { assert(index < _size); } @@ -616,6 +625,7 @@ public: assert(_type == kArrayTypeInt16); if (getSciVersion() >= SCI_VERSION_3) { + // This code is different from SSCI; see getAsID for an explanation resize(index + 1); } else { assert(index < _size); @@ -632,7 +642,8 @@ public: assert(_type == kArrayTypeString || _type == kArrayTypeByte); if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // This code is different from SSCI; see getAsID for an explanation + resize(index + 1); } else { assert(index < _size); } @@ -648,7 +659,8 @@ public: assert(_type == kArrayTypeString || _type == kArrayTypeByte); if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // This code is different from SSCI; see getAsID for an explanation + resize(index + 1); } else { assert(index < _size); } @@ -664,7 +676,8 @@ public: assert(_type == kArrayTypeID || _type == kArrayTypeInt16); if (getSciVersion() >= SCI_VERSION_3) { - resize(index); + // This code is different from SSCI; see getAsID for an explanation + resize(index + 1); } else { assert(index < _size); } |