5828: Ignore server info with control characters r=def- a=heinrich5991

This simply treats server info as invalid if it contains control
characters in any string.

Fixes #5826.

## Checklist

- [ ] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test (especially base/) or added coverage to integration test
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
bors[bot] 2022-09-11 22:06:22 +00:00 committed by GitHub
commit bc1bd0b439
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 12 deletions

View file

@ -2650,6 +2650,20 @@ char *str_trim_words(char *str, int words)
return str;
}
bool str_has_cc(const char *str)
{
unsigned char *s = (unsigned char *)str;
while(*s)
{
if(*s < 32)
{
return true;
}
s++;
}
return false;
}
/* makes sure that the string only contains the characters between 32 and 255 */
void str_sanitize_cc(char *str_in)
{

View file

@ -1249,6 +1249,19 @@ int str_format(char *buffer, int buffer_size, const char *format, ...)
*/
char *str_trim_words(char *str, int words);
/**
* Check whether string has ASCII control characters.
*
* @ingroup Strings
*
* @param str String to check.
*
* @return Whether the string has ASCII control characters.
*
* @remark The strings are treated as zero-terminated strings.
*/
bool str_has_cc(const char *str);
/**
* Replaces all characters below 32 with whitespace.
*

View file

@ -74,10 +74,10 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson)
Error = Error || MaxClients.type != json_integer;
Error = Error || MaxPlayers.type != json_integer;
Error = Error || Passworded.type != json_boolean;
Error = Error || GameType.type != json_string;
Error = Error || Name.type != json_string;
Error = Error || MapName.type != json_string;
Error = Error || Version.type != json_string;
Error = Error || GameType.type != json_string || str_has_cc(GameType);
Error = Error || Name.type != json_string || str_has_cc(Name);
Error = Error || MapName.type != json_string || str_has_cc(MapName);
Error = Error || Version.type != json_string || str_has_cc(Version);
Error = Error || Clients.type != json_array;
if(Error)
{
@ -102,8 +102,8 @@ bool CServerInfo2::FromJsonRaw(CServerInfo2 *pOut, const json_value *pJson)
const json_value &Score = Client["score"];
const json_value &IsPlayer = Client["is_player"];
Error = false;
Error = Error || ClientName.type != json_string;
Error = Error || Clan.type != json_string;
Error = Error || ClientName.type != json_string || str_has_cc(ClientName);
Error = Error || Clan.type != json_string || str_has_cc(ClientName);
Error = Error || Country.type != json_integer;
Error = Error || Score.type != json_integer;
Error = Error || IsPlayer.type != json_boolean;

View file

@ -337,7 +337,7 @@ TEST(Str, InList)
EXPECT_TRUE(str_in_list("abc,,def", ",", "def"));
}
TEST(Str, StrFormat)
TEST(Str, Format)
{
char aBuf[4];
EXPECT_EQ(str_format(aBuf, 4, "%d:", 9), 2);
@ -348,7 +348,7 @@ TEST(Str, StrFormat)
EXPECT_STREQ(aBuf, "99:");
}
TEST(Str, StrFormatTruncate)
TEST(Str, FormatTruncate)
{
const char *pStr = "DDNet最好了";
char aBuf[64];
@ -374,7 +374,7 @@ TEST(Str, StrFormatTruncate)
EXPECT_STREQ(aBuf, "DDNet最好了");
}
TEST(Str, StrCopyNum)
TEST(Str, CopyNum)
{
const char *pFoo = "Foobaré";
char aBuf[64];
@ -399,7 +399,7 @@ TEST(Str, StrCopyNum)
EXPECT_STREQ(aBuf3, "Foobaré");
}
TEST(Str, StrCopy)
TEST(Str, Copy)
{
const char *pStr = "DDNet最好了";
char aBuf[64];
@ -462,7 +462,7 @@ TEST(Str, Utf8Stats)
EXPECT_EQ(Count, 3);
}
TEST(Str, StrTime)
TEST(Str, Time)
{
char aBuf[32] = "foobar";
@ -514,7 +514,7 @@ TEST(Str, StrTime)
EXPECT_STREQ(aBuf, "2057:36.78");
}
TEST(Str, StrTimeFloat)
TEST(Str, TimeFloat)
{
char aBuf[64];
EXPECT_EQ(str_time_float(123456.78, TIME_DAYS, aBuf, sizeof(aBuf)), 11);
@ -523,3 +523,19 @@ TEST(Str, StrTimeFloat)
EXPECT_EQ(str_time_float(12.16, TIME_HOURS_CENTISECS, aBuf, sizeof(aBuf)), 8);
EXPECT_STREQ(aBuf, "00:12.16");
}
TEST(Str, HasCc)
{
EXPECT_FALSE(str_has_cc(""));
EXPECT_FALSE(str_has_cc("a"));
EXPECT_FALSE(str_has_cc("Merhaba dünya!"));
EXPECT_TRUE(str_has_cc("\n"));
EXPECT_TRUE(str_has_cc("\n"));
EXPECT_TRUE(str_has_cc("\r"));
EXPECT_TRUE(str_has_cc("\t"));
EXPECT_TRUE(str_has_cc("a\n"));
EXPECT_TRUE(str_has_cc("a\rb"));
EXPECT_TRUE(str_has_cc("\tb"));
EXPECT_TRUE(str_has_cc("\n\n"));
}