From 847d4e8b032be70c0a0ddc34a3c6f524ba9326fc Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 24 May 2018 15:03:15 +0200 Subject: [PATCH] =?UTF-8?q?Process=20string=5Fto=5Fmoney's=20worst=20case?= =?UTF-8?q?=20in=20O(n)=20rather=20than=20O(n=C2=B2).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/openrct2/localisation/Localisation.cpp | 46 ++++++++++------------ 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/openrct2/localisation/Localisation.cpp b/src/openrct2/localisation/Localisation.cpp index 8fd9e1ef1a..aee9815ca5 100644 --- a/src/openrct2/localisation/Localisation.cpp +++ b/src/openrct2/localisation/Localisation.cpp @@ -1230,51 +1230,51 @@ void format_string_to_upper(utf8 *dest, size_t size, rct_string_id format, void money32 string_to_money(const char* string_to_monetise) { - char processedString[128]; - safe_strcpy(processedString, string_to_monetise, 128); const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT); - char* text_ptr = processedString; + char processedString[128]; + uint32 numNumbers = 0; bool hasMinus = false; bool hasDecSep = false; + const char* src_ptr = string_to_monetise; + char* dst_ptr = processedString; - // Remove everything except numbers decimal, and minus sign(s) - for (uint32 i = 0, j; text_ptr[i] != '\0'; ++i) + // Process the string, keeping only numbers decimal, and minus sign(s). + while (*src_ptr != '\0') { - if (text_ptr[i] >= '0' && text_ptr[i] <= '9') + if (*src_ptr >= '0' && *src_ptr <= '9') { numNumbers++; } - else if (text_ptr[i] == decimal_char[0]) + else if (*src_ptr == decimal_char[0]) { if (hasDecSep) return MONEY32_UNDEFINED; else hasDecSep = true; } - else if (text_ptr[i] == '-') + else if (*src_ptr == '-') { if (hasMinus) return MONEY32_UNDEFINED; else hasMinus = true; } - - while (!( - (text_ptr[i] >= '0' && text_ptr[i] <= '9') || - (text_ptr[i] == decimal_char[0]) || - (text_ptr[i] == '-') || - (text_ptr[i] == '\0'))) + else { - // Move everything over to the left by one - for (j = i; text_ptr[j] != '\0'; ++j) - { - text_ptr[j] = text_ptr[j + 1]; - } - text_ptr[j] = '\0'; + // Skip invalid characters. + src_ptr++; + continue; } + + // Copy numeric values. + *dst_ptr++ = *src_ptr; + src_ptr++; } + // Terminate destination string. + *dst_ptr = '\0'; + if (numNumbers == 0) return MONEY32_UNDEFINED; @@ -1282,14 +1282,10 @@ money32 string_to_money(const char* string_to_monetise) if (hasMinus) { // If there is a minus sign, it has to be at position 0 in order to be valid. - if (text_ptr[0] == '-') - { + if (processedString[0] == '-') sign = -1; - } else - { return MONEY32_UNDEFINED; - } } // Due to the nature of strstr and strtok, decimals at the very beginning will be ignored, causing