From fb7a84589dac8b045571f67d9fd6c286b0ee3852 Mon Sep 17 00:00:00 2001 From: Trygve Aaberge Date: Mon, 25 Nov 2024 19:51:31 +0100 Subject: [PATCH] perl: only set Perl locale if the locale is broken It turns out that Debian has reverted the commit in Perl that broke the locale in their 5.38 branch, so it did not have the issue. However, the workaround we added to fix the locale apparently makes the version Debian/Ubuntu has crash on perl_destruct. I'm not sure why it makes it crash, but since it doesn't crash on newer Perl versions, I'm assuming that it's another bug with the locale handling in that Perl version. To avoid the crash, make sure to only set the locale if we detect that it has been broken by Perl. We do this by checking if the value returned by wcwidth (160) (the first non-ascii printable character) has changed. If this value is not the same after the call to perl_construct, the locale has been broken. I moved the call to Perl_setlocale to right after perl_construct, as the call to perl_construct is what breaks the locale. --- src/plugins/perl/weechat-perl.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/plugins/perl/weechat-perl.c b/src/plugins/perl/weechat-perl.c index f7cd7ef89..09c591c66 100644 --- a/src/plugins/perl/weechat-perl.c +++ b/src/plugins/perl/weechat-perl.c @@ -23,6 +23,7 @@ #undef _ #include +#include #include #include #include @@ -507,7 +508,9 @@ weechat_perl_load (const char *filename, const char *code) struct stat buf; char *perl_code; int length; -#ifndef MULTIPLICITY +#ifdef MULTIPLICITY + int wcwidth160; +#else char pkgname[64]; #endif /* MULTIPLICITY */ @@ -564,14 +567,18 @@ weechat_perl_load (const char *filename, const char *code) PERL_PLUGIN_NAME); PERL_SET_CONTEXT (perl_current_interpreter); + wcwidth160 = wcwidth (160); perl_construct (perl_current_interpreter); + + if (wcwidth (160) != wcwidth160) + { + /* restore the locale that's broken in some versions of Perl */ + Perl_setlocale (LC_ALL, ""); + } + temp_script.interpreter = (PerlInterpreter *) perl_current_interpreter; perl_parse (perl_current_interpreter, weechat_perl_api_init, perl_args_count, perl_args, NULL); -#if PERL_REVISION >= 6 || (PERL_REVISION == 5 && PERL_VERSION >= 38) - /* restore the locale that could be changed by Perl >= 5.38 */ - Perl_setlocale (LC_ALL, ""); -#endif length = strlen (perl_weechat_code) + strlen (str_warning) + strlen (str_error) - 2 + 4 + strlen ((code) ? code : filename) + 4 + 1; perl_code = malloc (length); @@ -1248,6 +1255,9 @@ int weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) { int old_perl_quiet; +#ifndef MULTIPLICITY + int wcwidth160; +#endif /* MULTIPLICITY */ #ifdef PERL_SYS_INIT3 int a; @@ -1298,13 +1308,17 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) return WEECHAT_RC_ERROR; } + wcwidth160 = wcwidth (160); perl_construct (perl_main); + + if (wcwidth (160) != wcwidth160) + { + /* restore the locale that's broken in some versions of Perl */ + Perl_setlocale (LC_ALL, ""); + } + perl_parse (perl_main, weechat_perl_api_init, perl_args_count, perl_args, NULL); -#if PERL_REVISION >= 6 || (PERL_REVISION == 5 && PERL_VERSION >= 38) - /* restore the locale that could be changed by Perl >= 5.38 */ - Perl_setlocale (LC_ALL, ""); -#endif #endif /* MULTIPLICITY */ perl_data.config_file = &perl_config_file;