diff options
author | Thierry Crozat | 2016-10-22 21:31:39 +0100 |
---|---|---|
committer | Thierry Crozat | 2016-10-22 21:32:16 +0100 |
commit | 74b3b45c61a41300c2e84201f813817eada27351 (patch) | |
tree | 73ca0b5be269620cf0568f2983be2e99d302b5b6 | |
parent | 9f94294d80e904a7d7af51bdf8fe8fb9456b6832 (diff) | |
download | scummvm-rg350-74b3b45c61a41300c2e84201f813817eada27351.tar.gz scummvm-rg350-74b3b45c61a41300c2e84201f813817eada27351.tar.bz2 scummvm-rg350-74b3b45c61a41300c2e84201f813817eada27351.zip |
GUI: Fix possible access to free'ed memory or double deletion in tab widget
The issue could occur when adding or removing widgets to a tab, and then
not switching to a different tab before the destructor or reflowLayout() were
called. In such a case the firstWidget of the current widget in the _tabs list
could be out of date. Accessing this first widget from the destructor or from
reflowLayout() could then cause a crash, or random issues caused to access
to free'ed memory. In theory this could also lead to a memory leak, although
I don't think this could occur in our current code.
Usually we add several tabs to a TabWidget and then switch back to the first
tab after building all the tabs. So in such a case the issue would not occur.
But because we are deleting and reconstructing the clear buttons for the
MIDI and Path tabs of the options dialog from reflowLayout(), if the current
tab is the Path tab, it would be kept as active tab after adding and removing
widget to it and the issue would occur.
This fixes bug #9618.
-rw-r--r-- | gui/widgets/tab.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/gui/widgets/tab.cpp b/gui/widgets/tab.cpp index 15e6a9d370..ed261c98ec 100644 --- a/gui/widgets/tab.cpp +++ b/gui/widgets/tab.cpp @@ -70,6 +70,12 @@ void TabWidget::init() { } TabWidget::~TabWidget() { + // If widgets were added or removed in the current tab, without tabs + // having been switched using setActiveTab() afterward, then the + // firstWidget in the _tabs list for the active tab may not be up to + // date. So update it now. + if (_activeTab != -1) + _tabs[_activeTab].firstWidget = _firstWidget; _firstWidget = 0; for (uint i = 0; i < _tabs.size(); ++i) { delete _tabs[i].firstWidget; @@ -274,6 +280,13 @@ void TabWidget::reflowLayout() { _tabWidth = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Width"); _titleVPad = g_gui.xmlEval()->getVar("Globals.TabWidget.Tab.Padding.Top"); + // If widgets were added or removed in the current tab, without tabs + // having been switched using setActiveTab() afterward, then the + // firstWidget in the _tabs list for the active tab may not be up to + // date. So update it now. + if (_activeTab != -1) + _tabs[_activeTab].firstWidget = _firstWidget; + for (uint i = 0; i < _tabs.size(); ++i) { Widget *w = _tabs[i].firstWidget; while (w) { |