merge/upstream-full #105
@@ -44,14 +44,3 @@
|
||||
|
||||
* Commit `Start new cycle`
|
||||
* Push
|
||||
|
||||
## Updating website
|
||||
Make changes to the git repo including uploading the new artefacts at:
|
||||
https://github.com/profanity-im/profanity-im.github.io
|
||||
|
||||
* Add .xz and .zip tarballs to `tarballs` directory
|
||||
* Copy generated main_fragment.html and toc_fragment.html to `guide/latest`
|
||||
* Copy `guide/latest` to `guide/newversion`
|
||||
* Tarball location, name, checksum in index.html will be updated automatically during `make` / GH Action
|
||||
* Update profanity_version.txt
|
||||
* Take results from profanity.doap and put them into xeps.html
|
||||
|
||||
@@ -313,25 +313,25 @@ gboolean
|
||||
strtoi_range(const char* str, int* saveptr, int min, int max, gchar** err_msg)
|
||||
{
|
||||
char* ptr;
|
||||
int val;
|
||||
long lval;
|
||||
if (str == NULL) {
|
||||
if (err_msg)
|
||||
*err_msg = g_strdup_printf("'str' input pointer can not be NULL");
|
||||
return FALSE;
|
||||
}
|
||||
errno = 0;
|
||||
val = (int)strtol(str, &ptr, 0);
|
||||
lval = strtol(str, &ptr, 0);
|
||||
if (errno != 0 || *str == '\0' || *ptr != '\0') {
|
||||
if (err_msg)
|
||||
*err_msg = g_strdup_printf("Could not convert \"%s\" to a number.", str);
|
||||
return FALSE;
|
||||
} else if (val < min || val > max) {
|
||||
} else if (lval < (long)min || lval > (long)max) {
|
||||
if (err_msg)
|
||||
*err_msg = g_strdup_printf("Value %s out of range. Must be in %d..%d.", str, min, max);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*saveptr = val;
|
||||
*saveptr = (int)lval;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -237,24 +237,16 @@ _name_to_tlscert_name_(const char* in, tls_cert_name_t* out, const char* name)
|
||||
}
|
||||
}
|
||||
|
||||
static gchar*
|
||||
_checked_g_strdup(const char* in)
|
||||
{
|
||||
if (in == NULL)
|
||||
return NULL;
|
||||
return g_strdup(in);
|
||||
}
|
||||
|
||||
TLSCertificate*
|
||||
tlscerts_new(const char* fingerprint_sha1, int version, const char* serialnumber, const char* subjectname,
|
||||
const char* issuername, const char* notbefore, const char* notafter,
|
||||
const char* key_alg, const char* signature_alg, const char* pem,
|
||||
const char* fingerprint_sha256, const char* pubkey_fingerprint)
|
||||
|
jabber.developer marked this conversation as resolved
|
||||
{
|
||||
return _tlscerts_new(_checked_g_strdup(fingerprint_sha1), version, _checked_g_strdup(serialnumber), _checked_g_strdup(subjectname),
|
||||
_checked_g_strdup(issuername), _checked_g_strdup(notbefore), _checked_g_strdup(notafter),
|
||||
_checked_g_strdup(key_alg), _checked_g_strdup(signature_alg), _checked_g_strdup(pem),
|
||||
_checked_g_strdup(fingerprint_sha256), _checked_g_strdup(pubkey_fingerprint));
|
||||
return _tlscerts_new(g_strdup(fingerprint_sha1), version, g_strdup(serialnumber), g_strdup(subjectname),
|
||||
g_strdup(issuername), g_strdup(notbefore), g_strdup(notafter),
|
||||
g_strdup(key_alg), g_strdup(signature_alg), g_strdup(pem),
|
||||
g_strdup(fingerprint_sha256), g_strdup(pubkey_fingerprint));
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -581,7 +581,8 @@ _add_to_db(ProfMessage* message, const char* type, const Jid* const from_jid, co
|
||||
if (rc == SQLITE_ROW) {
|
||||
log_debug("Successfully inserted message into database.");
|
||||
} else if (rc == SQLITE_DONE) {
|
||||
log_debug("Message already exists in database (archive_id: %s), skipping.", message->stanzaid);
|
||||
log_warning("Message already exists in database (archive_id: %s), skipping.", message->stanzaid);
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
It deserves at least It deserves at least `warning` level. We can't just silently not write message to log: the message might contain important information for user. The error also should be extremely rare and it should represent invalid state, so it makes sense to `cons_show_error` it to alert the user.
|
||||
cons_show_error("Duplicate message detected (archive_id: %s), skipping.", message->stanzaid);
|
||||
} else {
|
||||
log_error("SQLite error in _add_to_db() (step): %s", sqlite3_errmsg(g_chatlog_database));
|
||||
}
|
||||
@@ -758,7 +759,7 @@ _migrate_to_v3(void)
|
||||
|
||||
cleanup:
|
||||
if (SQLITE_OK != sqlite3_exec(g_chatlog_database, "ROLLBACK;", NULL, 0, &err_msg)) {
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
Why not?
Why not?
` log_error("[DB Migration] Unable to ROLLBACK: %s", err_msg);`
`[` is missing (likely a strange typo)
|
||||
log_error("DB Migration] Unable to ROLLBACK: %s", err_msg);
|
||||
log_error("[DB Migration] Unable to ROLLBACK: %s", err_msg);
|
||||
if (err_msg) {
|
||||
sqlite3_free(err_msg);
|
||||
}
|
||||
|
||||
@@ -525,25 +525,29 @@ omemo_set_device_list(const char* const from, GList* device_list)
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
auto_gchar gchar* dev_id_str = g_strdup_printf("%u", dev_id);
|
||||
if (!g_key_file_has_key(omemo_ctx.knowndevices.keyfile, jid->barejid, dev_id_str, NULL)) {
|
||||
if (equals_our_barejid(jid->barejid)) {
|
||||
if (dev_id != omemo_ctx.device_id) {
|
||||
cons_show("New OMEMO device (ID: %u) added to your account.", dev_id);
|
||||
}
|
||||
} else {
|
||||
ProfChatWin* chatwin = wins_get_chat(jid->barejid);
|
||||
if (chatwin) {
|
||||
win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid);
|
||||
} else {
|
||||
ProfMucWin* mucwin = wins_get_muc(jid->barejid);
|
||||
if (mucwin) {
|
||||
win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
auto_gchar gchar* dev_id_str = g_strdup_printf("%u", dev_id);
|
||||
if (g_key_file_has_key(omemo_ctx.knowndevices.keyfile, jid->barejid, dev_id_str, NULL))
|
||||
continue;
|
||||
|
||||
if (equals_our_barejid(jid->barejid)) {
|
||||
if (dev_id != omemo_ctx.device_id) {
|
||||
cons_show("New OMEMO device (ID: %u) added to your account.", dev_id);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ProfChatWin* chatwin = wins_get_chat(jid->barejid);
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
extremely excessive nesting extremely excessive nesting
|
||||
if (chatwin) {
|
||||
win_println((ProfWin*)chatwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid);
|
||||
continue;
|
||||
}
|
||||
|
||||
ProfMucWin* mucwin = wins_get_muc(jid->barejid);
|
||||
if (mucwin) {
|
||||
win_println((ProfWin*)mucwin, THEME_DEFAULT, "!", "New OMEMO device (ID: %u) found for %s.", dev_id, jid->barejid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,10 +399,9 @@ _search(Autocomplete ac, GList* curr, gboolean quote, search_direction direction
|
||||
|
||||
// We only use transliterated match if the search string conversion didn't result
|
||||
// in unknown characters ('?'), to avoid false matches between different scripts.
|
||||
if (strchr(search_str_ascii_lower, '?') == NULL) {
|
||||
if (g_str_has_prefix(curr_ascii_lower, search_str_ascii_lower)) {
|
||||
match = TRUE;
|
||||
}
|
||||
if (strchr(search_str_ascii_lower, '?') == NULL
|
||||
&& g_str_has_prefix(curr_ascii_lower, search_str_ascii_lower)) {
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
could be just could be just `&&` operator instead of nested condition
|
||||
match = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -246,9 +246,8 @@ editor_process(ProfWin* window)
|
||||
log_debug("[Editor] Exiting background mode");
|
||||
}
|
||||
|
||||
// Deprecated synchronous editor call. Returns a message as returned_message.
|
||||
// Please avoid using it, since it blocks execution of the message handling and other important functionality until the editor is closed.
|
||||
// Returns true if an error occurred
|
||||
// Returns a message via callback once the editor is closed.
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
need to remove this comment since it doesn't reflect new version of this method need to remove this comment since it doesn't reflect new version of this method
|
||||
// Returns true if an error occurred.
|
||||
gboolean
|
||||
launch_editor(gchar* initial_content, void (*callback)(gchar* content, void* data), void* user_data)
|
||||
{
|
||||
|
||||
@@ -417,9 +417,8 @@ _inp_write(char* line, int offset)
|
||||
end += next_ch_len;
|
||||
}
|
||||
|
||||
char* word = g_strndup(&line[start], end - start);
|
||||
auto_gchar gchar* word = g_strndup(&line[start], end - start);
|
||||
gboolean misspelled = spellcheck_is_misspelled(word);
|
||||
g_free(word);
|
||||
|
||||
if (misspelled) {
|
||||
wattron(inp_win, theme_attrs(THEME_INPUT_MISSPELLED));
|
||||
|
||||
@@ -45,6 +45,24 @@ static void _show_privacy(ProfChatWin* chatwin);
|
||||
static void _show_muc_privacy(ProfMucWin* mucwin);
|
||||
static void _show_scrolled(ProfWin* current);
|
||||
static void _show_attention(ProfWin* current, gboolean attention);
|
||||
static void _show_trust_indicator(gboolean trusted, int bracket_attrs, int trusted_attrs, int untrusted_attrs);
|
||||
|
||||
static inline void
|
||||
_wprintw_withattr(WINDOW* w, const char* text, int attrs)
|
||||
{
|
||||
wattron(w, attrs);
|
||||
wprintw(w, "%s", text);
|
||||
wattroff(w, attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
_show_trust_indicator(gboolean trusted, int bracket_attrs, int trusted_attrs, int untrusted_attrs)
|
||||
{
|
||||
wprintw(win, " ");
|
||||
_wprintw_withattr(win, "[", bracket_attrs);
|
||||
_wprintw_withattr(win, trusted ? "trusted" : "untrusted", trusted ? trusted_attrs : untrusted_attrs);
|
||||
_wprintw_withattr(win, "]", bracket_attrs);
|
||||
}
|
||||
|
||||
void
|
||||
create_title_bar(void)
|
||||
@@ -433,29 +451,7 @@ _show_muc_privacy(ProfMucWin* mucwin)
|
||||
wattroff(win, bracket_attrs);
|
||||
|
||||
#ifdef HAVE_OMEMO
|
||||
if (mucwin->omemo_trusted) {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, trusted_attrs);
|
||||
wprintw(win, "trusted");
|
||||
wattroff(win, trusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
} else {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, untrusted_attrs);
|
||||
wprintw(win, "untrusted");
|
||||
wattroff(win, untrusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
}
|
||||
_show_trust_indicator(mucwin->omemo_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
|
||||
#endif
|
||||
|
||||
return;
|
||||
@@ -524,29 +520,7 @@ _show_privacy(ProfChatWin* chatwin)
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
if (chatwin->otr_is_trusted) {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, trusted_attrs);
|
||||
wprintw(win, "trusted");
|
||||
wattroff(win, trusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
} else {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, untrusted_attrs);
|
||||
wprintw(win, "untrusted");
|
||||
wattroff(win, untrusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
}
|
||||
_show_trust_indicator(chatwin->otr_is_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -588,29 +562,7 @@ _show_privacy(ProfChatWin* chatwin)
|
||||
wattroff(win, bracket_attrs);
|
||||
|
||||
#ifdef HAVE_OMEMO
|
||||
if (chatwin->omemo_trusted) {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, trusted_attrs);
|
||||
wprintw(win, "trusted");
|
||||
wattroff(win, trusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
} else {
|
||||
wprintw(win, " ");
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "[");
|
||||
wattroff(win, bracket_attrs);
|
||||
wattron(win, untrusted_attrs);
|
||||
wprintw(win, "untrusted");
|
||||
wattroff(win, untrusted_attrs);
|
||||
wattron(win, bracket_attrs);
|
||||
wprintw(win, "]");
|
||||
wattroff(win, bracket_attrs);
|
||||
}
|
||||
_show_trust_indicator(chatwin->omemo_trusted, bracket_attrs, trusted_attrs, untrusted_attrs);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
@@ -65,11 +65,30 @@ static void _handle_pubsub(xmpp_stanza_t* const stanza, xmpp_stanza_t* const eve
|
||||
static gboolean _handle_form(xmpp_stanza_t* const stanza);
|
||||
static gboolean _handle_jingle_message(xmpp_stanza_t* const stanza);
|
||||
static gboolean _should_ignore_based_on_silence(xmpp_stanza_t* const stanza);
|
||||
#ifdef HAVE_OMEMO
|
||||
static void _receive_omemo(xmpp_stanza_t* const stanza, ProfMessage* message);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBGPGME
|
||||
static xmpp_stanza_t* _ox_openpgp_signcrypt(xmpp_ctx_t* ctx, const char* const to, const char* const text);
|
||||
#endif // HAVE_LIBGPGME
|
||||
|
||||
#ifdef HAVE_OMEMO
|
||||
static void
|
||||
_receive_omemo(xmpp_stanza_t* const stanza, ProfMessage* message)
|
||||
{
|
||||
message->plain = omemo_receive_message(stanza, &message->trusted, &message->omemo_err);
|
||||
if (message->omemo_err != OMEMO_ERR_NONE) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
if (message->plain == NULL) {
|
||||
message->plain = omemo_error_to_string(message->omemo_err);
|
||||
}
|
||||
} else if (message->plain != NULL) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
}
|
||||
}
|
||||
#endif // HAVE_OMEMO
|
||||
|
||||
static GHashTable* pubsub_event_handlers;
|
||||
|
||||
gchar*
|
||||
@@ -1088,15 +1107,7 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
|
||||
|
||||
// check omemo encryption
|
||||
#ifdef HAVE_OMEMO
|
||||
message->plain = omemo_receive_message(stanza, &message->trusted, &message->omemo_err);
|
||||
if (message->omemo_err != OMEMO_ERR_NONE) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
if (message->plain == NULL) {
|
||||
message->plain = omemo_error_to_string(message->omemo_err);
|
||||
}
|
||||
} else if (message->plain != NULL) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
}
|
||||
_receive_omemo(stanza, message);
|
||||
#endif
|
||||
|
||||
if (!message->plain && !message->body) {
|
||||
@@ -1253,15 +1264,7 @@ _handle_muc_private_message(xmpp_stanza_t* const stanza)
|
||||
|
||||
// check omemo encryption
|
||||
#ifdef HAVE_OMEMO
|
||||
message->plain = omemo_receive_message(stanza, &message->trusted, &message->omemo_err);
|
||||
if (message->omemo_err != OMEMO_ERR_NONE) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
if (message->plain == NULL) {
|
||||
message->plain = omemo_error_to_string(message->omemo_err);
|
||||
}
|
||||
} else if (message->plain != NULL) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
}
|
||||
_receive_omemo(stanza, message);
|
||||
#endif
|
||||
|
||||
message->timestamp = stanza_get_delay(stanza);
|
||||
@@ -1428,15 +1431,7 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c
|
||||
|
||||
#ifdef HAVE_OMEMO
|
||||
// check omemo encryption
|
||||
message->plain = omemo_receive_message(stanza, &message->trusted, &message->omemo_err);
|
||||
if (message->omemo_err != OMEMO_ERR_NONE) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
if (message->plain == NULL) {
|
||||
message->plain = omemo_error_to_string(message->omemo_err);
|
||||
}
|
||||
} else if (message->plain != NULL) {
|
||||
message->enc = PROF_MSG_ENC_OMEMO;
|
||||
}
|
||||
_receive_omemo(stanza, message);
|
||||
#endif
|
||||
|
||||
xmpp_stanza_t* encrypted = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_ENCRYPTED);
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
this code is duplicated 3 times. this code is duplicated 3 times.
|
||||
|
||||
@@ -708,7 +708,7 @@ _omemo_bundle_publish_configure_result(xmpp_stanza_t* const stanza, void* const
|
||||
return 0;
|
||||
}
|
||||
|
||||
char*
|
||||
gchar*
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
It should be It should be `gchar*`
|
||||
omemo_error_to_string(omemo_error_t error)
|
||||
{
|
||||
switch (error) {
|
||||
|
||||
@@ -19,4 +19,4 @@ void omemo_bundle_request(const char* const jid, uint32_t device_id, ProfIqCallb
|
||||
int omemo_start_device_session_handle_bundle(xmpp_stanza_t* const stanza, void* const userdata);
|
||||
|
||||
char* omemo_receive_message(xmpp_stanza_t* const stanza, gboolean* trusted, omemo_error_t* error) __attribute__((nonnull(2, 3)));
|
||||
char* omemo_error_to_string(omemo_error_t error);
|
||||
gchar* omemo_error_to_string(omemo_error_t error);
|
||||
|
||||
@@ -70,7 +70,9 @@ resource_destroy(Resource* resource)
|
||||
{
|
||||
if (resource) {
|
||||
g_free(resource->name);
|
||||
resource->name = NULL;
|
||||
g_free(resource->status);
|
||||
|
jabber.developer marked this conversation as resolved
jabber.developer
commented
we should set it to NULL for safety we should set it to NULL for safety
jabber.developer
commented
it wasn't addressed. The pointer still is not set to it wasn't addressed. The pointer still is not set to `null`, though with this function we can't actually do it, I guess. We need to pass pointer to pointer to actually do it. Instead, we can at least set it to null near each call to `resource_destroy`.
jabber.developer2
commented
|
||||
resource->status = NULL;
|
||||
g_free(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/strophe/libstrophe.git
|
||||
url = https://git.jabber.space/devs/libstrophe-gh.git
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
We might want to point to our fork We might want to point to our fork
jabber.developer2
commented
Done — wrap now points at Done — wrap now points at `devs/libstrophe-gh-mirror` (live auto-mirror, 8h). 1e372f6fa.
|
||||
revision = HEAD
|
||||
patch_directory = libstrophe
|
||||
|
||||
@@ -17,7 +17,7 @@ _create_test_file(const char* path)
|
||||
}
|
||||
|
||||
void
|
||||
cmd_ac_complete_filepath__segfaults_when_empty(void** state)
|
||||
cmd_ac_complete_filepath__no_segfault_when_empty(void** state)
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
*Wouldn't it also result in a CI failure? `segfaults_when_empty`? Is it an actual behavior*? Or is it what we try to avoid? It's either a really strange test that expects undesired behavior or poor choice of a test name
\*Wouldn't it also result in a CI failure?
|
||||
{
|
||||
char* result = cmd_ac_complete_filepath("/sendfile ", "/sendfile", FALSE);
|
||||
|
||||
@@ -62,33 +62,44 @@ cmd_ac_complete_filepath__cycles_through_files(void** state)
|
||||
mkdir("test_dir", 0755);
|
||||
_create_test_file("test_dir/file1.txt");
|
||||
_create_test_file("test_dir/file2.txt");
|
||||
_create_test_file("test_dir/file3.txt");
|
||||
|
||||
// 1st TAB
|
||||
// TAB forward: file1 -> file2 -> file3
|
||||
char* res1 = cmd_ac_complete_filepath("/sendfile test_dir/file", "/sendfile", FALSE);
|
||||
assert_non_null(res1);
|
||||
assert_string_equal(res1, "/sendfile test_dir/file1.txt");
|
||||
|
||||
// 2nd TAB
|
||||
char* res2 = cmd_ac_complete_filepath(res1, "/sendfile", FALSE);
|
||||
assert_non_null(res2);
|
||||
assert_string_equal(res2, "/sendfile test_dir/file2.txt");
|
||||
|
||||
// 3rd TAB
|
||||
char* res3 = cmd_ac_complete_filepath(res2, "/sendfile", FALSE);
|
||||
assert_non_null(res3);
|
||||
assert_string_equal(res3, "/sendfile test_dir/file1.txt");
|
||||
assert_string_equal(res3, "/sendfile test_dir/file3.txt");
|
||||
|
||||
// SHIFT-TAB
|
||||
char* res4 = cmd_ac_complete_filepath(res3, "/sendfile", TRUE);
|
||||
// TAB wraps around: file3 -> file1
|
||||
char* res4 = cmd_ac_complete_filepath(res3, "/sendfile", FALSE);
|
||||
|
jabber.developer marked this conversation as resolved
Outdated
jabber.developer
commented
This case doesn't test much :) Whether This case doesn't test much :) Whether `tab` or `shift+tab`, we'll get `file2.txt`. We need at least 3 files to make an actual test.
|
||||
assert_non_null(res4);
|
||||
assert_string_equal(res4, "/sendfile test_dir/file2.txt");
|
||||
assert_string_equal(res4, "/sendfile test_dir/file1.txt");
|
||||
|
||||
// SHIFT-TAB goes backward: file1 -> file3, then file3 -> file2
|
||||
char* res5 = cmd_ac_complete_filepath(res4, "/sendfile", TRUE);
|
||||
assert_non_null(res5);
|
||||
assert_string_equal(res5, "/sendfile test_dir/file3.txt");
|
||||
|
||||
char* res6 = cmd_ac_complete_filepath(res5, "/sendfile", TRUE);
|
||||
assert_non_null(res6);
|
||||
assert_string_equal(res6, "/sendfile test_dir/file2.txt");
|
||||
|
||||
free(res1);
|
||||
free(res2);
|
||||
free(res3);
|
||||
free(res4);
|
||||
free(res5);
|
||||
free(res6);
|
||||
|
||||
remove("test_dir/file1.txt");
|
||||
remove("test_dir/file2.txt");
|
||||
remove("test_dir/file3.txt");
|
||||
rmdir("test_dir");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef TESTS_TEST_CMD_AC_H
|
||||
#define TESTS_TEST_CMD_AC_H
|
||||
|
||||
void cmd_ac_complete_filepath__segfaults_when_empty(void** state);
|
||||
void cmd_ac_complete_filepath__no_segfault_when_empty(void** state);
|
||||
void cmd_ac_complete_filepath__finds_files_in_current_dir(void** state);
|
||||
void cmd_ac_complete_filepath__finds_files_with_dot_slash(void** state);
|
||||
void cmd_ac_complete_filepath__cycles_through_files(void** state);
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "xmpp/resource.h"
|
||||
#include "common.h"
|
||||
#include "prof_cmocka.h"
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "tests/unittests/ui/stub_ui.h" // Include for mocking cons_show
|
||||
|
||||
@@ -519,6 +521,63 @@ strtoi_range__returns__correct_values_when_err_msg_null(void** state)
|
||||
assert_false(result);
|
||||
}
|
||||
|
||||
void
|
||||
strtoi_range__returns__false_for_integer_overflow_underflow(void** state)
|
||||
{
|
||||
int value;
|
||||
gchar* err_msg = NULL;
|
||||
gboolean result;
|
||||
char buf[64];
|
||||
|
||||
// INT_MAX + 1 overflows
|
||||
snprintf(buf, sizeof(buf), "%lld", (long long)INT_MAX + 1);
|
||||
result = strtoi_range(buf, &value, INT_MIN, INT_MAX, &err_msg);
|
||||
assert_false(result);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
|
||||
// INT_MIN - 1 underflows
|
||||
snprintf(buf, sizeof(buf), "%lld", (long long)INT_MIN - 1);
|
||||
result = strtoi_range(buf, &value, INT_MIN, INT_MAX, &err_msg);
|
||||
assert_false(result);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
|
||||
// Extreme overflow, larger than `long`
|
||||
result = strtoi_range("9999999999999999999999999999999999", &value, INT_MIN, INT_MAX, &err_msg);
|
||||
assert_false(result);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
strtoi_range__returns_consistent_with_strtol_parsing(void** state)
|
||||
{
|
||||
int value;
|
||||
gchar* err_msg = NULL;
|
||||
gboolean result;
|
||||
|
||||
// Hexadecimal: "0x10" -> 16
|
||||
result = strtoi_range("0x10", &value, 0, 100, &err_msg);
|
||||
assert_true(result);
|
||||
assert_int_equal(16, value);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
|
||||
// Octal: "010" -> 8
|
||||
result = strtoi_range("010", &value, 0, 100, &err_msg);
|
||||
assert_true(result);
|
||||
assert_int_equal(8, value);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
|
||||
// Floating point "0.8" should fail: '.' is not a valid integer char
|
||||
result = strtoi_range("0.8", &value, -10, 10, &err_msg);
|
||||
assert_false(result);
|
||||
g_free(err_msg);
|
||||
err_msg = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
string_to_verbosity__returns__correct_values(void** state)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,8 @@ void strtoi_range__returns__false_for_out_of_range(void** state);
|
||||
void strtoi_range__returns__false_for_invalid_input(void** state);
|
||||
void strtoi_range__returns__false_for_null_empty_input(void** state);
|
||||
void strtoi_range__returns__correct_values_when_err_msg_null(void** state);
|
||||
void strtoi_range__returns__false_for_integer_overflow_underflow(void** state);
|
||||
void strtoi_range__returns_consistent_with_strtol_parsing(void** state);
|
||||
void string_matches_one_of__tests__edge_cases(void** state);
|
||||
void valid_tls_policy_option__is__correct_for_various_inputs(void** state);
|
||||
void get_mentions__tests__various(void** state);
|
||||
|
||||
@@ -107,7 +107,7 @@ main(int argc, char* argv[])
|
||||
cmocka_unit_test(unique_filename_from_url__tests__table_driven),
|
||||
cmocka_unit_test(string_to_verbosity__returns__correct_values),
|
||||
cmocka_unit_test(get_expanded_path__returns__expanded),
|
||||
cmocka_unit_test_setup_teardown(cmd_ac_complete_filepath__segfaults_when_empty, load_preferences, close_preferences),
|
||||
cmocka_unit_test_setup_teardown(cmd_ac_complete_filepath__no_segfault_when_empty, load_preferences, close_preferences),
|
||||
cmocka_unit_test_setup_teardown(cmd_ac_complete_filepath__finds_files_in_current_dir, load_preferences, close_preferences),
|
||||
cmocka_unit_test_setup_teardown(cmd_ac_complete_filepath__finds_files_with_dot_slash, load_preferences, close_preferences),
|
||||
cmocka_unit_test_setup_teardown(cmd_ac_complete_filepath__cycles_through_files, load_preferences, close_preferences),
|
||||
@@ -116,6 +116,8 @@ main(int argc, char* argv[])
|
||||
cmocka_unit_test(strtoi_range__returns__false_for_invalid_input),
|
||||
cmocka_unit_test(strtoi_range__returns__false_for_null_empty_input),
|
||||
cmocka_unit_test(strtoi_range__returns__correct_values_when_err_msg_null),
|
||||
cmocka_unit_test(strtoi_range__returns__false_for_integer_overflow_underflow),
|
||||
cmocka_unit_test(strtoi_range__returns_consistent_with_strtol_parsing),
|
||||
cmocka_unit_test(string_matches_one_of__tests__edge_cases),
|
||||
cmocka_unit_test(valid_tls_policy_option__is__correct_for_various_inputs),
|
||||
cmocka_unit_test(autocomplete_complete__returns__null_when_empty),
|
||||
@@ -175,6 +177,7 @@ main(int argc, char* argv[])
|
||||
cmocka_unit_test(jid_create__returns__null_from_multiple_at_in_bare),
|
||||
cmocka_unit_test(jid_create__returns__correct_parts_with_at_in_resource_only),
|
||||
cmocka_unit_test(jid_is_valid_user_jid__is__true_for_valid_user_jid),
|
||||
cmocka_unit_test(jid_is_valid_user_jid__is__true_for_at_in_resource),
|
||||
cmocka_unit_test(jid_is_valid_user_jid__is__false_for_domain_jid),
|
||||
cmocka_unit_test(jid_is_valid_user_jid__is__false_for_invalid_jid),
|
||||
cmocka_unit_test(jid_is_valid__is__true_for_valid_jid),
|
||||
|
||||
@@ -319,6 +319,14 @@ jid_is_valid_user_jid__is__true_for_valid_user_jid(void** state)
|
||||
assert_true(jid_is_valid_user_jid("myuser@mydomain"));
|
||||
}
|
||||
|
||||
void
|
||||
jid_is_valid_user_jid__is__true_for_at_in_resource(void** state)
|
||||
{
|
||||
// RFC 6122 section 2.4: '@' is allowed in the resourcepart.
|
||||
assert_true(jid_is_valid_user_jid("myuser@mydomain/user@laptop"));
|
||||
assert_true(jid_is_valid_user_jid("room@conference.example.org/user@host.example.org"));
|
||||
}
|
||||
|
||||
void
|
||||
jid_is_valid_user_jid__is__false_for_domain_jid(void** state)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ void jid_create__returns__null_from_empty_parts(void** state);
|
||||
void jid_create__returns__null_from_multiple_at_in_bare(void** state);
|
||||
void jid_create__returns__correct_parts_with_at_in_resource_only(void** state);
|
||||
void jid_is_valid_user_jid__is__true_for_valid_user_jid(void** state);
|
||||
void jid_is_valid_user_jid__is__true_for_at_in_resource(void** state);
|
||||
void jid_is_valid_user_jid__is__false_for_domain_jid(void** state);
|
||||
void jid_is_valid_user_jid__is__false_for_invalid_jid(void** state);
|
||||
void jid_is_valid__is__true_for_valid_jid(void** state);
|
||||
|
||||
Why though?
According to official doc,
g_strdup:Though maybe earlier glib versions are less safe...