aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorColin Snover2017-01-05 14:34:55 -0600
committerColin Snover2017-01-05 16:01:05 -0600
commit0c40d60d24e2b7419999c8c05bf00458dae3489e (patch)
tree8eb3860e3612f7929f3acb72ebd6a4dcacd1b3d1 /engines/sci
parent70d1edf615bf997261066b1601b7af823af9ca1e (diff)
downloadscummvm-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.h25
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);
}