Skip to content

Commit

Permalink
Merge pull request #14 from Lihis/fix-parameter-with-semicolon
Browse files Browse the repository at this point in the history
Fix message parse/string with single parameter containing semicolon
  • Loading branch information
n0la authored Nov 5, 2023
2 parents cf8f753 + 3c3bf75 commit 21c7e69
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
14 changes: 8 additions & 6 deletions lib/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,14 @@ static void irc_message_add2(char ***ac, size_t *av, char const *s)
irc_strv_add(ac, av, dup);
}

static void irc_message_add(char ***ac, size_t *av, strbuf_t b)
static void irc_message_add(char ***ac, size_t *av, strbuf_t b, bool final)
{
char *dup = NULL;

if (strbuf_getc(b) == ':') {
strbuf_delete(b, 1);
if (final == false) {
if (strbuf_getc(b) == ':') {
strbuf_delete(b, 1);
}
}

dup = strbuf_strdup(b);
Expand Down Expand Up @@ -194,7 +196,7 @@ irc_error_t irc_message_parse(irc_message_t c, char const *l, size_t len)
/* Check if their is remaining argument
*/
if (argbuf) {
irc_message_add(&args, &argslen, argbuf);
irc_message_add(&args, &argslen, argbuf, final);
}

c->prefix = prefix;
Expand Down Expand Up @@ -339,9 +341,9 @@ irc_error_t irc_message_string(irc_message_t m, char **s, size_t *slen)
if (m->args) {
for (tmp = m->args; *tmp != NULL; ++tmp) {
size_t tmplen = strlen(*tmp);
/* if we find a space we add a `:`
/* if we find a space or argument starts with `:` we add a `:`
*/
if (strchr(*tmp, ' ') != NULL) {
if (strchr(*tmp, ' ') != NULL || *tmp[0] == ':') {
strbuf_append(buf, ":", 1);
}
strbuf_append(buf, *tmp, tmplen);
Expand Down
52 changes: 48 additions & 4 deletions tests/test_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void test_message_parse_with_parameter_containing_spaces(void **data)
irc_error_t error = irc_error_internal;

error = irc_message_parse(m, str, -1);
assert_return_code (error, irc_error_success);
assert_return_code(error, irc_error_success);
assert_string_equal(m->prefix, "guest");
assert_string_equal(m->command, "PRIVMSG");
assert_int_equal(m->argslen, 2);
Expand All @@ -43,6 +43,25 @@ static void test_message_parse_with_parameter_containing_spaces(void **data)
irc_message_unref(m);
}

static void test_message_parse_with_final_starting_with_semicolon(void **data)
{
irc_message_t m = irc_message_new();
const char *str = ":guest PRIVMSG #channel ::-)";
irc_error_t error = irc_error_internal;

error = irc_message_parse(m, str, -1);
assert_return_code(error, irc_error_success);
assert_string_equal(m->prefix, "guest");
assert_string_equal(m->command, "PRIVMSG");
assert_int_equal(m->argslen, 2);
assert_string_equal(m->args[0], "#channel");
assert_string_equal(m->args[1], ":-)");
assert_int_equal(m->tagslen, 0);
assert_ptr_equal(m->tags, NULL);

irc_message_unref(m);
}

static void test_message_parse_with_parameters(void **data)
{
irc_message_t m = irc_message_new();
Expand Down Expand Up @@ -135,12 +154,35 @@ static void test_message_string_with_semicolon(void **data)

// Pass length minus the "\r\n"
error = irc_message_parse(m, expected, strlen(expected) - 2);
assert_int_equal (m->argslen, 2);
assert_int_equal(m->argslen, 2);
assert_string_equal(m->args[0], "#channel");
assert_string_equal(m->args[1], "A smiley :) and text");
assert_return_code (error, irc_error_success);
assert_return_code(error, irc_error_success);

error = irc_message_string(m, &actual, &len);
assert_return_code (error, irc_error_success);
assert_return_code(error, irc_error_success);
assert_string_equal(actual, expected);

free(actual);
irc_message_unref(m);
}

static void test_message_string_with_final_param_semicolon(void **data)
{
irc_message_t m = irc_message_new();
const char *expected = ":prefix PRIVMSG #channel ::-)\r\n";
irc_error_t error = irc_error_internal;
char *actual = NULL;
size_t len = 0;

error = irc_message_parse(m, expected, strlen(expected) - 2);
assert_int_equal(m->argslen, 2);
assert_string_equal(m->args[0], "#channel");
assert_string_equal(m->args[1], ":-)");
assert_return_code(error, irc_error_success);

error = irc_message_string(m, &actual, &len);
assert_return_code(error, irc_error_success);
assert_string_equal(actual, expected);

free(actual);
Expand All @@ -152,11 +194,13 @@ int main(int ac, char **av)
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_message_parse_without_tag),
cmocka_unit_test(test_message_parse_with_parameter_containing_spaces),
cmocka_unit_test(test_message_parse_with_final_starting_with_semicolon),
cmocka_unit_test(test_message_parse_with_parameters),
cmocka_unit_test(test_message_parse_with_single_tag),
cmocka_unit_test(test_message_parse_with_multiple_tag),
cmocka_unit_test(test_message_string),
cmocka_unit_test(test_message_string_with_semicolon),
cmocka_unit_test(test_message_string_with_final_param_semicolon),
};

return cmocka_run_group_tests(tests, NULL, NULL);
Expand Down

0 comments on commit 21c7e69

Please sign in to comment.