Skip to content

Commit

Permalink
Bug 799320 - GNUCash Immediately Exits on Startup
Browse files Browse the repository at this point in the history
Some excellent and insightful debugging by the reporter found that the cause was specifying
a locale as en_US.utf8 instead of en_US.utf-8. GnuLib's locale functions and so Guile's are
apparently quite picky on Win32.

To address this move reading the environment file to before we set the mac and Windows
locales and ensure that UTF/UCS and ISO-8859 character sets are specified with minus
separators on Windows. I tested on macOS and didn't experience the crash.
  • Loading branch information
jralls committed May 30, 2024
1 parent 99a9265 commit 35a0e77
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
2 changes: 1 addition & 1 deletion gnucash/gnucash-core-app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,10 @@ Gnucash::CoreApp::CoreApp (const char* app_name) : m_app_name {app_name}
* The user may have configured a different language via
* the environment file.
*/
gnc_environment_setup();
#if defined MAC_INTEGRATION || defined __MINGW32__
sys_locale = set_platform_locale();
#endif
gnc_environment_setup();
#if ! defined MAC_INTEGRATION && ! defined __MINGW32__/* setlocale already done */
sys_locale = g_strdup (setlocale (LC_ALL, ""));
if (!sys_locale)
Expand Down
79 changes: 79 additions & 0 deletions gnucash/gnucash-locale-windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,74 @@
#include <glib/gi18n.h>
#include "gnucash-locale-platform.h"

static void
rectify_utf(const char* envvar, const char* locale,
const char* dot, const char* rest)
{
char *new_locale;
if (rest && *rest)
new_locale = g_strdup_printf ("%s.UTF-%s@%s",
locale, dot + 3, rest);
else
new_locale = g_strdup_printf ("%s.UTF-%s", locale, dot + 3);

_putenv_s (envvar, new_locale);
g_free(new_locale);
}

static void
rectify_iso(const char* envvar, const char* locale,
const char* dot, const char* rest)
{

char *eefn = strstr (dot, "8859");

if (!(eefn && *eefn))
return;

char* isonum = (*(eefn + 4) == '-') ? eefn + 5 : eefn + 4;

if (*isonum == '\0')
return;

char *new_locale;
if (rest && *rest)
new_locale = g_strdup_printf ("%s.ISO-8859-%s@%s", locale, isonum, rest);
else
new_locale = g_strdup_printf ("%s.ISO-8859-%s", locale, isonum);

_putenv_s (envvar, new_locale);
g_free (new_locale);
}

static void
rectify_environment_charset(const char* envvar)
{
if (!(envvar && *envvar))
return;
if (strcmp (envvar, "LANG") && strncmp (envvar, "LC_", 3))
return;
char* saveptr;
char* varval = getenv (envvar);
char* locale = strtok_r (varval, ".", &saveptr);
char* dot = strtok_r (NULL, "@", &saveptr);

if (!dot) //strsep didn't find a .
return;

char* rest = strtok_r (NULL, "@", &saveptr);

if ((strncasecmp (dot, "utf", 3) == 0 || strncasecmp (dot, "ucs", 3) == 0) &&
dot[3] != '-')
return rectify_utf (envvar, locale, dot, rest);

if (strncasecmp (dot, "iso", 3) == 0 && strlen (dot) >= 8 &&
dot[3] != '-' && dot[8] != '-')
return rectify_iso (envvar, locale, dot, rest);

//Otherwise do nothing
}

/* If one of the Unix locale variables LC_ALL, LC_MESSAGES, or LANG is
* set in the environment check to see if it's a valid locale and if
* it is set both the Windows and POSIX locales to that. If not
Expand All @@ -37,6 +105,17 @@ set_platform_locale(void)
{
WCHAR lpLocaleName[LOCALE_NAME_MAX_LENGTH];
char *locale = NULL;
/* Prevent Bug 799320 by ensuring that the localization
environment variables of interest have well-formed UTF or
ISO-8859 specifiers for GnuLib's interpretation of well-formed,
which means having minuses in the right places. This only
protects agains missing hyphens, it won't help if you specify
utf42 as a charset when you meant utf32.
*/
rectify_environment_charset ("LANG");
rectify_environment_charset ("LC_ALL");
rectify_environment_charset ("LC_MESSAGES");
rectify_environment_charset ("LC_CTYPE");

if (((locale = getenv ("LC_ALL")) != NULL && locale[0] != '\0') ||
((locale = getenv ("LC_MESSAGES")) != NULL && locale[0] != '\0') ||
Expand Down

0 comments on commit 35a0e77

Please sign in to comment.