From 486ea8837adbc744db43977f8d66560f8bcd3435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Wed, 26 Jun 2024 18:44:35 +0200 Subject: [PATCH] python: call empty eval workaround before auto-load of scripts (issue #2046, issue #2126) This should definitely fix the crash with Python 3.12, even when scripts are auto-loaded (the previous fix was working only when the scripts are loaded manually). --- src/plugins/guile/weechat-guile.c | 1 + src/plugins/javascript/weechat-js.cpp | 1 + src/plugins/lua/weechat-lua.c | 1 + src/plugins/perl/weechat-perl.c | 1 + src/plugins/php/weechat-php.c | 1 + src/plugins/plugin-script.c | 7 +++++++ src/plugins/plugin-script.h | 1 + src/plugins/python/weechat-python.c | 24 ++++++++++++++++++------ src/plugins/ruby/weechat-ruby.c | 1 + src/plugins/tcl/weechat-tcl.c | 1 + 10 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/plugins/guile/weechat-guile.c b/src/plugins/guile/weechat-guile.c index 3c95ccc17..ae0837cc4 100644 --- a/src/plugins/guile/weechat-guile.c +++ b/src/plugins/guile/weechat-guile.c @@ -1321,6 +1321,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) guile_data.callback_signal_debug_dump = &weechat_guile_signal_debug_dump_cb; guile_data.callback_signal_script_action = &weechat_guile_signal_script_action_cb; guile_data.callback_load_file = &weechat_guile_load_cb; + guile_data.init_before_autoload = NULL; guile_data.unload_all = &weechat_guile_unload_all; old_guile_quiet = guile_quiet; diff --git a/src/plugins/javascript/weechat-js.cpp b/src/plugins/javascript/weechat-js.cpp index 719b95e5e..c717839b1 100644 --- a/src/plugins/javascript/weechat-js.cpp +++ b/src/plugins/javascript/weechat-js.cpp @@ -955,6 +955,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) js_data.callback_signal_debug_dump = &weechat_js_signal_debug_dump_cb; js_data.callback_signal_script_action = &weechat_js_signal_script_action_cb; js_data.callback_load_file = &weechat_js_load_cb; + js_data.init_before_autoload = NULL; js_data.unload_all = &weechat_js_unload_all; old_js_quiet = js_quiet; diff --git a/src/plugins/lua/weechat-lua.c b/src/plugins/lua/weechat-lua.c index 36e5fe49e..8fb917359 100644 --- a/src/plugins/lua/weechat-lua.c +++ b/src/plugins/lua/weechat-lua.c @@ -1295,6 +1295,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) lua_data.callback_signal_debug_dump = &weechat_lua_signal_debug_dump_cb; lua_data.callback_signal_script_action = &weechat_lua_signal_script_action_cb; lua_data.callback_load_file = &weechat_lua_load_cb; + lua_data.init_before_autoload = NULL; lua_data.unload_all = &weechat_lua_unload_all; old_lua_quiet = lua_quiet; diff --git a/src/plugins/perl/weechat-perl.c b/src/plugins/perl/weechat-perl.c index afd18c026..d0b79f701 100644 --- a/src/plugins/perl/weechat-perl.c +++ b/src/plugins/perl/weechat-perl.c @@ -1320,6 +1320,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) perl_data.callback_signal_debug_dump = &weechat_perl_signal_debug_dump_cb; perl_data.callback_signal_script_action = &weechat_perl_signal_script_action_cb; perl_data.callback_load_file = &weechat_perl_load_cb; + perl_data.init_before_autoload = NULL; perl_data.unload_all = &weechat_perl_unload_all; old_perl_quiet = perl_quiet; diff --git a/src/plugins/php/weechat-php.c b/src/plugins/php/weechat-php.c index b24519d1e..9cd1b8416 100644 --- a/src/plugins/php/weechat-php.c +++ b/src/plugins/php/weechat-php.c @@ -1305,6 +1305,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) php_data.callback_signal_debug_dump = &weechat_php_signal_debug_dump_cb; php_data.callback_signal_script_action = &weechat_php_signal_script_action_cb; php_data.callback_load_file = &weechat_php_load_cb; + php_data.init_before_autoload = NULL; php_data.unload_all = &weechat_php_unload_all; php_embed_module.startup = php_weechat_startup; diff --git a/src/plugins/plugin-script.c b/src/plugins/plugin-script.c index f6408a9a5..418040621 100644 --- a/src/plugins/plugin-script.c +++ b/src/plugins/plugin-script.c @@ -317,6 +317,13 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, &plugin_script_info_version_cb, weechat_plugin, NULL); + /* + * call function "init_before_autoload" + * (called even if no scripts are auto-loaded) + */ + if (plugin_data->init_before_autoload) + (void)(plugin_data->init_before_autoload) (); + /* check if auto-load of scripts is enabled */ info_auto_load_scripts = weechat_info_get ("auto_load_scripts", NULL); auto_load_scripts = (info_auto_load_scripts diff --git a/src/plugins/plugin-script.h b/src/plugins/plugin-script.h index 4ccac05b4..70ada42b0 100644 --- a/src/plugins/plugin-script.h +++ b/src/plugins/plugin-script.h @@ -122,6 +122,7 @@ struct t_plugin_script_data void (*callback_load_file) (void *data, const char *filename); /* functions */ + void (*init_before_autoload) (); void (*unload_all) (); }; diff --git a/src/plugins/python/weechat-python.c b/src/plugins/python/weechat-python.c index f6801ecb5..eccb9a1cd 100644 --- a/src/plugins/python/weechat-python.c +++ b/src/plugins/python/weechat-python.c @@ -1088,6 +1088,23 @@ weechat_python_eval (struct t_gui_buffer *buffer, int send_to_buffer_as_input, return 1; } +/* + * Function called before the auto-load of scripts. + */ + +void +weechat_python_init_before_autoload () +{ +#if PY_VERSION_HEX >= 0x030C0000 && PY_VERSION_HEX < 0x030D0000 + /* + * Workaround for crash when ending interpreters in Python 3.12: + * the first time we load a script, we eval an empty string. + * See https://github.com/weechat/weechat/issues/2046 + */ + weechat_python_eval (NULL, 0, 0, ""); +#endif +} + /* * Callback for command "/python". */ @@ -1592,6 +1609,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) python_data.callback_signal_debug_dump = &weechat_python_signal_debug_dump_cb; python_data.callback_signal_script_action = &weechat_python_signal_script_action_cb; python_data.callback_load_file = &weechat_python_load_cb; + python_data.init_before_autoload = &weechat_python_init_before_autoload; python_data.unload_all = &weechat_python_unload_all; old_python_quiet = python_quiet; @@ -1613,12 +1631,6 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) "", &weechat_python_infolist_cb, NULL, NULL); -#if PY_VERSION_HEX >= 0x030C0000 && PY_VERSION_HEX < 0x030D0000 - // Workaround for crash when ending interpreters in Python 3.12 - // See https://github.com/weechat/weechat/issues/2046 - weechat_python_eval (NULL, 0, 0, ""); -#endif - /* init OK */ return WEECHAT_RC_OK; } diff --git a/src/plugins/ruby/weechat-ruby.c b/src/plugins/ruby/weechat-ruby.c index fb67aebc6..502e3530e 100644 --- a/src/plugins/ruby/weechat-ruby.c +++ b/src/plugins/ruby/weechat-ruby.c @@ -1408,6 +1408,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) ruby_data.callback_signal_debug_dump = &weechat_ruby_signal_debug_dump_cb; ruby_data.callback_signal_script_action = &weechat_ruby_signal_script_action_cb; ruby_data.callback_load_file = &weechat_ruby_load_cb; + ruby_data.init_before_autoload = NULL; ruby_data.unload_all = &weechat_ruby_unload_all; old_ruby_quiet = ruby_quiet; diff --git a/src/plugins/tcl/weechat-tcl.c b/src/plugins/tcl/weechat-tcl.c index b16295fb0..67be86e28 100644 --- a/src/plugins/tcl/weechat-tcl.c +++ b/src/plugins/tcl/weechat-tcl.c @@ -948,6 +948,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[]) tcl_data.callback_signal_debug_dump = &weechat_tcl_signal_debug_dump_cb; tcl_data.callback_signal_script_action = &weechat_tcl_signal_script_action_cb; tcl_data.callback_load_file = &weechat_tcl_load_cb; + tcl_data.init_before_autoload = NULL; tcl_data.unload_all = &weechat_tcl_unload_all; old_tcl_quiet = tcl_quiet;