Fix crash when using a wxRadioBox without items in wxOSX

wxRadioBox::m_radioButtonCycle is never null -- except when it is, when
there are no items at all in the radio box. Handle this case without
crashing too by checking for the pointer being valid before using it.

Also add a unit test checking that this works correctly.

See #22751.

(cherry picked from commit b0c417db36b7daca3b9b6731588f5b7b3f19ca6a)
This commit is contained in:
Vadim Zeitlin 2022-08-29 18:39:09 +02:00
parent ccca07af33
commit 9660c80430
3 changed files with 26 additions and 4 deletions

View File

@ -266,6 +266,7 @@ wxOSX:
- Fix wxBitmapBundle compatibility when using template NSImages (#22623). - Fix wxBitmapBundle compatibility when using template NSImages (#22623).
- Fix bezel style of borderless wxToggleButton (#22140). - Fix bezel style of borderless wxToggleButton (#22140).
- Improve wxWebView full screen support (Tobias Taschner, #22637). - Improve wxWebView full screen support (Tobias Taschner, #22637).
- Fix crash when creating wxRadioBox without any items (#22751).
3.2.0: (released 2022-07-07) 3.2.0: (released 2022-07-07)

View File

@ -59,18 +59,21 @@ wxRadioBox::~wxRadioBox()
wxRadioButton *next, *current; wxRadioButton *next, *current;
current = m_radioButtonCycle->NextInCycle(); current = m_radioButtonCycle;
if (current != NULL) if (current != NULL)
{ {
while (current != m_radioButtonCycle) // We need to start deleting the buttons from the second one because
// deleting the first one would change the pointers stored in them.
for (current = current->NextInCycle();;)
{ {
next = current->NextInCycle(); next = current->NextInCycle();
delete current; delete current;
if (next == m_radioButtonCycle)
break;
current = next; current = next;
} }
delete current;
} }
} }
@ -339,6 +342,9 @@ void wxRadioBox::Command( wxCommandEvent& event )
// //
void wxRadioBox::SetFocus() void wxRadioBox::SetFocus()
{ {
if (!m_radioButtonCycle)
return;
wxRadioButton *current; wxRadioButton *current;
current = m_radioButtonCycle; current = m_radioButtonCycle;

View File

@ -16,6 +16,7 @@
#include "wx/radiobox.h" #include "wx/radiobox.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/scopedptr.h"
#include "wx/tooltip.h" #include "wx/tooltip.h"
class RadioBoxTestCase : public CppUnit::TestCase class RadioBoxTestCase : public CppUnit::TestCase
@ -223,4 +224,18 @@ void RadioBoxTestCase::SetString()
CPPUNIT_ASSERT_EQUAL("", m_radio->GetString(2)); CPPUNIT_ASSERT_EQUAL("", m_radio->GetString(2));
} }
TEST_CASE("RadioBox::NoItems", "[radiobox]")
{
wxScopedPtr<wxRadioBox>
radio(new wxRadioBox(wxTheApp->GetTopWindow(), wxID_ANY, "Empty",
wxDefaultPosition, wxDefaultSize,
0, NULL,
1, wxRA_SPECIFY_COLS));
CHECK( radio->GetCount() == 0 );
CHECK( radio->IsEmpty() );
CHECK_NOTHROW( radio->SetFocus() );
}
#endif // wxUSE_RADIOBOX #endif // wxUSE_RADIOBOX