Fix memory free() mismatch (#875)

This issue was revealed during testing for GitHub Issue #875.

"ERROR: AddressSanitizer: attempting free on address which was not
malloc()-ed", reported by examples/howto-menu-with-images.cxx if
the window object was released at the end of the program, causing
Fl_Menu_::clear() to be called.

The issue was caused by casting all supported label types to
'const char *' which are stored in Fl_Menu_Item::text and then trying
to free() all text strings in Fl_Menu_::clear() under certain
conditions.

Now images and Fl_Multi_Label's are no longer (tried to be) free'd.
This commit is contained in:
Albrecht Schlosser 2023-12-23 19:48:58 +01:00
parent f59702e290
commit 016c36c917

View File

@ -500,8 +500,33 @@ Fl_Menu_* fl_menu_array_owner = 0;
*/
void Fl_Menu_::clear() {
if (alloc) {
if (alloc>1) for (int i = size(); i--;)
if (menu_[i].text) free((void*)menu_[i].text);
if (alloc > 1) {
// See GitHub issue #875: we can't release "everything"
// for several reasons. Maybe we can do better if we create
// a new menu system based on Fl_Widget in 1.5.0 or later.
// Fl_Image's and Fl_Multi_Label's and their linked objects
// can't be released automatically. However, we must take care
// not to free() images or Fl_Multi_Label's because they can
// either be static or are allocated by operator new.
for (int i = size(); i--;) {
if (!menu_[i].text)
continue;
switch(menu_[i].labeltype_) {
case _FL_IMAGE_LABEL:
break;
case _FL_MULTI_LABEL:
break;
default:
free((void*)menu_[i].text);
break;
}
}
}
if (this == fl_menu_array_owner)
fl_menu_array_owner = 0;
else