Codechange: Use EnumBitSet for StringValidationSettings. (#13974)

This commit is contained in:
Peter Nelson 2025-04-08 21:19:17 +01:00 committed by GitHub
parent 4e4f413913
commit 5b9d171e63
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 38 additions and 34 deletions

View File

@ -103,7 +103,7 @@ void IConsolePrint(TextColour colour_code, const std::string &string)
/* Create a copy of the string, strip it of colours and invalid /* Create a copy of the string, strip it of colours and invalid
* characters and (when applicable) assign it to the console buffer */ * characters and (when applicable) assign it to the console buffer */
std::string str = StrMakeValid(string, SVS_NONE); std::string str = StrMakeValid(string, {});
if (_network_dedicated) { if (_network_dedicated) {
NetworkAdminConsole("console", str); NetworkAdminConsole("console", str);

View File

@ -87,7 +87,7 @@ public:
uint64_t Recv_uint64(); uint64_t Recv_uint64();
std::vector<uint8_t> Recv_buffer(); std::vector<uint8_t> Recv_buffer();
size_t Recv_bytes(std::span<uint8_t> span); size_t Recv_bytes(std::span<uint8_t> span);
std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); std::string Recv_string(size_t length, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark);
size_t RemainingBytesToTransfer() const; size_t RemainingBytesToTransfer() const;

View File

@ -441,7 +441,11 @@ template <class T>
static inline void SanitizeSingleStringHelper([[maybe_unused]] CommandFlags cmd_flags, T &data) static inline void SanitizeSingleStringHelper([[maybe_unused]] CommandFlags cmd_flags, T &data)
{ {
if constexpr (std::is_same_v<std::string, T>) { if constexpr (std::is_same_v<std::string, T>) {
StrMakeValidInPlace(data, (!_network_server && cmd_flags.Test(CommandFlag::StrCtrl)) ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK); if (!_network_server && cmd_flags.Test(CommandFlag::StrCtrl)) {
StrMakeValidInPlace(data, {StringValidationSetting::AllowControlCode, StringValidationSetting::ReplaceWithQuestionMark});
} else {
StrMakeValidInPlace(data, {StringValidationSetting::ReplaceWithQuestionMark});
}
} }
} }

View File

@ -68,7 +68,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet &p)
ci->name = p.Recv_string(NETWORK_CONTENT_NAME_LENGTH); ci->name = p.Recv_string(NETWORK_CONTENT_NAME_LENGTH);
ci->version = p.Recv_string(NETWORK_CONTENT_VERSION_LENGTH); ci->version = p.Recv_string(NETWORK_CONTENT_VERSION_LENGTH);
ci->url = p.Recv_string(NETWORK_CONTENT_URL_LENGTH); ci->url = p.Recv_string(NETWORK_CONTENT_URL_LENGTH);
ci->description = p.Recv_string(NETWORK_CONTENT_DESC_LENGTH, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE); ci->description = p.Recv_string(NETWORK_CONTENT_DESC_LENGTH, {StringValidationSetting::ReplaceWithQuestionMark, StringValidationSetting::AllowNewline});
ci->unique_id = p.Recv_uint32(); ci->unique_id = p.Recv_uint32();
p.Recv_bytes(ci->md5sum); p.Recv_bytes(ci->md5sum);

View File

@ -1398,8 +1398,8 @@ private:
/** Sort grfs by name. */ /** Sort grfs by name. */
static bool NameSorter(const GRFConfig * const &a, const GRFConfig * const &b) static bool NameSorter(const GRFConfig * const &a, const GRFConfig * const &b)
{ {
std::string name_a = StrMakeValid(a->GetName(), SVS_NONE); // Make a copy without control codes. std::string name_a = StrMakeValid(a->GetName(), {}); // Make a copy without control codes.
std::string name_b = StrMakeValid(b->GetName(), SVS_NONE); // Make a copy without control codes. std::string name_b = StrMakeValid(b->GetName(), {}); // Make a copy without control codes.
int i = StrNaturalCompare(name_a, name_b, true); // Sort by name (natural sorting). int i = StrNaturalCompare(name_a, name_b, true); // Sort by name (natural sorting).
if (i != 0) return i < 0; if (i != 0) return i < 0;

View File

@ -1190,7 +1190,7 @@ void ShowLastNewsMessage()
static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem &ni) static void DrawNewsString(uint left, uint right, int y, TextColour colour, const NewsItem &ni)
{ {
/* Get the string, replaces newlines with spaces and remove control codes from the string. */ /* Get the string, replaces newlines with spaces and remove control codes from the string. */
std::string message = StrMakeValid(ni.GetStatusText(), SVS_REPLACE_TAB_CR_NL_WITH_SPACE); std::string message = StrMakeValid(ni.GetStatusText(), StringValidationSetting::ReplaceTabCrNlWithSpace);
/* Truncate and show string; postfixed by '...' if necessary */ /* Truncate and show string; postfixed by '...' if necessary */
DrawString(left, right, y, message, colour); DrawString(left, right, y, message, colour);

View File

@ -1020,13 +1020,13 @@ static void SlStdString(void *ptr, VarType conv)
SlReadString(*str, len); SlReadString(*str, len);
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK; StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark;
if ((conv & SLF_ALLOW_CONTROL) != 0) { if ((conv & SLF_ALLOW_CONTROL) != 0) {
settings = settings | SVS_ALLOW_CONTROL_CODE; settings.Set(StringValidationSetting::AllowControlCode);
if (IsSavegameVersionBefore(SLV_ENCODED_STRING_FORMAT)) FixSCCEncoded(*str, IsSavegameVersionBefore(SLV_169)); if (IsSavegameVersionBefore(SLV_ENCODED_STRING_FORMAT)) FixSCCEncoded(*str, IsSavegameVersionBefore(SLV_169));
} }
if ((conv & SLF_ALLOW_NEWLINE) != 0) { if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE; settings.Set(StringValidationSetting::AllowNewline);
} }
StrMakeValidInPlace(*str, settings); StrMakeValidInPlace(*str, settings);
} }

View File

@ -353,7 +353,7 @@ namespace ScriptObjectInternal {
if constexpr (std::is_same_v<std::string, T>) { if constexpr (std::is_same_v<std::string, T>) {
/* The string must be valid, i.e. not contain special codes. Since some /* The string must be valid, i.e. not contain special codes. Since some
* can be made with GSText, make sure the control codes are removed. */ * can be made with GSText, make sure the control codes are removed. */
::StrMakeValidInPlace(data, SVS_NONE); ::StrMakeValidInPlace(data, {});
} }
} }

View File

@ -204,7 +204,7 @@ void ScriptText::ParamCheck::Encode(std::back_insert_iterator<std::string> &outp
void operator()(std::string value) void operator()(std::string value)
{ {
Utf8Encode(this->output, SCC_ENCODED_STRING); Utf8Encode(this->output, SCC_ENCODED_STRING);
StrMakeValidInPlace(value, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE | SVS_REPLACE_TAB_CR_NL_WITH_SPACE); StrMakeValidInPlace(value, {StringValidationSetting::ReplaceWithQuestionMark, StringValidationSetting::AllowNewline, StringValidationSetting::ReplaceTabCrNlWithSpace});
fmt::format_to(this->output, "{}", value); fmt::format_to(this->output, "{}", value);
} }

View File

@ -598,7 +598,7 @@ void StringSettingDesc::MakeValueValid(std::string &str) const
* includes the '\0' termination for network transfer purposes. * includes the '\0' termination for network transfer purposes.
* Also ensure the string is valid after chopping of some bytes. */ * Also ensure the string is valid after chopping of some bytes. */
str.erase(this->max_length - 1, std::string::npos); str.erase(this->max_length - 1, std::string::npos);
StrMakeValidInPlace(str, SVS_NONE); StrMakeValidInPlace(str, {});
} }
/** /**

View File

@ -39,7 +39,7 @@
static bool DrawScrollingStatusText(const NewsItem &ni, int scroll_pos, int left, int right, int top, int bottom) static bool DrawScrollingStatusText(const NewsItem &ni, int scroll_pos, int left, int right, int top, int bottom)
{ {
/* Replace newlines and the likes with spaces. */ /* Replace newlines and the likes with spaces. */
std::string message = StrMakeValid(ni.GetStatusText(), SVS_REPLACE_TAB_CR_NL_WITH_SPACE); std::string message = StrMakeValid(ni.GetStatusText(), StringValidationSetting::ReplaceTabCrNlWithSpace);
DrawPixelInfo tmp_dpi; DrawPixelInfo tmp_dpi;
if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true; if (!FillDrawPixelInfo(&tmp_dpi, left, top, right - left, bottom)) return true;

View File

@ -159,25 +159,25 @@ static void StrMakeValid(T &dst, const char *str, const char *last, StringValida
continue; continue;
} }
if ((IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END)) || ((settings & SVS_ALLOW_CONTROL_CODE) != 0 && IsSccEncodedCode(c))) { if ((IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END)) || (settings.Test(StringValidationSetting::AllowControlCode) && IsSccEncodedCode(c))) {
/* Copy the character back. Even if dst is current the same as str /* Copy the character back. Even if dst is current the same as str
* (i.e. no characters have been changed) this is quicker than * (i.e. no characters have been changed) this is quicker than
* moving the pointers ahead by len */ * moving the pointers ahead by len */
do { do {
*dst++ = *str++; *dst++ = *str++;
} while (--len != 0); } while (--len != 0);
} else if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\n') { } else if (settings.Test(StringValidationSetting::AllowNewline) && c == '\n') {
*dst++ = *str++; *dst++ = *str++;
} else { } else {
if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\r' && str[1] == '\n') { if (settings.Test(StringValidationSetting::AllowNewline) && c == '\r' && str[1] == '\n') {
str += len; str += len;
continue; continue;
} }
str += len; str += len;
if ((settings & SVS_REPLACE_TAB_CR_NL_WITH_SPACE) != 0 && (c == '\r' || c == '\n' || c == '\t')) { if (settings.Test(StringValidationSetting::ReplaceTabCrNlWithSpace) && (c == '\r' || c == '\n' || c == '\t')) {
/* Replace the tab, carriage return or newline with a space. */ /* Replace the tab, carriage return or newline with a space. */
*dst++ = ' '; *dst++ = ' ';
} else if ((settings & SVS_REPLACE_WITH_QUESTION_MARK) != 0) { } else if (settings.Test(StringValidationSetting::ReplaceWithQuestionMark)) {
/* Replace the undesirable character with a question mark */ /* Replace the undesirable character with a question mark */
*dst++ = '?'; *dst++ = '?';
} }

View File

@ -21,15 +21,15 @@ void strecpy(std::span<char> dst, std::string_view src);
std::string FormatArrayAsHex(std::span<const uint8_t> data); std::string FormatArrayAsHex(std::span<const uint8_t> data);
void StrMakeValidInPlace(char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); void StrMakeValidInPlace(char *str, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark);
void StrMakeValidInPlace(std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); void StrMakeValidInPlace(std::string &str, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark);
[[nodiscard]] std::string StrMakeValid(std::string_view str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); [[nodiscard]] std::string StrMakeValid(std::string_view str, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark);
[[nodiscard]] inline std::string StrMakeValid(const char *str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) [[nodiscard]] inline std::string StrMakeValid(const char *str, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark)
{ {
return StrMakeValid(std::string_view(str), settings); return StrMakeValid(std::string_view(str), settings);
} }
[[nodiscard]] inline std::string StrMakeValid(std::string &&str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) [[nodiscard]] inline std::string StrMakeValid(std::string &&str, StringValidationSettings settings = StringValidationSetting::ReplaceWithQuestionMark)
{ {
StrMakeValidInPlace(str, settings); StrMakeValidInPlace(str, settings);
return std::move(str); return std::move(str);

View File

@ -41,19 +41,19 @@ static const char32_t CHAR_TD_RLO = 0x202E; ///< Force the following characters
static const char32_t CHAR_TD_PDF = 0x202C; ///< Restore the text-direction state to before the last LRE, RLE, LRO or RLO. static const char32_t CHAR_TD_PDF = 0x202C; ///< Restore the text-direction state to before the last LRE, RLE, LRO or RLO.
/** Settings for the string validation. */ /** Settings for the string validation. */
enum StringValidationSettings : uint8_t { enum class StringValidationSetting : uint8_t {
SVS_NONE = 0, ///< Allow nothing and replace nothing. ReplaceWithQuestionMark, ///< Replace the unknown/bad bits with question marks.
SVS_REPLACE_WITH_QUESTION_MARK = 1 << 0, ///< Replace the unknown/bad bits with question marks. AllowNewline, ///< Allow newlines; replaces '\r\n' with '\n' during processing.
SVS_ALLOW_NEWLINE = 1 << 1, ///< Allow newlines; replaces '\r\n' with '\n' during processing. AllowControlCode, ///< Allow the special control codes.
SVS_ALLOW_CONTROL_CODE = 1 << 2, ///< Allow the special control codes.
/** /**
* Replace tabs ('\t'), carriage returns ('\r') and newlines ('\n') with spaces. * Replace tabs ('\t'), carriage returns ('\r') and newlines ('\n') with spaces.
* When #SVS_ALLOW_NEWLINE is set, a '\n' or '\r\n' combination are not replaced with a space. A lone '\r' is replaced with a space. * When #StringValidationSetting::AllowNewline is set, a '\n' or '\r\n' combination are not replaced with a space. A lone '\r' is replaced with a space.
* When #SVS_REPLACE_WITH_QUESTION_MARK is set, this replacement runs first. * When #StringValidationSetting::ReplaceWithQuestionMark is set, this replacement runs first.
*/ */
SVS_REPLACE_TAB_CR_NL_WITH_SPACE = 1 << 3, ReplaceTabCrNlWithSpace,
}; };
DECLARE_ENUM_AS_BIT_SET(StringValidationSettings)
using StringValidationSettings = EnumBitSet<StringValidationSetting, uint8_t>;
/** Type for a list of strings. */ /** Type for a list of strings. */

View File

@ -803,7 +803,7 @@ static std::vector<char> Xunzip(std::span<char> input)
*/ */
void TextfileWindow::LoadText(std::string_view buf) void TextfileWindow::LoadText(std::string_view buf)
{ {
std::string text = StrMakeValid(buf, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE | SVS_REPLACE_TAB_CR_NL_WITH_SPACE); std::string text = StrMakeValid(buf, {StringValidationSetting::ReplaceWithQuestionMark, StringValidationSetting::AllowNewline, StringValidationSetting::ReplaceTabCrNlWithSpace});
this->lines.clear(); this->lines.clear();
/* Split the string on newlines. */ /* Split the string on newlines. */