From 3b178bf58d4bc5af55f615141b5d1edf60b8c910 Mon Sep 17 00:00:00 2001 From: frosch Date: Fri, 14 Mar 2025 14:04:13 +0100 Subject: [PATCH] Fix: NewGRF string interpolation did not process all string parameters, if certain string control codes were present. String control codes with inline data may contain null characters, in particular plural/gender/case choice lists. --- src/newgrf_text.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 7c314f954b..c13448d26e 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -764,6 +764,40 @@ static void ProcessNewGRFStringControlCode(char32_t scc, const char *&str, TextR * After this call, a new call is made with `modify_parameters` set to false when the string is finally formatted. */ switch (scc) { default: return; + + case SCC_PLURAL_LIST: + ++str; // plural form + [[fallthrough]]; + case SCC_GENDER_LIST: { + ++str; // offset + /* plural and gender choices cannot contain any string commands, so just skip the whole thing */ + uint num = static_cast(*str++); + uint total_len = 0; + for (uint i = 0; i != num; i++) { + total_len += static_cast(*str++); + } + str += total_len; + break; + } + + case SCC_SWITCH_CASE: { + /* skip all cases and continue with default case */ + uint num = static_cast(*str++); + for (uint i = 0; i != num; i++) { + str += 3 + (static_cast(str[1]) << 8) + static_cast(str[2]); + } + break; + } + + case SCC_GENDER_INDEX: + case SCC_SET_CASE: + ++str; + break; + + case SCC_ARG_INDEX: + NOT_REACHED(); + break; + case SCC_NEWGRF_PRINT_BYTE_SIGNED: params.emplace_back(stack.PopSignedByte()); break; case SCC_NEWGRF_PRINT_QWORD_CURRENCY: params.emplace_back(stack.PopSignedQWord()); break;