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
on: [push, pull_request]
jobs:
build:
flatpak_build:
runs-on: ubuntu-latest
container:
image: bilelmoussaoui/flatpak-github-actions:gnome-40

View File

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

View File

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

View File

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

View File

@ -26,6 +26,19 @@
<id>hexchat.desktop</id>
</provides>
<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">
<description>
<p>This is a feature release:</p>

View File

@ -1,5 +1,5 @@
project('hexchat', 'c',
version: '2.16.0',
version: '2.16.1',
meson_version: '>= 0.47.0',
default_options: [
'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('LOCALEDIR', join_paths(get_option('prefix'),
get_option('datadir'), 'locale'))
config_h.set_quoted('G_LOG_DOMAIN', 'hexchat')
config_h.set10('ENABLE_NLS', true)
# Optional features

View File

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

View File

@ -1,5 +1,6 @@
shared_module('exec', 'exec.c',
dependencies: hexchat_plugin_dep,
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)++); \
} 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
@ -228,9 +276,19 @@ char *fish_cipher(const char *plaintext, size_t plaintext_len, const char *key,
plaintext_len -= 8;
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-CBC", NULL);
#else
cipher = (EVP_CIPHER *) EVP_bf_cbc();
#endif
} 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();
#endif
}
/* Zero Padding */

View File

@ -35,6 +35,8 @@ enum fish_mode {
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_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);

View File

@ -19,4 +19,5 @@ shared_module('fishlim', fishlim_sources,
install: true,
install_dir: plugindir,
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, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL);
if (!fish_init())
return 0;
if (!dh1080_init())
return 0;
@ -828,6 +831,7 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
int hexchat_plugin_deinit(void) {
g_clear_pointer(&pending_exchanges, g_hash_table_destroy);
dh1080_deinit();
fish_deinit();
hexchat_printf(ph, "%s plugin unloaded\n", plugin_name);
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/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;
if(!script->name)
return luaL_error(L, "cannot use hexchat.pluginprefs before registering with hexchat.register");
dest = lua_newuserdata(L, 4096);
h = script->handle;
if(!hexchat_pluginpref_list(h, dest))
strcpy(dest, "");
lua_pushlightuserdata(L, dest);
lua_pushlightuserdata(L, dest);
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)
@ -1764,4 +1769,3 @@ G_MODULE_EXPORT int hexchat_plugin_deinit(hexchat_plugin *plugin_handle)
g_clear_pointer(&expand_buffer, g_free);
return 1;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -123,7 +123,11 @@ notify_save (void)
{
int fh;
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);
if (fh != -1)
@ -142,6 +146,7 @@ notify_save (void)
}
close (fh);
}
g_slist_free(list);
}
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);
return FALSE;
}
len = strlen(word_eol[2]);
temp = g_strconcat (word_eol[2], "\n", NULL);
PrintText(sess, temp);
if (strcmp (word[2], "--") == 0)
{
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);
g_free(temp);
@ -3881,34 +3898,6 @@ cmd_wallchop (struct session *sess, char *tbuf, char *word[],
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
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")},
#ifndef __EMX__
{"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
#if 0
@ -4147,8 +4136,6 @@ const struct commands xc_cmds[] = {
{"USERLIST", cmd_userlist, 1, 1, 1, 0},
{"VOICE", cmd_voice, 1, 1, 1,
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,
N_("WALLCHOP <message>, sends the message to all chanops on the current channel")},
{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);
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 */
/* NOTE: FREENODE returns these results inconsistent with e.g. +b */
/* 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])
return;
if (port < 0)
if (port < 1 || port > 65535)
{
/* use default port for this server type */
port = 6667;
@ -1567,8 +1567,8 @@ server_connect (server *serv, char *hostname, int port, int no_login)
if (serv->use_ssl)
port = 6697;
#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)
server_disconnect (sess, TRUE, -1);

View File

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

View File

@ -1054,6 +1054,46 @@ osx_show_uri (const char *url)
#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
fe_open_url_inner (const char *url)
{
@ -1071,8 +1111,8 @@ fe_open_url_inner (const char *url)
#elif defined(__APPLE__)
osx_show_uri (url);
#else
char *escaped_url = g_uri_escape_string (url, G_URI_RESERVED_CHARS_GENERIC_DELIMITERS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS,
FALSE);
char *escaped_url = maybe_escape_uri (url);
g_debug ("Opening URL \"%s\" (%s)", escaped_url, url);
gtk_show_uri (NULL, escaped_url, GDK_CURRENT_TIME, NULL);
g_free (escaped_url);
#endif

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <string.h>
#include <gio/gio.h>
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 (error)
hexchat_printf(plugin_handle, "Failed loading notification plugin: %s\n", error);
g_debug("Failed loading notification plugin: %s\n", error);
return 0;
}