1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-26 00:04:43 +01:00

Fix invalid indices to user strings (#19738)

C++ treats `%` (mod) operation differently to common knowledge. While
`1 % 4` yields expected `1`, `-1 % 4` yields `-1` instead of expected
`3`. This can lead to user string IDs with low values (less than
`USER_STRING_START` or 0x8000) to become negative, resulting in
incorrect reads from user strings array.

Instead of trying to massage the value less `USER_STRING_START` into
expected range, I observed the original value (of uint16_t type) would
be congruent even if we didn't subtract, as both modulus and subtrahent
are sufficiently large powers of two.

This is _possibly_ the reason for issues such as
https://github.com/OpenRCT2/OpenRCT2/issues/19240 where crash occured
during park load.

This can be trivially reproduced by loading "Prehistoric - After the
Asteroid" from "Time Twister".
This commit is contained in:
Michał Janiszewski
2023-03-28 17:10:59 +02:00
committed by GitHub
parent e11d9553f3
commit 20d43db4a7
3 changed files with 2 additions and 3 deletions

View File

@@ -45,7 +45,6 @@ bool IsUserStringID(StringId stringId);
#define MAX_USER_STRINGS 1024
#define USER_STRING_MAX_LENGTH 32
#define USER_STRING_START 0x8000
#define USER_STRING_END 0x8FFF
#define REAL_NAME_START 0xA000
#define REAL_NAME_END 0xDFFF

View File

@@ -2470,7 +2470,7 @@ namespace RCT1
std::string GetUserString(StringId stringId)
{
const auto originalString = _s4.StringTable[(stringId - USER_STRING_START) % 1024];
const auto originalString = _s4.StringTable[stringId % 1024];
auto originalStringView = std::string_view(
originalString, RCT2::GetRCT2StringBufferLen(originalString, USER_STRING_MAX_LENGTH));
auto asUtf8 = RCT2StringToUTF8(originalStringView, RCT2LanguageId::EnglishUK);

View File

@@ -1858,7 +1858,7 @@ namespace RCT2
std::string GetUserString(StringId stringId)
{
const auto originalString = _s6.CustomStrings[(stringId - USER_STRING_START) % 1024];
const auto originalString = _s6.CustomStrings[stringId % 1024];
auto originalStringView = std::string_view(
originalString, GetRCT2StringBufferLen(originalString, USER_STRING_MAX_LENGTH));
auto asUtf8 = RCT2StringToUTF8(originalStringView, RCT2LanguageId::EnglishUK);