scripts: fix memory leak in hook_info callback
This commit is contained in:
parent
cc06b95ba7
commit
9265acf879
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
@ -387,6 +394,29 @@ invalid:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user