From 778309ed56d7af86ea10c77555697102558947c4 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 27 Feb 2008 11:03:09 +0000 Subject: Simplified Control::handleKeyPress and fixed a long-standing bug in the verification of the save name svn-id: r30981 --- engines/sky/control.cpp | 44 ++++++++++++++++++-------------------------- engines/sky/control.h | 1 - 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp index 5b06efd589..db20c05f44 100644 --- a/engines/sky/control.cpp +++ b/engines/sky/control.cpp @@ -983,38 +983,30 @@ uint16 Control::saveRestorePanel(bool allowSave) { return clickRes; } -bool Control::checkKeyList(uint8 key) { - static const uint8 charList[14] = " ,().='-&+!?\""; - for (uint chCnt = 0; chCnt < ARRAYSIZE(charList); chCnt++) - if (charList[chCnt] == key) - return true; - return false; -} - void Control::handleKeyPress(Common::KeyState kbd, uint8 *textBuf) { + const int len = strlen((const char *)textBuf); if (kbd.keycode == Common::KEYCODE_BACKSPACE) { // backspace - for (uint8 cnt = 0; cnt < 6; cnt++) - if (!textBuf[cnt]) - return; - - while (textBuf[1]) - textBuf++; - textBuf[0] = 0; + // The first 5 chars are the label: "123: ", so the user is not allowed to delete those. + if (len < 6) + return; + textBuf[len-1] = 0; } else { + // Cannot enter text wider than the save/load panel if (_enteredTextWidth >= PAN_LINE_WIDTH - 10) return; - if (((kbd.ascii >= 'A') && (kbd.ascii <= 'Z')) || ((kbd.ascii >= 'a') && (kbd.ascii <= 'z')) || - ((kbd.ascii >= '0') && (kbd.ascii <= '9')) || checkKeyList(kbd.ascii)) { - uint8 strLen = 0; - while (textBuf[0]) { - textBuf++; - strLen++; - } - if (strLen < MAX_TEXT_LEN) { - textBuf[0] = kbd.ascii; - textBuf[1] = 0; - } + // Cannot enter text longer than MAX_TEXT_LEN-1 chars, since + // the storage is only so big. Note: The code used to incorrectly + // allow up to MAX_TEXT_LEN, which caused an out of bounds access, + // overwriting the next entry in the list of savegames partially. + // This could be triggered by e.g. entering lots of periods ".". + if (len >= MAX_TEXT_LEN - 1) + return; + // Allow the key only if is a letter, a digit, or one of a selected + // list of extra characters + if (isalnum(kbd.ascii) || strchr(" ,().='-&+!?\"", kbd.ascii) != 0) { + textBuf[len] = kbd.ascii; + textBuf[len+1] = 0; } } } diff --git a/engines/sky/control.h b/engines/sky/control.h index 754f2100d2..2191a9b79e 100644 --- a/engines/sky/control.h +++ b/engines/sky/control.h @@ -220,7 +220,6 @@ private: void saveDescriptions(uint8 *srcBuf); void setUpGameSprites(uint8 *nameBuf, dataFileHeader **nameSprites, uint16 firstNum, uint16 selectedGame); void showSprites(dataFileHeader **nameSprites, bool allowSave); - bool checkKeyList(uint8 key); void handleKeyPress(Common::KeyState kbd, uint8 *textBuf); uint16 _selectedGame; -- cgit v1.2.3