From 8e0958fd19b42777575f3089ad99ae648898ec47 Mon Sep 17 00:00:00 2001 From: deepend Date: Thu, 26 Feb 2026 11:54:42 -0700 Subject: [PATCH] Added a Windows-specific startup path in main() to reconstruct argc/argv from g_win32_get_command_line() before any argument parsing, so GLib option parsing no longer depends on potentially malformed CRT argv in subsystem/protocol-handler launches (a likely source of your launch crash stack through glib-2.0-0.dll). Ensured the allocated Windows command-line vector is freed on all early-return and normal-exit paths in main() to avoid leaks/regressions from the new startup handling. --- src/common/zoitechat.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/common/zoitechat.c b/src/common/zoitechat.c index b2da65a2..262e1edc 100644 --- a/src/common/zoitechat.c +++ b/src/common/zoitechat.c @@ -1847,6 +1847,9 @@ main (int argc, char *argv[]) { int i; int ret; +#ifdef WIN32 + char **win32_argv = NULL; +#endif #ifdef WIN32 HRESULT coinit_result; @@ -1854,6 +1857,18 @@ main (int argc, char *argv[]) srand ((unsigned int) time (NULL)); /* CL: do this only once! */ +#ifdef WIN32 + /* Build argv from the Unicode command line first. In subsystem:windows + * launches (for example protocol handlers), CRT argv can be invalid and can + * crash GLib option parsing during startup. */ + win32_argv = g_win32_get_command_line (); + if (win32_argv != NULL && win32_argv[0] != NULL) + { + argv = win32_argv; + argc = g_strv_length (win32_argv); + } +#endif + /* We must check for the config dir parameter, otherwise load_config() will behave incorrectly. * load_config() must come before fe_args() because fe_args() calls gtk_init() which needs to * know the language which is set in the config. The code below is copy-pasted from fe_args() @@ -1904,11 +1919,19 @@ main (int argc, char *argv[]) ret = fe_args (argc, argv); if (ret != -1) + { +#ifdef WIN32 + g_strfreev (win32_argv); +#endif return ret; + } #ifdef WIN32 if (zoitechat_remote_win32 ()) + { + g_strfreev (win32_argv); return 0; + } #endif #ifdef USE_DBUS @@ -1961,5 +1984,9 @@ main (int argc, char *argv[]) WSACleanup (); #endif +#ifdef WIN32 + g_strfreev (win32_argv); +#endif + return 0; }