From 1bdaa38c7ab3247cbb4ecf78514a2c0c297f7b40 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 2 Feb 2024 04:25:30 -0800 Subject: [PATCH] Replace CopyCaretColors with D_ParseCarets - New function also sanitizes input --- src/d_clisrv.c | 67 +----------------------------------------------- src/sanitize.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++ src/sanitize.h | 10 ++++++++ 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9345dcdb0..8f149d998 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1002,70 +1002,6 @@ static boolean CL_SendKey(void) return HSendPacket(servernode, false, 0, sizeof (clientkey_pak) ); } -static void -CopyCaretColors (char *p, const char *s, int n) -{ - char *t; - int m; - int c; - if (!n) - return; - while (( t = strchr(s, '^') )) - { - m = ( t - s ); - - if (m >= n) - { - memcpy(p, s, n); - return; - } - else - memcpy(p, s, m); - - p += m; - n -= m; - s += m; - - if (!n) - return; - - if (s[1]) - { - c = toupper(s[1]); - if (isdigit(c)) - c = 0x80 + ( c - '0' ); - else if (c >= 'A' && c <= 'F') - c = 0x80 + ( c - 'A' ); - else - c = 0; - - if (c) - { - *p++ = c; - n--; - - if (!n) - return; - } - else - { - if (n < 2) - break; - - memcpy(p, s, 2); - - p += 2; - n -= 2; - } - - s += 2; - } - else - break; - } - strncpy(p, s, n); -} - static void SV_SendServerInfo(INT32 node, tic_t servertime) { UINT8 *p; @@ -1112,8 +1048,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) (dedicated ? SV_DEDICATED : 0) ); - CopyCaretColors(netbuffer->u.serverinfo.servername, cv_servername.string, - MAXSERVERNAME); + D_ParseCarets(netbuffer->u.serverinfo.servername, cv_servername.string, MAXSERVERNAME); M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); diff --git a/src/sanitize.cpp b/src/sanitize.cpp index 0fbe146f9..9aa58fff6 100644 --- a/src/sanitize.cpp +++ b/src/sanitize.cpp @@ -43,6 +43,18 @@ std::string& filter_out(std::string& out, const std::string_view& range, F filte return out; }; +int hexconv(int c) +{ + if (std::isdigit(c)) + return c - '0'; + + c = std::toupper(c); + if (c >= 'A' && c <= 'F') + return 10 + (c - 'A'); + + return -1; +} + }; // namespace namespace srb2::sanitize @@ -64,9 +76,58 @@ std::string sanitize(std::string_view in, SanitizeMode mode) }()); } +std::string parse_carets(std::string_view in, ParseMode mode) +{ + std::string out; + + using std::size_t; + for (;;) + { + size_t p = in.find('^'); + + // copy chars up until the caret + // but filter out codes outside of the ASCII range + filter_out(out, in.substr(0, p), print_filter); + + if (p == in.npos) + { + break; // end of input + } + + in.remove_prefix(p); + + // need two characters for caret code + // convert to color byte + if (int c; in.length() > 1 && (c = hexconv(in[1])) != -1) + { + out.push_back(0x80 | c); + } + + if (mode != ParseMode::kConsume) + { + // preserve caret code in output + filter_out(out, in.substr(0, 2), print_filter); + } + + if (in.length() < 2) + { + break; + } + + in.remove_prefix(2); + } + + return out; +} + }; // namespace srb2 void D_SanitizeKeepColors(char *out, const char *in, size_t out_size) { strlcpy(out, sanitize(in, SanitizeMode::kKeepColors).c_str(), out_size); } + +void D_ParseCarets(char *out, const char *in, size_t out_size) +{ + strlcpy(out, parse_carets(in, ParseMode::kConsume).c_str(), out_size); +} diff --git a/src/sanitize.h b/src/sanitize.h index 24e757a15..f413923b5 100644 --- a/src/sanitize.h +++ b/src/sanitize.h @@ -25,15 +25,25 @@ enum class SanitizeMode kKeepColors, }; +enum class ParseMode +{ + kConsume, + kPreserve, +}; + // sanitizes string of all 0x80 codes std::string sanitize(std::string_view in, SanitizeMode mode); +// sanitizes string of all 0x80 codes then parses caret codes +std::string parse_carets(std::string_view in, ParseMode mode); + }; // namespace srb2 extern "C" { #endif void D_SanitizeKeepColors(char *out, const char *in, size_t out_size); // SanitizeMode::kKeepColors +void D_ParseCarets(char *out, const char *in, size_t out_size); // ParseMode::kConsume #ifdef __cplusplus } // extern "C"