Skip to content

Commit b622e9e

Browse files
korneel-emwebRockinRoel
authored andcommitted
WT-8392: crash when using WToolBar::widget()
It is possible to add any widget using WToolBar::addWidget(), but count() and widget() didn't expect it. Fixed by tracking all added widgets instead of relying on dynamic_cast
1 parent 578dd9d commit b622e9e

File tree

2 files changed

+31
-58
lines changed

2 files changed

+31
-58
lines changed

src/Wt/WToolBar.C

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include "Wt/WSplitButton.h"
1111
#include "Wt/WToolBar.h"
1212

13+
#include <algorithm>
14+
1315
namespace Wt {
1416

1517
LOGGER("WToolBar");
@@ -34,6 +36,8 @@ void WToolBar::setOrientation(Orientation orientation)
3436
void WToolBar::addButton(std::unique_ptr<WPushButton> button,
3537
AlignmentFlag alignmentFlag)
3638
{
39+
widgets_.push_back(button.get());
40+
3741
if (compact_){
3842
if (alignmentFlag == AlignmentFlag::Right)
3943
button->setAttributeValue("style", "float:right;");
@@ -48,6 +52,8 @@ void WToolBar::addButton(std::unique_ptr<WPushButton> button,
4852
void WToolBar::addButton(std::unique_ptr<WSplitButton> button,
4953
AlignmentFlag alignmentFlag)
5054
{
55+
widgets_.push_back(button.get());
56+
5157
setCompact(false);
5258
lastGroup_ = nullptr;
5359
if (alignmentFlag == AlignmentFlag::Right)
@@ -58,6 +64,8 @@ void WToolBar::addButton(std::unique_ptr<WSplitButton> button,
5864
void WToolBar::addWidget(std::unique_ptr<WWidget> widget,
5965
AlignmentFlag alignmentFlag)
6066
{
67+
widgets_.push_back(widget.get());
68+
6169
setCompact(false);
6270
lastGroup_ = nullptr;
6371
if (alignmentFlag == AlignmentFlag::Right)
@@ -67,23 +75,19 @@ void WToolBar::addWidget(std::unique_ptr<WWidget> widget,
6775

6876
std::unique_ptr<WWidget> WToolBar::removeWidget(WWidget *widget)
6977
{
70-
WWidget *p = widget->parent();
71-
if (p == impl_)
72-
return impl_->removeWidget(widget);
73-
else {
74-
int i = impl_->indexOf(p);
75-
if (i >= 0) {
76-
WContainerWidget *cw = dynamic_cast<WContainerWidget *>(p);
77-
if (cw) {
78-
std::unique_ptr<WWidget> result = cw->removeWidget(widget);
79-
if (cw->count() == 0)
80-
cw->parent()->removeWidget(cw);
81-
return result;
82-
}
83-
}
84-
}
85-
86-
return std::unique_ptr<WWidget>();
78+
auto it = std::find(widgets_.begin(), widgets_.end(), widget);
79+
if (it != widgets_.end()) {
80+
auto widget = *it;
81+
auto parent = static_cast<WContainerWidget*>(widget->parent());
82+
83+
auto retval = parent->removeWidget(widget);
84+
if (parent != impl_ && parent->count() == 0)
85+
impl_->removeWidget(parent);
86+
widgets_.erase(it);
87+
88+
return retval;
89+
} else
90+
return nullptr;
8791
}
8892

8993
void WToolBar::addSeparator()
@@ -129,51 +133,15 @@ WContainerWidget *WToolBar::lastGroup()
129133

130134
int WToolBar::count() const
131135
{
132-
if (compact_)
133-
return impl_->count();
134-
else {
135-
int result = 0;
136-
for (int i = 0; i < impl_->count(); ++i) {
137-
WWidget *w = impl_->widget(i);
138-
139-
if (dynamic_cast<WSplitButton *>(w))
140-
++result;
141-
else {
142-
WContainerWidget *group = dynamic_cast<WContainerWidget *>(w);
143-
144-
result += group->count();
145-
}
146-
}
147-
148-
return result;
149-
}
136+
return widgets_.size();
150137
}
151138

152139
WWidget *WToolBar::widget(int index) const
153140
{
154-
if (compact_)
155-
return impl_->widget(index);
156-
else {
157-
int current = 0;
158-
for (int i = 0; i < impl_->count(); ++i) {
159-
WWidget *w = impl_->widget(i);
160-
161-
if (dynamic_cast<WSplitButton *>(w)) {
162-
if (index == current)
163-
return w;
164-
++current;
165-
} else {
166-
WContainerWidget *group = dynamic_cast<WContainerWidget *>(w);
167-
168-
if (index < current + group->count())
169-
return group->widget(index - current);
170-
171-
current += group->count();
172-
}
173-
}
174-
141+
if (index < widgets_.size())
142+
return widgets_[index];
143+
else
175144
return nullptr;
176-
}
177145
}
178146

179147
}

src/Wt/WToolBar.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ class WT_API WToolBar : public WCompositeWidget
6767
*/
6868
void addSeparator();
6969

70-
/*! \brief Returns the number of buttons.
70+
/*! \brief Returns the number of widgets.
71+
*
72+
* The counted widgets are either a WPushButton or WSplitButton added by
73+
* addButton() or a widget added by addWidget().
7174
*
7275
* \sa widget()
7376
*/
@@ -99,6 +102,8 @@ class WT_API WToolBar : public WCompositeWidget
99102
WContainerWidget *impl_;
100103
WContainerWidget *lastGroup_;
101104

105+
std::vector<WWidget *> widgets_;
106+
102107
WContainerWidget *lastGroup();
103108
};
104109

0 commit comments

Comments
 (0)