Merge branch 'hexchat:master' into master

This commit is contained in:
veganaiZe 2022-04-15 11:34:57 -07:00 committed by GitHub
commit 319e7b411e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 187 additions and 52 deletions

View File

@ -1,7 +1,7 @@
name: Flatpak Build name: Flatpak Build
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: flatpak_build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: bilelmoussaoui/flatpak-github-actions:gnome-40 image: bilelmoussaoui/flatpak-github-actions:gnome-40

View File

@ -2,7 +2,7 @@ name: MSYS2 Build
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: msys2_build:
runs-on: windows-latest runs-on: windows-latest
defaults: defaults:
run: run:

View File

@ -1,7 +1,7 @@
name: Ubuntu Build name: Ubuntu Build
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: ubuntu_build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:

View File

@ -2,7 +2,7 @@ name: Windows Build
on: [push, pull_request] on: [push, pull_request]
jobs: jobs:
build: windows_build:
runs-on: windows-2019 runs-on: windows-2019
strategy: strategy:
matrix: matrix:

View File

@ -26,6 +26,19 @@
<id>hexchat.desktop</id> <id>hexchat.desktop</id>
</provides> </provides>
<releases> <releases>
<release date="2022-02-12" version="2.16.1">
<description>
<p>This is a minor release with mostly bug-fixes:</p>
<ul>
<li>Add `-NOOVERRIDE` flag to the `GUI COLOR` command</li>
<li>Add `-q` (quiet) flag to the `EXECWRITE` command</li>
<li>Rename installed icon to match app-id (Fixes notification icon)</li>
<li>Fix escaping already escaped URLs when opening them</li>
<li>Fix Python scripts not being opened as UTF-8</li>
<li>Fix `TIMER` command supporting decimals regardless of locale</li>
</ul>
</description>
</release>
<release date="2021-10-01" version="2.16.0"> <release date="2021-10-01" version="2.16.0">
<description> <description>
<p>This is a feature release:</p> <p>This is a feature release:</p>

View File

@ -1,5 +1,5 @@
project('hexchat', 'c', project('hexchat', 'c',
version: '2.16.0', version: '2.16.1',
meson_version: '>= 0.47.0', meson_version: '>= 0.47.0',
default_options: [ default_options: [
'c_std=gnu89', 'c_std=gnu89',
@ -34,6 +34,7 @@ config_h.set_quoted('PACKAGE_NAME', meson.project_name())
config_h.set_quoted('GETTEXT_PACKAGE', 'hexchat') config_h.set_quoted('GETTEXT_PACKAGE', 'hexchat')
config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'),
get_option('datadir'), 'locale')) get_option('datadir'), 'locale'))
config_h.set_quoted('G_LOG_DOMAIN', 'hexchat')
config_h.set10('ENABLE_NLS', true) config_h.set10('ENABLE_NLS', true)
# Optional features # Optional features

View File

@ -3,4 +3,5 @@ shared_module('checksum', 'checksum.c',
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'checksum.def',
) )

View File

@ -1,5 +1,6 @@
shared_module('exec', 'exec.c', shared_module('exec', 'exec.c',
dependencies: hexchat_plugin_dep, dependencies: hexchat_plugin_dep,
install: true, install: true,
install_dir: plugindir install_dir: plugindir,
vs_module_defs: 'exec.def',
) )

View File

@ -87,6 +87,54 @@ static const signed char fish_unbase64[256] = {
dest |= (uint8_t)*((source)++); \ dest |= (uint8_t)*((source)++); \
} while (0); } while (0);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/provider.h>
static OSSL_PROVIDER *legacy_provider;
static OSSL_PROVIDER *default_provider;
static OSSL_LIB_CTX* *ossl_ctx;
#endif
int fish_init(void)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
ossl_ctx = OSSL_LIB_CTX_new();
if (!ossl_ctx)
return 0;
legacy_provider = OSSL_PROVIDER_load(ossl_ctx, "legacy");
if (!legacy_provider) {
fish_deinit();
return 0;
}
default_provider = OSSL_PROVIDER_load(ossl_ctx, "default");
if (!default_provider) {
fish_deinit();
return 0;
}
#endif
return 1;
}
void fish_deinit(void)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (legacy_provider) {
OSSL_PROVIDER_unload(legacy_provider);
legacy_provider = NULL;
}
if (default_provider) {
OSSL_PROVIDER_unload(default_provider);
default_provider = NULL;
}
if (ossl_ctx) {
OSSL_LIB_CTX_free(ossl_ctx);
ossl_ctx = NULL;
}
#endif
}
/** /**
* Encode ECB FiSH Base64 * Encode ECB FiSH Base64
@ -228,9 +276,19 @@ char *fish_cipher(const char *plaintext, size_t plaintext_len, const char *key,
plaintext_len -= 8; plaintext_len -= 8;
} }
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-CBC", NULL);
#else
cipher = (EVP_CIPHER *) EVP_bf_cbc(); cipher = (EVP_CIPHER *) EVP_bf_cbc();
#endif
} else if (mode == EVP_CIPH_ECB_MODE) { } else if (mode == EVP_CIPH_ECB_MODE) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-ECB", NULL);
#else
cipher = (EVP_CIPHER *) EVP_bf_ecb(); cipher = (EVP_CIPHER *) EVP_bf_ecb();
#endif
} }
/* Zero Padding */ /* Zero Padding */

View File

@ -35,6 +35,8 @@ enum fish_mode {
FISH_CBC_MODE = 0x2 FISH_CBC_MODE = 0x2
}; };
int fish_init(void);
void fish_deinit(void);
char *fish_base64_encode(const char *message, size_t message_len); char *fish_base64_encode(const char *message, size_t message_len);
char *fish_base64_decode(const char *message, size_t *final_len); char *fish_base64_decode(const char *message, size_t *final_len);
char *fish_encrypt(const char *key, size_t keylen, const char *message, size_t message_len, enum fish_mode mode); char *fish_encrypt(const char *key, size_t keylen, const char *message, size_t message_len, enum fish_mode mode);

View File

@ -19,4 +19,5 @@ shared_module('fishlim', fishlim_sources,
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'fishlim.def',
) )

View File

@ -815,6 +815,9 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL);
hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
if (!fish_init())
return 0;
if (!dh1080_init()) if (!dh1080_init())
return 0; return 0;
@ -828,6 +831,7 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
int hexchat_plugin_deinit(void) { int hexchat_plugin_deinit(void) {
g_clear_pointer(&pending_exchanges, g_hash_table_destroy); g_clear_pointer(&pending_exchanges, g_hash_table_destroy);
dh1080_deinit(); dh1080_deinit();
fish_deinit();
hexchat_printf(ph, "%s plugin unloaded\n", plugin_name); hexchat_printf(ph, "%s plugin unloaded\n", plugin_name);
return 1; return 1;

View File

@ -278,5 +278,8 @@ main(int argc, char *argv[]) {
g_test_add_func("/fishlim/max_text_command_len", test_max_text_command_len); g_test_add_func("/fishlim/max_text_command_len", test_max_text_command_len);
g_test_add_func("/fishlim/foreach_utf8_data_chunks", test_foreach_utf8_data_chunks); g_test_add_func("/fishlim/foreach_utf8_data_chunks", test_foreach_utf8_data_chunks);
return g_test_run(); fish_init();
int ret = g_test_run();
fish_deinit();
return ret;
} }

View File

@ -957,16 +957,21 @@ static int api_hexchat_pluginprefs_meta_pairs(lua_State *L)
hexchat_plugin *h; hexchat_plugin *h;
if(!script->name) if(!script->name)
return luaL_error(L, "cannot use hexchat.pluginprefs before registering with hexchat.register"); return luaL_error(L, "cannot use hexchat.pluginprefs before registering with hexchat.register");
dest = lua_newuserdata(L, 4096); dest = lua_newuserdata(L, 4096);
h = script->handle; h = script->handle;
if(!hexchat_pluginpref_list(h, dest)) if(!hexchat_pluginpref_list(h, dest))
strcpy(dest, ""); strcpy(dest, "");
lua_pushlightuserdata(L, dest); lua_pushlightuserdata(L, dest);
lua_pushlightuserdata(L, dest); lua_pushlightuserdata(L, dest);
lua_pushcclosure(L, api_hexchat_pluginprefs_meta_pairs_closure, 2); lua_pushcclosure(L, api_hexchat_pluginprefs_meta_pairs_closure, 2);
return 1; lua_insert(L, -2); // Return the userdata (second return value from pairs),
// even though it's not used by the closure (first return
// value from pairs), so that Lua knows not to GC it.
return 2;
} }
static int api_attrs_meta_index(lua_State *L) static int api_attrs_meta_index(lua_State *L)
@ -1764,4 +1769,3 @@ G_MODULE_EXPORT int hexchat_plugin_deinit(hexchat_plugin *plugin_handle)
g_clear_pointer(&expand_buffer, g_free); g_clear_pointer(&expand_buffer, g_free);
return 1; return 1;
} }

View File

@ -88,4 +88,5 @@ shared_module('perl',
install_dir: plugindir, install_dir: plugindir,
install_rpath: perl_rpath, install_rpath: perl_rpath,
name_prefix: '', name_prefix: '',
vs_module_defs: 'perl.def',
) )

View File

@ -28,4 +28,5 @@ shared_module('python', python3_source,
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'python.def'
) )

View File

@ -57,4 +57,5 @@ shared_module('sysinfo', sysinfo_sources,
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'sysinfo.def',
) )

View File

@ -5,4 +5,5 @@ shared_module('upd', 'upd.c',
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'upd.def',
) )

View File

@ -3,4 +3,5 @@ shared_module('winamp', 'winamp.c',
install: true, install: true,
install_dir: plugindir, install_dir: plugindir,
name_prefix: '', name_prefix: '',
vs_module_defs: 'winamp.def',
) )

View File

@ -47,7 +47,6 @@ if host_machine.system() == 'windows'
] ]
common_sysinfo_deps += [ common_sysinfo_deps += [
cc.find_library('wbemuuid'), # sysinfo cc.find_library('wbemuuid'), # sysinfo
cc.find_library('wbemcore'),
] ]
common_sources += 'sysinfo/win32/backend.c' common_sources += 'sysinfo/win32/backend.c'

View File

@ -123,7 +123,11 @@ notify_save (void)
{ {
int fh; int fh;
struct notify *notify; struct notify *notify;
GSList *list = notify_list; // while reading the notify.conf file, elements are added by prepending to the
// list. reverse the list before writing to disk to keep the original
// order of the list
GSList *list = g_slist_copy(notify_list);
list = g_slist_reverse(list);
fh = hexchat_open_file ("notify.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE); fh = hexchat_open_file ("notify.conf", O_TRUNC | O_WRONLY | O_CREAT, 0600, XOF_DOMODE);
if (fh != -1) if (fh != -1)
@ -142,6 +146,7 @@ notify_save (void)
} }
close (fh); close (fh);
} }
g_slist_free(list);
} }
void void

View File

@ -1579,9 +1579,26 @@ cmd_execw (struct session *sess, char *tbuf, char *word[], char *word_eol[])
EMIT_SIGNAL (XP_TE_NOCHILD, sess, NULL, NULL, NULL, NULL, 0); EMIT_SIGNAL (XP_TE_NOCHILD, sess, NULL, NULL, NULL, NULL, 0);
return FALSE; return FALSE;
} }
len = strlen(word_eol[2]); if (strcmp (word[2], "--") == 0)
temp = g_strconcat (word_eol[2], "\n", NULL); {
PrintText(sess, temp); len = strlen(word_eol[3]);
temp = g_strconcat (word_eol[3], "\n", NULL);
PrintText(sess, temp);
}
else
{
if (strcmp (word[2], "-q") == 0)
{
len = strlen(word_eol[3]);
temp = g_strconcat (word_eol[3], "\n", NULL);
}
else
{
len = strlen(word_eol[2]);
temp = g_strconcat (word_eol[2], "\n", NULL);
PrintText(sess, temp);
}
}
write(sess->running_exec->myfd, temp, len + 1); write(sess->running_exec->myfd, temp, len + 1);
g_free(temp); g_free(temp);
@ -3881,34 +3898,6 @@ cmd_wallchop (struct session *sess, char *tbuf, char *word[],
return TRUE; return TRUE;
} }
static int
cmd_wallchan (struct session *sess, char *tbuf, char *word[],
char *word_eol[])
{
GSList *list;
if (*word_eol[2])
{
list = sess_list;
while (list)
{
sess = list->data;
if (sess->type == SESS_CHANNEL)
{
message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT;
inbound_chanmsg (sess->server, NULL, sess->channel,
sess->server->nick, word_eol[2], TRUE, FALSE,
&no_tags);
sess->server->p_message (sess->server, sess->channel, word_eol[2]);
}
list = list->next;
}
return TRUE;
}
return FALSE;
}
static int static int
cmd_hop (struct session *sess, char *tbuf, char *word[], char *word_eol[]) cmd_hop (struct session *sess, char *tbuf, char *word[], char *word_eol[])
{ {
@ -4005,7 +3994,7 @@ const struct commands xc_cmds[] = {
N_("EXECKILL [-9], kills a running exec in the current session. If -9 is given the process is SIGKILL'ed")}, N_("EXECKILL [-9], kills a running exec in the current session. If -9 is given the process is SIGKILL'ed")},
#ifndef __EMX__ #ifndef __EMX__
{"EXECSTOP", cmd_execs, 0, 0, 1, N_("EXECSTOP, sends the process SIGSTOP")}, {"EXECSTOP", cmd_execs, 0, 0, 1, N_("EXECSTOP, sends the process SIGSTOP")},
{"EXECWRITE", cmd_execw, 0, 0, 1, N_("EXECWRITE, sends data to the processes stdin")}, {"EXECWRITE", cmd_execw, 0, 0, 1, N_("EXECWRITE [-q|--], sends data to the processes stdin; use -q flag to quiet/suppress output at text box; use -- flag to stop interpreting arguments as flags, needed if -q itself would occur as data")},
#endif #endif
#endif #endif
#if 0 #if 0
@ -4147,8 +4136,6 @@ const struct commands xc_cmds[] = {
{"USERLIST", cmd_userlist, 1, 1, 1, 0}, {"USERLIST", cmd_userlist, 1, 1, 1, 0},
{"VOICE", cmd_voice, 1, 1, 1, {"VOICE", cmd_voice, 1, 1, 1,
N_("VOICE <nick>, gives voice status to someone (needs chanop)")}, N_("VOICE <nick>, gives voice status to someone (needs chanop)")},
{"WALLCHAN", cmd_wallchan, 1, 1, 1,
N_("WALLCHAN <message>, writes the message to all channels")},
{"WALLCHOP", cmd_wallchop, 1, 1, 1, {"WALLCHOP", cmd_wallchop, 1, 1, 1,
N_("WALLCHOP <message>, sends the message to all chanops on the current channel")}, N_("WALLCHOP <message>, sends the message to all chanops on the current channel")},
{0, 0, 0, 0, 0, 0} {0, 0, 0, 0, 0, 0}

View File

@ -920,6 +920,14 @@ process_numeric (session * sess, int n,
notify_set_online (serv, word[4], tags_data); notify_set_online (serv, word[4], tags_data);
break; break;
case 524: // ERR_HELPNOTFOUND
case 704: // RPL_HELPSTART
case 705: // RPL_HELPTXT
case 706: // RPL_ENDOFHELP
EMIT_SIGNAL_TIMESTAMP (XP_TE_SERVTEXT, sess, STRIP_COLON(word, word_eol, 5), NULL, NULL, NULL,
0, tags_data->timestamp);
break;
case 728: /* +q-list entry */ case 728: /* +q-list entry */
/* NOTE: FREENODE returns these results inconsistent with e.g. +b */ /* NOTE: FREENODE returns these results inconsistent with e.g. +b */
/* Who else has imlemented MODE_QUIET, I wonder? */ /* Who else has imlemented MODE_QUIET, I wonder? */

View File

@ -1559,7 +1559,7 @@ server_connect (server *serv, char *hostname, int port, int no_login)
if (!hostname[0]) if (!hostname[0])
return; return;
if (port < 0) if (port < 1 || port > 65535)
{ {
/* use default port for this server type */ /* use default port for this server type */
port = 6667; port = 6667;
@ -1567,8 +1567,8 @@ server_connect (server *serv, char *hostname, int port, int no_login)
if (serv->use_ssl) if (serv->use_ssl)
port = 6697; port = 6697;
#endif #endif
g_debug ("Attempted to connect to invalid port, assuming default port %d", port);
} }
port &= 0xffff; /* wrap around */
if (serv->connected || serv->connecting || serv->recondelay_tag) if (serv->connected || serv->connecting || serv->recondelay_tag)
server_disconnect (sess, TRUE, -1); server_disconnect (sess, TRUE, -1);

View File

@ -84,7 +84,8 @@ sysinfo_get_cpu_arch (void)
GetNativeSystemInfo (&si); GetNativeSystemInfo (&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
{ {
return cpu_arch = 64; return cpu_arch = 64;
} }
@ -106,7 +107,8 @@ sysinfo_get_build_arch (void)
GetSystemInfo (&si); GetSystemInfo (&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)
{ {
return build_arch = 64; return build_arch = 64;
} }

View File

@ -1054,6 +1054,46 @@ osx_show_uri (const char *url)
#endif #endif
static inline char *
escape_uri (const char *uri)
{
return g_uri_escape_string(uri, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, FALSE);
}
static inline gboolean
uri_contains_forbidden_characters (const char *uri)
{
while (*uri)
{
/* This is not an exhaustive list, the full URI has segments that allow characters like "[]:" for example. */
if (strchr ("`<> ${}\"+", *uri) != NULL || (*uri & 0x80) /* non-ascii */)
return TRUE;
uri++;
}
return FALSE;
}
static char *
maybe_escape_uri (const char *uri)
{
/* The only way to know if a string has already been escaped or not
* is by fulling parsing each segement but we can try some more simple heuristics. */
/* If we find characters that should clearly be escaped. */
if (uri_contains_forbidden_characters (uri))
return escape_uri (uri);
/* If it fails to be unescaped then it was not escaped. */
char *unescaped = g_uri_unescape_string (uri, NULL);
if (!unescaped)
return escape_uri (uri);
g_free (unescaped);
/* At this point it is probably safe to pass through as-is. */
return g_strdup (uri);
}
static void static void
fe_open_url_inner (const char *url) fe_open_url_inner (const char *url)
{ {
@ -1071,8 +1111,8 @@ fe_open_url_inner (const char *url)
#elif defined(__APPLE__) #elif defined(__APPLE__)
osx_show_uri (url); osx_show_uri (url);
#else #else
char *escaped_url = g_uri_escape_string (url, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS, char *escaped_url = maybe_escape_uri (url);
FALSE); g_debug ("Opening URL \"%s\" (%s)", escaped_url, url);
gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, NULL); gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, NULL);
g_free (escaped_url); g_free (escaped_url);
#endif #endif

View File

@ -18,6 +18,7 @@
#include "config.h" #include "config.h"
#include <string.h>
#include <gio/gio.h> #include <gio/gio.h>
static GDBusProxy *fdo_notifications; static GDBusProxy *fdo_notifications;

View File

@ -218,7 +218,7 @@ notification_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, cha
if (!notification_backend_init (&error)) if (!notification_backend_init (&error))
{ {
if (error) if (error)
hexchat_printf(plugin_handle, "Failed loading notification plugin: %s\n", error); g_debug("Failed loading notification plugin: %s\n", error);
return 0; return 0;
} }