From 016c36c917de79383fb2d81c267faa0829147bdf Mon Sep 17 00:00:00 2001 From: Albrecht Schlosser Date: Sat, 23 Dec 2023 19:48:58 +0100 Subject: 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. --- src/Fl_Menu_.cxx | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Fl_Menu_.cxx b/src/Fl_Menu_.cxx index 0d82d92dc..73998ba7e 100644 --- a/src/Fl_Menu_.cxx +++ b/src/Fl_Menu_.cxx @@ -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 -- cgit v1.2.3