mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
core: fix crash when a custom bar item name is already used by a default bar item (issue #2034)
This commit is contained in:
@@ -15,6 +15,7 @@ For a list of important changes that require manual actions, please look at rele
|
||||
|
||||
Bug fixes::
|
||||
|
||||
* core: fix crash when a custom bar item name is already used by a default bar item (issue #2034)
|
||||
* core: fix generation of TOTP on Big Endian systems (issue #2021)
|
||||
* irc: move value `-all` at the end of completions for command `/ignore del`
|
||||
* irc: fix memory leak when joining channels with keys
|
||||
|
||||
@@ -11,6 +11,19 @@ It is recommended to read it when upgrading to a new stable version. +
|
||||
For a complete list of changes, please look at ChangeLog.
|
||||
|
||||
|
||||
[[v4.0.6]]
|
||||
== Version 4.0.6 (under dev)
|
||||
|
||||
[[v4.0.6_custom_bar_items]]
|
||||
=== Custom bar items
|
||||
|
||||
Custom bar items must now have a different name than default bar items
|
||||
(for example the custom bar item name `time` is now forbidden).
|
||||
|
||||
If you have such names in your config, WeeChat will now fail to load them
|
||||
(this should not happen anyway, since such bar items can not be properly used
|
||||
and can cause a crash of WeeChat).
|
||||
|
||||
[[v4.0.5]]
|
||||
== Version 4.0.5 (2023-09-24)
|
||||
|
||||
|
||||
+20
-10
@@ -2195,17 +2195,20 @@ config_weechat_custom_bar_item_read_cb (const void *pointer, void *data,
|
||||
if (!ptr_temp_item)
|
||||
{
|
||||
/* create new temporary custom bar item */
|
||||
ptr_temp_item = gui_bar_item_custom_alloc (item_name);
|
||||
if (ptr_temp_item)
|
||||
if (gui_bar_item_search_default (item_name) < 0)
|
||||
{
|
||||
/* add new custom bar item at the end */
|
||||
ptr_temp_item->prev_item = last_gui_temp_custom_bar_item;
|
||||
ptr_temp_item->next_item = NULL;
|
||||
if (last_gui_temp_custom_bar_item)
|
||||
last_gui_temp_custom_bar_item->next_item = ptr_temp_item;
|
||||
else
|
||||
gui_temp_custom_bar_items = ptr_temp_item;
|
||||
last_gui_temp_custom_bar_item = ptr_temp_item;
|
||||
ptr_temp_item = gui_bar_item_custom_alloc (item_name);
|
||||
if (ptr_temp_item)
|
||||
{
|
||||
/* add new custom bar item at the end */
|
||||
ptr_temp_item->prev_item = last_gui_temp_custom_bar_item;
|
||||
ptr_temp_item->next_item = NULL;
|
||||
if (last_gui_temp_custom_bar_item)
|
||||
last_gui_temp_custom_bar_item->next_item = ptr_temp_item;
|
||||
else
|
||||
gui_temp_custom_bar_items = ptr_temp_item;
|
||||
last_gui_temp_custom_bar_item = ptr_temp_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2226,6 +2229,13 @@ config_weechat_custom_bar_item_read_cb (const void *pointer, void *data,
|
||||
section->name, option_name, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sUnable to add custom bar item \"%s\""),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
item_name);
|
||||
}
|
||||
|
||||
free (item_name);
|
||||
|
||||
|
||||
@@ -439,31 +439,46 @@ gui_bar_item_custom_new (const char *name, const char *conditions,
|
||||
if (gui_bar_item_custom_search (name))
|
||||
return NULL;
|
||||
|
||||
if (gui_bar_item_search_default (name) >= 0)
|
||||
return NULL;
|
||||
|
||||
option_conditions = NULL;
|
||||
option_content = NULL;
|
||||
new_bar_item_custom = NULL;
|
||||
|
||||
option_conditions = gui_bar_item_custom_create_option (
|
||||
name,
|
||||
GUI_BAR_ITEM_CUSTOM_OPTION_CONDITIONS,
|
||||
conditions);
|
||||
if (!option_conditions)
|
||||
return NULL;
|
||||
goto error;
|
||||
|
||||
option_content = gui_bar_item_custom_create_option (
|
||||
name,
|
||||
GUI_BAR_ITEM_CUSTOM_OPTION_CONTENT,
|
||||
content);
|
||||
if (!option_content)
|
||||
{
|
||||
config_file_option_free (option_conditions, 0);
|
||||
return NULL;
|
||||
}
|
||||
goto error;
|
||||
|
||||
new_bar_item_custom = gui_bar_item_custom_new_with_options (
|
||||
name,
|
||||
option_conditions,
|
||||
option_content);
|
||||
if (!new_bar_item_custom)
|
||||
goto error;
|
||||
|
||||
gui_bar_item_custom_create_bar_item (new_bar_item_custom);
|
||||
if (!new_bar_item_custom->bar_item)
|
||||
goto error;
|
||||
|
||||
gui_bar_item_update (name);
|
||||
|
||||
return new_bar_item_custom;
|
||||
|
||||
error:
|
||||
if (new_bar_item_custom)
|
||||
{
|
||||
gui_bar_item_custom_create_bar_item (new_bar_item_custom);
|
||||
gui_bar_item_update (name);
|
||||
gui_bar_item_custom_free (new_bar_item_custom);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -472,8 +487,7 @@ gui_bar_item_custom_new (const char *name, const char *conditions,
|
||||
if (option_content)
|
||||
config_file_option_free (option_content, 0);
|
||||
}
|
||||
|
||||
return new_bar_item_custom;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -483,12 +497,13 @@ gui_bar_item_custom_new (const char *name, const char *conditions,
|
||||
void
|
||||
gui_bar_item_custom_use_temp_items ()
|
||||
{
|
||||
struct t_gui_bar_item_custom *ptr_temp_item;
|
||||
struct t_gui_bar_item_custom *ptr_temp_item, *ptr_next_temp_item;
|
||||
int i;
|
||||
|
||||
for (ptr_temp_item = gui_temp_custom_bar_items; ptr_temp_item;
|
||||
ptr_temp_item = ptr_temp_item->next_item)
|
||||
ptr_temp_item = gui_temp_custom_bar_items;
|
||||
while (ptr_temp_item)
|
||||
{
|
||||
ptr_next_temp_item = ptr_temp_item->next_item;
|
||||
for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
|
||||
{
|
||||
if (!ptr_temp_item->options[i])
|
||||
@@ -500,6 +515,20 @@ gui_bar_item_custom_use_temp_items ()
|
||||
}
|
||||
}
|
||||
gui_bar_item_custom_create_bar_item (ptr_temp_item);
|
||||
if (!ptr_temp_item->bar_item)
|
||||
{
|
||||
if (ptr_temp_item->prev_item)
|
||||
(ptr_temp_item->prev_item)->next_item = ptr_temp_item->next_item;
|
||||
if (ptr_temp_item->next_item)
|
||||
(ptr_temp_item->next_item)->prev_item = ptr_temp_item->prev_item;
|
||||
if (gui_temp_custom_bar_items == ptr_temp_item)
|
||||
gui_temp_custom_bar_items = ptr_temp_item->next_item;
|
||||
if (last_gui_temp_custom_bar_item == ptr_temp_item)
|
||||
last_gui_temp_custom_bar_item = ptr_temp_item->prev_item;
|
||||
gui_bar_item_custom_free_data (ptr_temp_item);
|
||||
free (ptr_temp_item);
|
||||
}
|
||||
ptr_temp_item = ptr_next_temp_item;
|
||||
}
|
||||
|
||||
/* remove any existing custom bar item */
|
||||
@@ -534,6 +563,9 @@ gui_bar_item_custom_rename (struct t_gui_bar_item_custom *item,
|
||||
if (gui_bar_item_custom_search (new_name))
|
||||
return 0;
|
||||
|
||||
if (gui_bar_item_search_default (new_name) >= 0)
|
||||
return 0;
|
||||
|
||||
old_name = strdup (item->name);
|
||||
if (!old_name)
|
||||
return 0;
|
||||
@@ -570,6 +602,24 @@ gui_bar_item_custom_rename (struct t_gui_bar_item_custom *item,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees data in a custom bar item.*
|
||||
*/
|
||||
|
||||
void
|
||||
gui_bar_item_custom_free_data (struct t_gui_bar_item_custom *item)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (item->name)
|
||||
free (item->name);
|
||||
for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
|
||||
{
|
||||
if (item->options[i])
|
||||
config_file_option_free (item->options[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Deletes a custom bar item.
|
||||
*/
|
||||
@@ -578,7 +628,6 @@ void
|
||||
gui_bar_item_custom_free (struct t_gui_bar_item_custom *item)
|
||||
{
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
@@ -599,13 +648,7 @@ gui_bar_item_custom_free (struct t_gui_bar_item_custom *item)
|
||||
last_gui_custom_bar_item = item->prev_item;
|
||||
|
||||
/* free data */
|
||||
if (item->name)
|
||||
free (item->name);
|
||||
for (i = 0; i < GUI_BAR_ITEM_CUSTOM_NUM_OPTIONS; i++)
|
||||
{
|
||||
if (item->options[i])
|
||||
config_file_option_free (item->options[i], 1);
|
||||
}
|
||||
gui_bar_item_custom_free_data (item);
|
||||
|
||||
free (item);
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ extern struct t_gui_bar_item_custom *gui_bar_item_custom_new (const char *name,
|
||||
extern void gui_bar_item_custom_use_temp_items ();
|
||||
extern int gui_bar_item_custom_rename (struct t_gui_bar_item_custom *item,
|
||||
const char *new_name);
|
||||
extern void gui_bar_item_custom_free_data (struct t_gui_bar_item_custom *item);
|
||||
extern void gui_bar_item_custom_free (struct t_gui_bar_item_custom *item);
|
||||
extern void gui_bar_item_custom_free_all ();
|
||||
|
||||
|
||||
@@ -97,6 +97,30 @@ gui_bar_item_valid (struct t_gui_bar_item *bar_item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for a default bar item by name.
|
||||
*
|
||||
* Returns index in gui_bar_item_names[], -1 if not found.
|
||||
*/
|
||||
|
||||
int
|
||||
gui_bar_item_search_default (const char *item_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!item_name || !item_name[0])
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < GUI_BAR_NUM_ITEMS; i++)
|
||||
{
|
||||
if (strcmp (gui_bar_item_names[i], item_name) == 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* default bar item not found */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Searches for a bar item by name.
|
||||
*/
|
||||
|
||||
@@ -89,6 +89,7 @@ extern char *gui_bar_item_names[];
|
||||
/* functions */
|
||||
|
||||
extern int gui_bar_item_valid (struct t_gui_bar_item *bar_item);
|
||||
extern int gui_bar_item_search_default (const char *item_name);
|
||||
extern struct t_gui_bar_item *gui_bar_item_search (const char *name);
|
||||
extern int gui_bar_item_used_in_bar (struct t_gui_bar *bar,
|
||||
const char *item_name,
|
||||
|
||||
@@ -464,6 +464,7 @@ TEST(GuiBarItemCustom, Rename)
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* gui_bar_item_custom_free_data
|
||||
* gui_bar_item_custom_free
|
||||
* gui_bar_item_custom_free_all
|
||||
*/
|
||||
|
||||
@@ -53,6 +53,21 @@ TEST(GuiBarItem, Valid)
|
||||
LONGS_EQUAL(0, gui_bar_item_valid (gui_bar_items + 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* gui_bar_item_search_default
|
||||
*/
|
||||
|
||||
TEST(GuiBarItem, SearchDefault)
|
||||
{
|
||||
LONGS_EQUAL(-1, gui_bar_item_search_default (NULL));
|
||||
LONGS_EQUAL(-1, gui_bar_item_search_default (""));
|
||||
LONGS_EQUAL(-1, gui_bar_item_search_default ("zzz"));
|
||||
|
||||
CHECK(gui_bar_item_search_default ("scroll") >= 0);
|
||||
CHECK(gui_bar_item_search_default ("time") >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests functions:
|
||||
* gui_bar_item_search
|
||||
|
||||
Reference in New Issue
Block a user