diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2018-04-13 19:55:20 +0200 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2018-04-13 19:55:20 +0200 |
commit | 9265acf87945426f765b068dd660995c0e8661f7 (patch) | |
tree | 487d4179ef2e5406d21413b189fe8281dfb273b7 | |
parent | cc06b95ba7b52595d9313606966d380592c9acf9 (diff) | |
download | weechat-9265acf87945426f765b068dd660995c0e8661f7.zip |
scripts: fix memory leak in hook_info callback
-rw-r--r-- | ChangeLog.adoc | 1 | ||||
-rw-r--r-- | src/plugins/guile/weechat-guile-api.c | 14 | ||||
-rw-r--r-- | src/plugins/guile/weechat-guile.c | 2 | ||||
-rw-r--r-- | src/plugins/javascript/weechat-js-api.cpp | 15 | ||||
-rw-r--r-- | src/plugins/javascript/weechat-js.cpp | 2 | ||||
-rw-r--r-- | src/plugins/lua/weechat-lua-api.c | 14 | ||||
-rw-r--r-- | src/plugins/lua/weechat-lua.c | 2 | ||||
-rw-r--r-- | src/plugins/perl/weechat-perl-api.c | 14 | ||||
-rw-r--r-- | src/plugins/perl/weechat-perl.c | 2 | ||||
-rw-r--r-- | src/plugins/php/weechat-php-api.c | 4 | ||||
-rw-r--r-- | src/plugins/php/weechat-php.c | 2 | ||||
-rw-r--r-- | src/plugins/plugin-script.c | 42 | ||||
-rw-r--r-- | src/plugins/plugin-script.h | 6 | ||||
-rw-r--r-- | src/plugins/python/weechat-python-api.c | 14 | ||||
-rw-r--r-- | src/plugins/python/weechat-python.c | 2 | ||||
-rw-r--r-- | src/plugins/ruby/weechat-ruby-api.c | 14 | ||||
-rw-r--r-- | src/plugins/ruby/weechat-ruby.c | 2 | ||||
-rw-r--r-- | src/plugins/tcl/weechat-tcl-api.c | 14 | ||||
-rw-r--r-- | src/plugins/tcl/weechat-tcl.c | 2 |
19 files changed, 122 insertions, 46 deletions
diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 83eae8719..c6ebe8e5a 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -37,6 +37,7 @@ Bug fixes:: * php: fix return code of functions config_write_option and config_write_line * php: fix memory leak in 72 functions returning allocated strings * ruby: fix memory leak in 7 functions returning allocated strings + * scripts: fix memory leak in hook_info callback * scripts: fix return value of hook_infolist callback (pointer instead of string) * scripts: return long integer instead of string in function infolist_time * xfer: set option TCP_NODELAY on socket when receiving a file via DCC (issue #1171) diff --git a/src/plugins/guile/weechat-guile-api.c b/src/plugins/guile/weechat-guile-api.c index ce5b2166d..6e48fa035 100644 --- a/src/plugins/guile/weechat-guile-api.c +++ b/src/plugins/guile/weechat-guile-api.c @@ -57,6 +57,8 @@ plugin_script_str2ptr (weechat_guile_plugin, \ GUILE_CURRENT_SCRIPT_NAME, \ guile_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&guile_data, __string); #define API_SCM_TO_STRING(__str) \ weechat_guile_api_scm_to_string(__str, \ guile_strings, &guile_num_strings) @@ -2875,7 +2877,7 @@ weechat_guile_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -2887,10 +2889,12 @@ weechat_guile_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_guile_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_guile_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/guile/weechat-guile.c b/src/plugins/guile/weechat-guile.c index 36112fb85..52f0c8631 100644 --- a/src/plugins/guile/weechat-guile.c +++ b/src/plugins/guile/weechat-guile.c @@ -1247,12 +1247,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ guile_quiet = 1; - plugin_script_end (plugin, &guile_data); if (guile_script_eval) { weechat_guile_unload (guile_script_eval); guile_script_eval = NULL; } + plugin_script_end (plugin, &guile_data); guile_quiet = 0; /* unprotect module */ diff --git a/src/plugins/javascript/weechat-js-api.cpp b/src/plugins/javascript/weechat-js-api.cpp index ed047c66f..de00752e4 100644 --- a/src/plugins/javascript/weechat-js-api.cpp +++ b/src/plugins/javascript/weechat-js-api.cpp @@ -95,7 +95,8 @@ extern "C" plugin_script_str2ptr (weechat_js_plugin, \ JS_CURRENT_SCRIPT_NAME, \ js_function_name.c_str(), __string) - +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&js_data, __string); #define API_RETURN_OK return v8::True(); #define API_RETURN_ERROR return v8::False(); #define API_RETURN_EMPTY \ @@ -2779,7 +2780,7 @@ weechat_js_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -2791,10 +2792,12 @@ weechat_js_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_js_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_js_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/javascript/weechat-js.cpp b/src/plugins/javascript/weechat-js.cpp index cd07f2bc7..f24b534b5 100644 --- a/src/plugins/javascript/weechat-js.cpp +++ b/src/plugins/javascript/weechat-js.cpp @@ -963,12 +963,12 @@ EXPORT int weechat_plugin_end (struct t_weechat_plugin *plugin) { js_quiet = 1; - plugin_script_end (plugin, &js_data); if (js_script_eval) { weechat_js_unload (js_script_eval); js_script_eval = NULL; } + plugin_script_end (plugin, &js_data); js_quiet = 0; /* free some data */ diff --git a/src/plugins/lua/weechat-lua-api.c b/src/plugins/lua/weechat-lua-api.c index 8938522e3..1224042de 100644 --- a/src/plugins/lua/weechat-lua-api.c +++ b/src/plugins/lua/weechat-lua-api.c @@ -67,6 +67,8 @@ plugin_script_str2ptr (weechat_lua_plugin, \ LUA_CURRENT_SCRIPT_NAME, \ lua_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&lua_data, __string); #define API_RETURN_OK \ lua_pushinteger (L, 1); \ return 1 @@ -2994,7 +2996,7 @@ weechat_lua_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -3006,10 +3008,12 @@ weechat_lua_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_lua_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_lua_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/lua/weechat-lua.c b/src/plugins/lua/weechat-lua.c index f2c9240cf..124ccbdab 100644 --- a/src/plugins/lua/weechat-lua.c +++ b/src/plugins/lua/weechat-lua.c @@ -1281,12 +1281,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ lua_quiet = 1; - plugin_script_end (plugin, &lua_data); if (lua_script_eval) { weechat_lua_unload (lua_script_eval); lua_script_eval = NULL; } + plugin_script_end (plugin, &lua_data); lua_quiet = 0; /* free some data */ diff --git a/src/plugins/perl/weechat-perl-api.c b/src/plugins/perl/weechat-perl-api.c index c267b3aca..a92f9e93b 100644 --- a/src/plugins/perl/weechat-perl-api.c +++ b/src/plugins/perl/weechat-perl-api.c @@ -60,6 +60,8 @@ plugin_script_str2ptr (weechat_perl_plugin, \ PERL_CURRENT_SCRIPT_NAME, \ perl_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&perl_data, __string); #define API_RETURN_OK XSRETURN_YES #define API_RETURN_ERROR XSRETURN_NO #define API_RETURN_EMPTY XSRETURN_EMPTY @@ -2918,7 +2920,7 @@ weechat_perl_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -2930,10 +2932,12 @@ weechat_perl_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_perl_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_perl_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/perl/weechat-perl.c b/src/plugins/perl/weechat-perl.c index b63d2ccb1..846a0ae6f 100644 --- a/src/plugins/perl/weechat-perl.c +++ b/src/plugins/perl/weechat-perl.c @@ -1317,12 +1317,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ perl_quiet = 1; - plugin_script_end (plugin, &perl_data); if (perl_script_eval) { weechat_perl_unload (perl_script_eval); perl_script_eval = NULL; } + plugin_script_end (plugin, &perl_data); perl_quiet = 0; #ifndef MULTIPLICITY diff --git a/src/plugins/php/weechat-php-api.c b/src/plugins/php/weechat-php-api.c index 4a30850aa..e821dfd44 100644 --- a/src/plugins/php/weechat-php-api.c +++ b/src/plugins/php/weechat-php-api.c @@ -67,6 +67,8 @@ plugin_script_str2ptr (weechat_php_plugin, \ PHP_CURRENT_SCRIPT_NAME, \ php_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&php_data, __string); #define API_RETURN_OK RETURN_LONG((long)1) #define API_RETURN_ERROR RETURN_LONG((long)0) #define API_RETURN_EMPTY RETURN_NULL() @@ -2824,7 +2826,7 @@ weechat_php_api_hook_info_cb (const void *pointer, weechat_php_cb (pointer, data, func_argv, "sss", WEECHAT_SCRIPT_EXEC_STRING, &rc); - return rc; + return API_STATIC_STRING(rc); } API_FUNC(hook_info) diff --git a/src/plugins/php/weechat-php.c b/src/plugins/php/weechat-php.c index aefcbcf0d..97b2f1322 100644 --- a/src/plugins/php/weechat-php.c +++ b/src/plugins/php/weechat-php.c @@ -1319,12 +1319,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ php_quiet = 1; - plugin_script_end (plugin, &php_data); if (php_script_eval) { weechat_php_unload (php_script_eval); php_script_eval = NULL; } + plugin_script_end (plugin, &php_data); php_quiet = 0; if (weechat_php_func_map) diff --git a/src/plugins/plugin-script.c b/src/plugins/plugin-script.c index a8b414d35..ba1ad2a77 100644 --- a/src/plugins/plugin-script.c +++ b/src/plugins/plugin-script.c @@ -171,6 +171,13 @@ plugin_script_init (struct t_weechat_plugin *weechat_plugin, char *action_signals[] = { "install", "remove", "autoload", NULL }; int i, auto_load_scripts; + /* initialize static strings */ + plugin_data->index_static_string = 0; + for (i = 0; i < WEECHAT_SCRIPT_STATIC_STRINGS; i++) + { + plugin_data->static_string[i] = NULL; + } + /* initialize script configuration file (file: "<language>.conf") */ plugin_script_config_init (weechat_plugin, plugin_data); @@ -388,6 +395,29 @@ invalid: } /* + * Gets a "static string": a string allocated that will be freed later + * (or when the plugin is unloaded). + * + * The "string" argument must have been allocated by free (or strdup, ...) + * and will be automatically freed later. + */ + +char * +plugin_script_get_static_string (struct t_plugin_script_data *plugin_data, + char *string) +{ + plugin_data->index_static_string = (plugin_data->index_static_string + 1) % + WEECHAT_SCRIPT_STATIC_STRINGS; + + if (plugin_data->static_string[plugin_data->index_static_string]) + free (plugin_data->static_string[plugin_data->index_static_string]); + + plugin_data->static_string[plugin_data->index_static_string] = string; + + return plugin_data->static_string[plugin_data->index_static_string]; +} + +/* * Builds concatenated function name and data (both are strings). * The result will be sent to callbacks. */ @@ -1742,7 +1772,7 @@ void plugin_script_end (struct t_weechat_plugin *weechat_plugin, struct t_plugin_script_data *plugin_data) { - int scripts_loaded; + int scripts_loaded, i; /* unload all scripts */ scripts_loaded = (*(plugin_data->scripts)) ? 1 : 0; @@ -1756,6 +1786,16 @@ plugin_script_end (struct t_weechat_plugin *weechat_plugin, /* write config file (file: "<language>.conf") */ weechat_config_write (*(plugin_data->config_file)); weechat_config_free (*(plugin_data->config_file)); + + /* free static strings */ + for (i = 0; i < WEECHAT_SCRIPT_STATIC_STRINGS; i++) + { + if (plugin_data->static_string[i]) + { + free (plugin_data->static_string[i]); + plugin_data->static_string[i] = NULL; + } + } } /* diff --git a/src/plugins/plugin-script.h b/src/plugins/plugin-script.h index b40e0a69a..c797d9de8 100644 --- a/src/plugins/plugin-script.h +++ b/src/plugins/plugin-script.h @@ -33,6 +33,8 @@ enum t_weechat_script_exec_type #define WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE 16 +#define WEECHAT_SCRIPT_STATIC_STRINGS 32 + #define WEECHAT_SCRIPT_EVAL_NAME "__eval__" #define WEECHAT_SCRIPT_MSG_NOT_INIT(__current_script, \ @@ -78,6 +80,8 @@ struct t_plugin_script_data struct t_config_option **config_look_eval_keep_context; struct t_plugin_script **scripts; struct t_plugin_script **last_script; + char *static_string[WEECHAT_SCRIPT_STATIC_STRINGS]; + int index_static_string; /* callbacks */ int (*callback_command) (const void *pointer, void *data, @@ -125,6 +129,8 @@ extern void *plugin_script_str2ptr (struct t_weechat_plugin *weechat_plugin, const char *script_name, const char *function_name, const char *pointer_str); +extern char *plugin_script_get_static_string (struct t_plugin_script_data *plugin_data, + char *string); extern char *plugin_script_build_function_and_data (const char *function, const char *data); extern void plugin_script_get_function_and_data (void *callback_data, diff --git a/src/plugins/python/weechat-python-api.c b/src/plugins/python/weechat-python-api.c index 8d8718c80..82399b494 100644 --- a/src/plugins/python/weechat-python-api.c +++ b/src/plugins/python/weechat-python-api.c @@ -59,6 +59,8 @@ plugin_script_str2ptr (weechat_python_plugin, \ PYTHON_CURRENT_SCRIPT_NAME, \ python_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&python_data, __string); #define API_RETURN_OK return PyLong_FromLong((long)1) #define API_RETURN_ERROR return PyLong_FromLong ((long)0) #define API_RETURN_EMPTY \ @@ -2948,7 +2950,7 @@ weechat_python_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -2960,10 +2962,12 @@ weechat_python_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_python_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_python_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/python/weechat-python.c b/src/plugins/python/weechat-python.c index f95577060..bbb10e95f 100644 --- a/src/plugins/python/weechat-python.c +++ b/src/plugins/python/weechat-python.c @@ -1609,12 +1609,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ python_quiet = 1; - plugin_script_end (plugin, &python_data); if (python_script_eval) { weechat_python_unload (python_script_eval); python_script_eval = NULL; } + plugin_script_end (plugin, &python_data); python_quiet = 0; /* free python interpreter */ diff --git a/src/plugins/ruby/weechat-ruby-api.c b/src/plugins/ruby/weechat-ruby-api.c index e8d3b10a6..bfe889962 100644 --- a/src/plugins/ruby/weechat-ruby-api.c +++ b/src/plugins/ruby/weechat-ruby-api.c @@ -57,6 +57,8 @@ plugin_script_str2ptr (weechat_ruby_plugin, \ RUBY_CURRENT_SCRIPT_NAME, \ ruby_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&ruby_data, __string); #define API_RETURN_OK return INT2FIX (1) #define API_RETURN_ERROR return INT2FIX (0) #define API_RETURN_EMPTY return Qnil @@ -3513,7 +3515,7 @@ weechat_ruby_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -3525,10 +3527,12 @@ weechat_ruby_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_ruby_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_ruby_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/ruby/weechat-ruby.c b/src/plugins/ruby/weechat-ruby.c index 7d0da943a..09aa122d5 100644 --- a/src/plugins/ruby/weechat-ruby.c +++ b/src/plugins/ruby/weechat-ruby.c @@ -1425,12 +1425,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ ruby_quiet = 1; - plugin_script_end (plugin, &ruby_data); if (ruby_script_eval) { weechat_ruby_unload (ruby_script_eval); ruby_script_eval = NULL; } + plugin_script_end (plugin, &ruby_data); ruby_quiet = 0; ruby_cleanup (0); diff --git a/src/plugins/tcl/weechat-tcl-api.c b/src/plugins/tcl/weechat-tcl-api.c index 250f3f7f7..2159ec645 100644 --- a/src/plugins/tcl/weechat-tcl-api.c +++ b/src/plugins/tcl/weechat-tcl-api.c @@ -68,6 +68,8 @@ plugin_script_str2ptr (weechat_tcl_plugin, \ TCL_CURRENT_SCRIPT_NAME, \ tcl_function_name, __string) +#define API_STATIC_STRING(__string) \ + plugin_script_get_static_string(&tcl_data, __string); #define API_RETURN_OK \ { \ objp = Tcl_GetObjResult (interp); \ @@ -3209,7 +3211,7 @@ weechat_tcl_api_hook_info_cb (const void *pointer, void *data, { struct t_plugin_script *script; void *func_argv[3]; - char empty_arg[1] = { '\0' }; + char empty_arg[1] = { '\0' }, *result; const char *ptr_function, *ptr_data; script = (struct t_plugin_script *)pointer; @@ -3221,10 +3223,12 @@ weechat_tcl_api_hook_info_cb (const void *pointer, void *data, func_argv[1] = (info_name) ? (char *)info_name : empty_arg; func_argv[2] = (arguments) ? (char *)arguments : empty_arg; - return (const char *)weechat_tcl_exec (script, - WEECHAT_SCRIPT_EXEC_STRING, - ptr_function, - "sss", func_argv); + result = (char *)weechat_tcl_exec (script, + WEECHAT_SCRIPT_EXEC_STRING, + ptr_function, + "sss", func_argv); + + return API_STATIC_STRING(result); } return NULL; diff --git a/src/plugins/tcl/weechat-tcl.c b/src/plugins/tcl/weechat-tcl.c index 83b4967df..aada3d960 100644 --- a/src/plugins/tcl/weechat-tcl.c +++ b/src/plugins/tcl/weechat-tcl.c @@ -970,12 +970,12 @@ weechat_plugin_end (struct t_weechat_plugin *plugin) { /* unload all scripts */ tcl_quiet = 1; - plugin_script_end (plugin, &tcl_data); if (tcl_script_eval) { weechat_tcl_unload (tcl_script_eval); tcl_script_eval = NULL; } + plugin_script_end (plugin, &tcl_data); tcl_quiet = 0; /* free some data */ |