Replace CopyCaretColors with D_ParseCarets

- New function also sanitizes input
This commit is contained in:
James R 2024-02-02 04:25:30 -08:00
parent 8f2c904651
commit 1bdaa38c7a
3 changed files with 72 additions and 66 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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"