aboutsummaryrefslogtreecommitdiff
path: root/gui
diff options
context:
space:
mode:
authorThierry Crozat2016-10-22 21:31:39 +0100
committerThierry Crozat2016-10-22 21:32:16 +0100
commit74b3b45c61a41300c2e84201f813817eada27351 (patch)
tree73ca0b5be269620cf0568f2983be2e99d302b5b6 /gui
parent9f94294d80e904a7d7af51bdf8fe8fb9456b6832 (diff)
downloadscummvm-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.
Diffstat (limited to 'gui')
-rw-r--r--gui/widgets/tab.cpp13
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) {