Skip to content

Commit

Permalink
refactor: filter inbound strings according to type
Browse files Browse the repository at this point in the history
Names have different requirements than non-names, so we
now filter them differently. Also added the colon character
to the invalid nick char list because the colon is used for
extracting nicks from logs.
  • Loading branch information
JFreegman committed Feb 28, 2024
1 parent 68beece commit 7ed06b0
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/chat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,7 +1578,7 @@ static void chat_onDraw(ToxWindow *self, Toxic *toxic)
tox_friend_get_status_message(toxic->tox, self->num, (uint8_t *) statusmsg, NULL);
const size_t s_len = tox_friend_get_status_message_size(toxic->tox, self->num, NULL);

filter_str(statusmsg, s_len);
filter_string(statusmsg, s_len, false);
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
statusbar->statusmsg_len = strlen(statusbar->statusmsg);

Expand Down Expand Up @@ -1738,7 +1738,7 @@ static void chat_onInit(ToxWindow *self, Toxic *toxic)
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH + 1] = {0};
tox_friend_get_status_message(tox, self->num, (uint8_t *) statusmsg, NULL);
statusmsg[s_len] = '\0';
filter_str(statusmsg, s_len);
filter_string(statusmsg, s_len, false);
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
}

Expand Down
4 changes: 2 additions & 2 deletions src/friendlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,7 @@ static void friendlist_onDraw(ToxWindow *self, Toxic *toxic)

statusmsg[s_len] = '\0';

filter_str(statusmsg, s_len);
filter_string(statusmsg, s_len, false);

pthread_mutex_lock(&Winthread.lock);
snprintf(Friends.list[f].statusmsg, sizeof(Friends.list[f].statusmsg), "%s", statusmsg);
Expand Down Expand Up @@ -1796,7 +1796,7 @@ bool friend_config_set_alias(const char *public_key, const char *alias, uint16_t

char tmp[TOXIC_MAX_NAME_LENGTH + 1];
const uint16_t tmp_len = copy_tox_str(tmp, sizeof(tmp), alias, length);
filter_str(tmp, tmp_len);
filter_string(tmp, tmp_len, true);

if (tmp_len == 0 || tmp_len > TOXIC_MAX_NAME_LENGTH) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/groupchats.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ void groupchat_update_statusbar_topic(ToxWindow *self, const Tox *tox)

tox_group_get_topic(tox, self->num, (uint8_t *)topic, NULL);
topic[t_len] = '\0';
filter_str(topic, t_len);
filter_string(topic, t_len, false);
snprintf(statusbar->topic, sizeof(statusbar->topic), "%s", topic);
statusbar->topic_len = strlen(statusbar->topic);
}
Expand Down
50 changes: 22 additions & 28 deletions src/misc_tools.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,59 +305,53 @@ int qsort_ptr_char_array_helper(const void *str1, const void *str2)
return strcasecmp(*(const char *const *)str1, *(const char *const *)str2);
}

static const char invalid_chars[] = {'/', '\n', '\t', '\v', '\r', '\0'};
/* List of characters we don't allow in nicks. */
static const char invalid_nick_chars[] = {':', '/', '\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v'};

/* List of characters we don't allow in single-line strings. */
static const char invalid_string_chars[] = {'\0', '\a', '\b', '\f', '\n', '\r', '\t', '\v'};

/*
* Helper function for `valid_nick()`.
*
* Returns true if `ch` is not in the `invalid_chars` array.
* Returns true if the character `ch` is not in the supplied `invalid_chars` array.
*/
static bool is_valid_char(char ch)
static bool is_valid_char(char ch, const char *const invalid_chars, size_t list_length)
{
char tmp;

for (size_t i = 0; (tmp = invalid_chars[i]); ++i) {
if (tmp == ch) {
for (size_t i = 0; i < list_length; ++i) {
if (invalid_chars[i] == ch) {
return false;
}
}

return true;
}

/* Returns true if nick is valid.
*
* A valid toxic nick:
* - cannot be empty
* - cannot start with a space
* - must not contain a forward slash (for logfile naming purposes)
* - must not contain contiguous spaces
* - must not contain a newline or tab seqeunce
*/
bool valid_nick(const char *nick)
{
if (!nick[0] || nick[0] == ' ') {
return false;
}

for (size_t i = 0; nick[i]; ++i) {
for (size_t i = 0; nick[i] != '\0'; ++i) {
char ch = nick[i];

if ((ch == ' ' && nick[i + 1] == ' ') || !is_valid_char(ch)) {
if ((ch == ' ' && nick[i + 1] == ' ')
|| !is_valid_char(ch, invalid_nick_chars, sizeof(invalid_nick_chars))) {
return false;
}
}

return true;
}

/* Converts all newline/tab chars to spaces (use for strings that should be contained to a single line) */
void filter_str(char *str, size_t len)
void filter_string(char *str, size_t len, bool is_nick)
{
const char *const invalid_chars = is_nick ? invalid_nick_chars : invalid_string_chars;
const size_t list_length = is_nick ? sizeof(invalid_nick_chars) : sizeof(invalid_string_chars);

for (size_t i = 0; i < len; ++i) {
char ch = str[i];

if (!is_valid_char(ch) || str[i] == '\0') {
if (!is_valid_char(ch, invalid_chars, list_length)) {
str[i] = ' ';
}
}
Expand Down Expand Up @@ -450,7 +444,7 @@ size_t get_nick_truncate(Tox *tox, char *buf, uint16_t buf_size, uint32_t friend

len = MIN(len, buf_size - 1);
buf[len] = '\0';
filter_str(buf, len);
filter_string(buf, len, false);

return len;

Expand All @@ -475,7 +469,7 @@ int get_conference_nick_truncate(Tox *tox, char *buf, uint32_t peernum, uint32_t

len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
buf[len] = '\0';
filter_str(buf, len);
filter_string(buf, len, true);
return len;

on_error:
Expand Down Expand Up @@ -507,7 +501,7 @@ size_t get_group_nick_truncate(Tox *tox, char *buf, uint32_t peer_id, uint32_t g
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
buf[len] = '\0';

filter_str(buf, len);
filter_string(buf, len, true);

return len;
}
Expand All @@ -531,9 +525,9 @@ size_t get_group_self_nick_truncate(Tox *tox, char *buf, uint32_t groupnum)
}

len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
buf[len] = 0;
buf[len] = '\0';

filter_str(buf, len);
filter_string(buf, len, true);

return len;
}
Expand Down
18 changes: 12 additions & 6 deletions src/misc_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,22 @@ int qsort_ptr_char_array_helper(const void *str1, const void *str2);
* A valid toxic nick:
* - cannot be empty
* - cannot start with a space
* - must not contain a forward slash (for logfile naming purposes)
* - must not contain contiguous spaces
* - must not contain a newline or tab seqeunce
* - cannot contain contiguous spaces
* - cannot contain forward slash (for log file naming purposes)
* - cannot contain any characters in the `invalid_nick_chars` array that
* resides in misc_tools.c.
*/
bool valid_nick(const char *nick);

/* Converts all newline/tab chars to spaces
* (use for strings that should be contained to a single line)
/* Converts all invalid single-line string characters to spaces (newlines,
* tabs, nul etc.).
*
* If `is_nick` is true, additional characters specific to nicks are filtered.
*
* This function is used for strings that should be human-readable, and contained
* to a single line, such as status messages, nicks, and group topics.
*/
void filter_str(char *str, size_t len);
void filter_string(char *str, size_t len, bool is_nick);

/* gets base file name from path or original file name if no path is supplied */
size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname);
Expand Down
13 changes: 9 additions & 4 deletions src/windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ void on_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data,

char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) data, length);
filter_string(msg, length, false);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand Down Expand Up @@ -136,7 +137,7 @@ void on_friend_name(Tox *tox, uint32_t friendnumber, const uint8_t *string, size

char nick[TOXIC_MAX_NAME_LENGTH + 1];
length = copy_tox_str(nick, sizeof(nick), (const char *) string, length);
filter_str(nick, length);
filter_string(nick, length, true);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand All @@ -159,7 +160,7 @@ void on_friend_status_message(Tox *tox, uint32_t friendnumber, const uint8_t *st

char msg[TOX_MAX_STATUS_MESSAGE_LENGTH + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) string, length);
filter_str(msg, length);
filter_string(msg, length, false);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand Down Expand Up @@ -266,7 +267,7 @@ void on_conference_peer_name(Tox *tox, uint32_t conferencenumber, uint32_t peern

char nick[TOXIC_MAX_NAME_LENGTH + 1];
length = copy_tox_str(nick, sizeof(nick), (const char *) name, length);
filter_str(nick, length);
filter_string(nick, length, true);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand All @@ -286,6 +287,7 @@ void on_conference_title(Tox *tox, uint32_t conferencenumber, uint32_t peernumbe

char data[MAX_STR_SIZE + 1];
length = copy_tox_str(data, sizeof(data), (const char *) title, length);
filter_string(data, length, false);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand Down Expand Up @@ -570,12 +572,14 @@ void on_group_peer_exit(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Gr

char toxic_nick[TOXIC_MAX_NAME_LENGTH + 1];
nick_len = copy_tox_str(toxic_nick, sizeof(toxic_nick), (const char *) nick, nick_len);
filter_string(toxic_nick, nick_len, true);

char buf[MAX_STR_SIZE + 1] = {0};
size_t buf_len = 0;

if (part_message) {
buf_len = copy_tox_str(buf, sizeof(buf), (const char *) part_message, length);
filter_string(buf, buf_len, false);
}

for (uint16_t i = 0; i < windows->count; ++i) {
Expand All @@ -597,6 +601,7 @@ void on_group_topic_change(Tox *tox, uint32_t groupnumber, uint32_t peer_id, con

char data[MAX_STR_SIZE + 1];
length = copy_tox_str(data, sizeof(data), (const char *) topic, length);
filter_string(data, length, false);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand Down Expand Up @@ -681,7 +686,7 @@ void on_group_nick_change(Tox *tox, uint32_t groupnumber, uint32_t peer_id, cons

char name[TOXIC_MAX_NAME_LENGTH + 1];
length = copy_tox_str(name, sizeof(name), (const char *) newname, length);
filter_str(name, length);
filter_string(name, length, true);

for (uint16_t i = 0; i < windows->count; ++i) {
ToxWindow *w = windows->list[i];
Expand Down

0 comments on commit 7ed06b0

Please sign in to comment.