All checks were successful
CI Code / Check spelling (pull_request) Successful in 14s
CI Code / Check coding style (pull_request) Successful in 26s
CI Code / Code Coverage (pull_request) Successful in 3m29s
CI Code / Linux (debian) (pull_request) Successful in 5m13s
CI Code / Linux (ubuntu) (pull_request) Successful in 5m16s
CI Code / Linux (arch) (pull_request) Successful in 7m34s
T02: guard the receive-path handlers that dereferenced jid_create() without a NULL check — MUC join errors, subscribed/unsubscribed presence and, with silence.non-roster enabled, every incoming message. A stanza with a missing or malformed 'from' crashed the client (REQ-INP-01) T11: restrict /url open and /url save to http, https and aesgcm, so a received file:, javascript: or data: URL is refused (REQ-INP-06); spawn terminal-notifier through g_spawn_async with an argv instead of building a shell command for system() (REQ-INP-07); apply the XEP-0359 disco gate to MAM result ids, as live stanza-ids already do (REQ-INP-05); replace control and bidi-reordering characters in incoming message bodies with U+FFFD before they reach the terminal, the logs and the database, keeping LRM/RLM for legitimate RTL text (REQ-INP-08); cover JID part-length boundaries and invalid UTF-8 (REQ-INP-02) T10: replace strcpy/strcat/alloca and sprintf with g_strdup_printf and g_snprintf (REQ-MEM-03); allocate the OMEMO key buffers with g_malloc so a failed allocation cannot reach the following memcpy (REQ-MEM-04); remove the variable-length arrays and enforce -Werror=vla. Two of them were sized from remote input: the disco#info feature count and a chat message word length. The flag also caught a one-past-the-end write and a leak in the plugin autocompleter bindings (REQ-MEM-09)
152 lines
5.0 KiB
C
152 lines
5.0 KiB
C
#include <glib.h>
|
|
#include "prof_cmocka.h"
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <stabber.h>
|
|
|
|
#include "proftest.h"
|
|
|
|
void
|
|
message_send(void **state)
|
|
{
|
|
prof_connect();
|
|
|
|
prof_input("/msg somejid@someserver.com Hi there");
|
|
|
|
assert_true(stbbr_received(
|
|
"<message id='*' to='somejid@someserver.com' type='chat'>"
|
|
"<body>Hi there</body>"
|
|
"</message>"
|
|
));
|
|
|
|
assert_true(prof_output_regex("me: .+Hi there"));
|
|
}
|
|
|
|
// TODO: `/message correct` XEP-0308 compliance (whether each correction links to the original message ID)
|
|
// https://xmpp.org/extensions/xep-0308.html#rules
|
|
|
|
void
|
|
message_receive_console(void **state)
|
|
{
|
|
prof_connect();
|
|
|
|
stbbr_send(
|
|
"<message id='message1' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>How are you?</body>"
|
|
"</message>"
|
|
);
|
|
|
|
assert_true(prof_output_exact("<< chat message: someuser@chatserv.org/laptop (win 2)"));
|
|
}
|
|
|
|
void
|
|
message_receive_chatwin(void **state)
|
|
{
|
|
prof_connect();
|
|
|
|
prof_input("/msg someuser@chatserv.org");
|
|
assert_true(prof_output_exact("someuser@chatserv.org"));
|
|
|
|
stbbr_send(
|
|
"<message id='message1' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>How are you?</body>"
|
|
"</message>"
|
|
);
|
|
|
|
assert_true(prof_output_regex("someuser@chatserv.org/laptop: .+How are you?"));
|
|
}
|
|
|
|
// XEP-0359 disco gate: server announces urn:xmpp:sid:0 -> stanza-id trusted -> replay flagged as duplicate.
|
|
void
|
|
stanza_id_dedup_fires_when_server_announces_sid0(void **state)
|
|
{
|
|
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
|
"<iq type='result' to='stabber@localhost/profanity' from='localhost'>"
|
|
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
|
"<identity category='server' type='im' name='TestServer'/>"
|
|
"<feature var='urn:xmpp:sid:0'/>"
|
|
"</query>"
|
|
"</iq>"
|
|
);
|
|
|
|
prof_connect();
|
|
|
|
stbbr_send(
|
|
"<message id='m-trust-1' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>first</body>"
|
|
"<stanza-id xmlns='urn:xmpp:sid:0' by='stabber@localhost' id='archive-id-42'/>"
|
|
"</message>"
|
|
);
|
|
assert_true(prof_output_exact("<< chat message: someuser@chatserv.org/laptop (win 2)"));
|
|
|
|
stbbr_send(
|
|
"<message id='m-trust-2' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>replay</body>"
|
|
"<stanza-id xmlns='urn:xmpp:sid:0' by='stabber@localhost' id='archive-id-42'/>"
|
|
"</message>"
|
|
);
|
|
assert_true(prof_output_exact("Got a message with duplicate (server-generated) stanza-id from someuser@chatserv.org/laptop."));
|
|
}
|
|
|
|
// XEP-0359 disco gate: server does NOT announce urn:xmpp:sid:0 -> stanza-id untrusted -> no replay error.
|
|
void
|
|
stanza_id_not_trusted_when_server_does_not_announce_sid0(void **state)
|
|
{
|
|
stbbr_for_query("http://jabber.org/protocol/disco#info",
|
|
"<iq type='result' to='stabber@localhost/profanity' from='localhost'>"
|
|
"<query xmlns='http://jabber.org/protocol/disco#info'>"
|
|
"<identity category='server' type='im' name='TestServer'/>"
|
|
"<feature var='urn:xmpp:ping'/>"
|
|
"</query>"
|
|
"</iq>"
|
|
);
|
|
|
|
prof_connect();
|
|
|
|
stbbr_send(
|
|
"<message id='m-untrust-1' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>first</body>"
|
|
"<stanza-id xmlns='urn:xmpp:sid:0' by='stabber@localhost' id='archive-id-77'/>"
|
|
"</message>"
|
|
);
|
|
assert_true(prof_output_exact("<< chat message: someuser@chatserv.org/laptop (win 2)"));
|
|
|
|
stbbr_send(
|
|
"<message id='m-untrust-2' to='stabber@localhost' from='someuser@chatserv.org/laptop' type='chat'>"
|
|
"<body>replay</body>"
|
|
"<stanza-id xmlns='urn:xmpp:sid:0' by='stabber@localhost' id='archive-id-77'/>"
|
|
"</message>"
|
|
);
|
|
|
|
prof_timeout(2);
|
|
assert_false(prof_output_exact("Got a message with duplicate (server-generated) stanza-id"));
|
|
prof_timeout_reset();
|
|
}
|
|
|
|
/* Regression test for issue #148 (REQ-INP-01): with silence.non-roster
|
|
* enabled the incoming-message filter dereferenced jid_create() without a
|
|
* NULL check, so a message with an invalid 'from' crashed the client. */
|
|
void
|
|
message_invalid_from_silence_no_crash(void **state)
|
|
{
|
|
prof_connect();
|
|
|
|
prof_input("/silence on");
|
|
assert_true(prof_output_exact("Block all messages from JIDs that are not in the roster enabled."));
|
|
|
|
stbbr_send(
|
|
"<message to='stabber@localhost' from='bad@@jid' type='chat'>"
|
|
"<body>should be dropped, not crash</body>"
|
|
"</message>"
|
|
);
|
|
|
|
/* client is still alive: a roster contact's message comes through */
|
|
stbbr_send(
|
|
"<message to='stabber@localhost' from='buddy1@localhost/mobile' type='chat'>"
|
|
"<body>still alive</body>"
|
|
"</message>"
|
|
);
|
|
assert_true(prof_output_exact("<< chat message: Buddy1/mobile (win 2)"));
|
|
}
|