diff options
author | Willem Jan Palenstijn | 2016-02-01 20:17:17 +0100 |
---|---|---|
committer | Willem Jan Palenstijn | 2016-02-01 20:21:27 +0100 |
commit | f94153f07a69e986547391922c8aa85ab0086874 (patch) | |
tree | 2435af4a301d8bb99ad26cd53e6ac08441c57196 | |
parent | 8a0e8134938435524c79944656edf6807c3a3722 (diff) | |
download | scummvm-rg350-f94153f07a69e986547391922c8aa85ab0086874.tar.gz scummvm-rg350-f94153f07a69e986547391922c8aa85ab0086874.tar.bz2 scummvm-rg350-f94153f07a69e986547391922c8aa85ab0086874.zip |
TOUCHE: Fix semi-intentional array overrun
op_getInventoryItem/op_setInventoryItem could operate on
inventoryItems[4] while inventoryItems has only 4 elements. This
effectively accesses the 'money' field right behind this array.
Due to a broken assert, this was never detected.
This commit fixes it by redirecting accesses to inventoryItems[4] to
money, and also fixes the assert.
An alternative solution would have been enlarging the array, and
removing the money field, but that would require more changes in the
engine.
-rw-r--r-- | engines/touche/opcodes.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/engines/touche/opcodes.cpp b/engines/touche/opcodes.cpp index ee7f3a9b6b..2af942885a 100644 --- a/engines/touche/opcodes.cpp +++ b/engines/touche/opcodes.cpp @@ -610,8 +610,13 @@ void ToucheEngine::op_getInventoryItem() { keyChar = _currentKeyCharNum; } assert(keyChar >= 0 && keyChar < NUM_KEYCHARS); - assert(item < sizeof(_keyCharsTable[keyChar].inventoryItems)); - *_script.stackDataPtr = _keyCharsTable[keyChar].inventoryItems[item]; + if (item == 4) { + // item 4 is the 'money' field + *_script.stackDataPtr = _keyCharsTable[keyChar].money; + } else { + assert(item < ARRAYSIZE(_keyCharsTable[keyChar].inventoryItems)); + *_script.stackDataPtr = _keyCharsTable[keyChar].inventoryItems[item]; + } } void ToucheEngine::op_setInventoryItem() { @@ -625,8 +630,13 @@ void ToucheEngine::op_setInventoryItem() { keyChar = _currentKeyCharNum; } assert(keyChar >= 0 && keyChar < NUM_KEYCHARS); - assert(item < sizeof(_keyCharsTable[keyChar].inventoryItems)); - _keyCharsTable[keyChar].inventoryItems[item] = *_script.stackDataPtr; + if (item == 4) { + // item 4 is the 'money' field + _keyCharsTable[keyChar].money = *_script.stackDataPtr; + } else { + assert(item < ARRAYSIZE(_keyCharsTable[keyChar].inventoryItems)); + _keyCharsTable[keyChar].inventoryItems[item] = *_script.stackDataPtr; + } if (item == 4 && !_hideInventoryTexts) { drawAmountOfMoneyInInventory(); } |