Add command/string helpers for string separator control character

pull/461/head
Jonathan G Rennison 2 years ago
parent 690ef6cc22
commit aaf0385dc5

@ -588,6 +588,7 @@ enum CommandFlags {
CMD_SERVER_NS = 0x1000, ///< the command can only be initiated by the server (this is not executed in spectator mode)
CMD_LOG_AUX = 0x2000, ///< the command should be logged in the auxiliary log instead of the main log
CMD_P1_TILE = 0x4000, ///< use p1 for money text and error tile
CMD_STR_SEP = 0x8000, ///< the command's string may contain separator control characters
};
DECLARE_ENUM_AS_BIT_SET(CommandFlags)

@ -330,7 +330,9 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
cp->tile = p->Recv_uint32();
cp->binary_length = p->Recv_uint32();
if (cp->binary_length == 0) {
p->Recv_string(cp->text, (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
StringValidationSettings settings = (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK;
if (GetCommandFlags(cp->cmd) & CMD_STR_SEP) settings |= SVS_ALLOW_SEPARATOR_CODE;
p->Recv_string(cp->text, settings);
} else {
if (!p->CanReadFromPacket(cp->binary_length + /* callback index */ 1)) return "invalid binary data length";
if (cp->binary_length > MAX_CMD_TEXT_LENGTH) return "over-size binary data length";

@ -319,7 +319,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
/* 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. */
text_validated = text;
::StrMakeValidInPlace(text_validated, SVS_NONE);
::StrMakeValidInPlace(text_validated, (GetCommandFlags(cmd) & CMD_STR_SEP) ? SVS_ALLOW_SEPARATOR_CODE : SVS_NONE);
text = text_validated.c_str();
}

@ -261,6 +261,8 @@ static void StrMakeValidInPlace(T &dst, const char *str, const char *last, Strin
} while (--len != 0);
} else if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\n') {
*dst++ = *str++;
} else if ((settings & SVS_ALLOW_SEPARATOR_CODE) != 0 && c == 0x1F) {
*dst++ = *str++;
} else {
if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\r' && str[1] == '\n') {
str += len;
@ -416,6 +418,21 @@ bool StrEndsWith(const std::string_view str, const std::string_view suffix)
return str.compare(str.size() - suffix_len, suffix_len, suffix, 0, suffix_len) == 0;
}
const char *StrConsumeToSeparator(std::string &result, const char *str)
{
if (str == nullptr) {
result = "";
return nullptr;
}
const char *end = str;
while (*end != '\0' && *end != 0x1F) {
end++;
}
result.assign(str, end);
if (*end == 0x1F) return end + 1;
return nullptr;
}
/** Scans the string for colour codes and strips them */
void str_strip_colours(char *str)

@ -59,6 +59,8 @@ void StrTrimInPlace(std::string &str);
bool StrStartsWith(const std::string_view str, const std::string_view prefix);
bool StrEndsWith(const std::string_view str, const std::string_view suffix);
const char *StrConsumeToSeparator(std::string &result, const char *str);
/**
* Check if a string buffer is empty.
*

@ -52,6 +52,7 @@ enum StringValidationSettings {
SVS_REPLACE_WITH_QUESTION_MARK = 1 << 0, ///< Replace the unknown/bad bits with question marks.
SVS_ALLOW_NEWLINE = 1 << 1, ///< Allow newlines.
SVS_ALLOW_CONTROL_CODE = 1 << 2, ///< Allow the special control codes.
SVS_ALLOW_SEPARATOR_CODE = 1 << 3, ///< Allow separator control code (0x1F).
};
DECLARE_ENUM_AS_BIT_SET(StringValidationSettings)

Loading…
Cancel
Save