From c3fa4c02ab11381b9139709882d85a14a19aa39a Mon Sep 17 00:00:00 2001 From: athrxx Date: Sun, 24 Feb 2019 19:56:31 +0100 Subject: KYRA: (EOB) - fix possible out of bounds mem access (This can't happen through normal gameplay, but still better to be fixed) --- engines/kyra/graphics/screen_eob.cpp | 11 ++++++++--- engines/kyra/gui/gui_eob.cpp | 37 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp index 90e2d1f41f..4cd471ee0a 100644 --- a/engines/kyra/graphics/screen_eob.cpp +++ b/engines/kyra/graphics/screen_eob.cpp @@ -1755,7 +1755,7 @@ bool OldDOSFont::load(Common::SeekableReadStream &file) { _width = _data[0x103]; _height = _data[0x102]; - _numGlyphs = 255; + _numGlyphs = (READ_LE_UINT16(_data + 2) / 2) - 2; _bitmapOffsets = (uint16 *)(_data + 2); @@ -1766,8 +1766,10 @@ bool OldDOSFont::load(Common::SeekableReadStream &file) { } int OldDOSFont::getCharWidth(uint16 c) const { - if (c >= _numGlyphs) - return 0; + // Since these fonts have a fixed character width we always give a return value + // even if there is no glyph for the specified character (which can't normally + // happen anyway - you'd have to do something like importing a Japanese save file + // into the English version). return _width; } @@ -1822,6 +1824,9 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const { } } + if (c >= _numGlyphs) + return; + pitch *= bpp; const uint8 *src = &_data[_bitmapOffsets[c]]; uint8 *dst2 = dst + pitch; diff --git a/engines/kyra/gui/gui_eob.cpp b/engines/kyra/gui/gui_eob.cpp index 2b16e7621f..1babce7267 100644 --- a/engines/kyra/gui/gui_eob.cpp +++ b/engines/kyra/gui/gui_eob.cpp @@ -2536,6 +2536,7 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo _menuCur = -1; printKatakanaOptions(0); + int bytesPerChar = (_vm->_flags.lang == Common::JA_JPN) ? 2 : 1; int in = 0; do { @@ -2586,9 +2587,9 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE) { if (pos > 0 && pos < len ) { for (int i = pos; i < len; i++) { - if (dest[i * 2] & 0x80) { - dest[(i - 1) * 2] = dest[i * 2]; - dest[(i - 1) * 2 + 1] = dest[i * 2 + 1]; + if (bytesPerChar == 2 && dest[i * bytesPerChar] & 0x80) { + dest[(i - 1) * bytesPerChar] = dest[i * bytesPerChar]; + dest[(i - 1) * bytesPerChar + 1] = dest[i * bytesPerChar + 1]; } else { dest[i - 1] = dest[i]; } @@ -2596,8 +2597,8 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo } if (pos > 0) { - if (dest[(len - 1) * 2] & 0x80) - dest[--len * 2] = 0; + if (bytesPerChar == 2 && dest[(len - 1) * bytesPerChar] & 0x80) + dest[--len * bytesPerChar] = 0; else dest[--len] = 0; pos--; @@ -2618,19 +2619,19 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo if (pos < len) { for (int i = destMaxLen - 2; i >= pos; i--) { - if (in == 0x89) { - dest[(i + 1) * 2] = dest[i * 2]; - dest[(i + 1) * 2 + 1] = dest[i * 2 + 1]; + if (bytesPerChar == 2 && in == 0x89) { + dest[(i + 1) * bytesPerChar] = dest[i * bytesPerChar]; + dest[(i + 1) * bytesPerChar + 1] = dest[i * bytesPerChar + 1]; } else { dest[i + 1] = dest[i]; } } - if (in == 0x89) { - dest[pos * 2] = _csjis[0]; - dest[pos++ * 2 + 1] = _csjis[1]; + if (bytesPerChar == 2 && in == 0x89) { + dest[pos * bytesPerChar] = _csjis[0]; + dest[pos++ * bytesPerChar + 1] = _csjis[1]; if (len == destMaxLen) - dest[len * 2] = 0; + dest[len * bytesPerChar] = 0; } else { dest[pos++] = in; if (len == destMaxLen) @@ -2642,10 +2643,10 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo len--; } - if (in == 0x89) { - dest[pos * 2] = _csjis[0]; - dest[pos * 2 + 1] = _csjis[1]; - dest[++pos * 2] = 0; + if (bytesPerChar == 2 && in == 0x89) { + dest[pos * bytesPerChar] = _csjis[0]; + dest[pos * bytesPerChar + 1] = _csjis[1]; + dest[++pos * bytesPerChar] = 0; } else { dest[pos++] = in; dest[pos] = 0; @@ -2665,8 +2666,8 @@ int GUI_EoB::getTextInput(char *dest, int x, int y, int destMaxLen, int textColo if (_vm->_flags.platform == Common::kPlatformFMTowns) { if (pos < len) { - sufx[0] = dest[pos * 2]; - sufx[1] = dest[pos * 2 + 1]; + sufx[0] = dest[pos * bytesPerChar]; + sufx[1] = dest[pos * bytesPerChar + 1]; } else { sufx[0] = 32; sufx[1] = 0; -- cgit v1.2.3