From afc0db8ca0bcae488ed7efa8ee3bcd873873a8d9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Mon, 16 Mar 2009 13:33:39 +0000 Subject: [PATCH] detect and report errors in XRC specification of grid sizers git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59572 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/sizer.h | 7 ++-- include/wx/xrc/xh_sizer.h | 1 + src/xrc/xh_sizer.cpp | 81 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/include/wx/sizer.h b/include/wx/sizer.h index 9a686c4fee..7af1eccb16 100644 --- a/include/wx/sizer.h +++ b/include/wx/sizer.h @@ -741,15 +741,16 @@ public: int GetVGap() const { return m_vgap; } int GetHGap() const { return m_hgap; } + // return the number of total items and the number of columns and rows + // (for internal use only) + int CalcRowsCols(int& rows, int& cols) const; + protected: int m_rows; int m_cols; int m_vgap; int m_hgap; - // return the number of total items and the number of columns and rows - int CalcRowsCols(int& rows, int& cols) const; - void SetItemBounds( wxSizerItem *item, int x, int y, int w, int h ); private: diff --git a/include/wx/xrc/xh_sizer.h b/include/wx/xrc/xh_sizer.h index 6c3992c787..5d57d7ea66 100644 --- a/include/wx/xrc/xh_sizer.h +++ b/include/wx/xrc/xh_sizer.h @@ -47,6 +47,7 @@ private: wxGridBagSizer* Handle_wxGridBagSizer(); wxSizer* Handle_wxWrapSizer(); + bool ValidateGridSizerChildren(); void SetGrowables(wxFlexGridSizer* fsizer, const wxChar* param, bool rows); wxGBPosition GetGBPos(const wxString& param); wxGBSpan GetGBSpan(const wxString& param); diff --git a/src/xrc/xh_sizer.cpp b/src/xrc/xh_sizer.cpp index 060d3bbbcd..30a1175b00 100644 --- a/src/xrc/xh_sizer.cpp +++ b/src/xrc/xh_sizer.cpp @@ -215,7 +215,11 @@ wxObject* wxSizerXmlHandler::Handle_sizer() sizer = Handle_wxStaticBoxSizer(); #endif else if (m_class == wxT("wxGridSizer")) + { + if ( !ValidateGridSizerChildren() ) + return NULL; sizer = Handle_wxGridSizer(); + } else if (m_class == wxT("wxFlexGridSizer")) { flexsizer = Handle_wxFlexGridSizer(); @@ -227,14 +231,18 @@ wxObject* wxSizerXmlHandler::Handle_sizer() sizer = flexsizer; } else if (m_class == wxT("wxWrapSizer")) + { sizer = Handle_wxWrapSizer(); - - if ( !sizer ) + } + else { ReportError(wxString::Format("unknown sizer class \"%s\"", m_class)); - return NULL; } + // creation of sizer failed for some (already reported) reason, so exit: + if ( !sizer ) + return NULL; + wxSize minsize = GetSize(wxT("minsize")); if (!(minsize == wxDefaultSize)) sizer->SetMinSize(minsize); @@ -318,6 +326,8 @@ wxSizer* wxSizerXmlHandler::Handle_wxGridSizer() wxFlexGridSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer() { + if ( !ValidateGridSizerChildren() ) + return NULL; return new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")), GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); } @@ -325,6 +335,8 @@ wxFlexGridSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer() wxGridBagSizer* wxSizerXmlHandler::Handle_wxGridBagSizer() { + if ( !ValidateGridSizerChildren() ) + return NULL; return new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); } @@ -335,16 +347,59 @@ wxSizer* wxSizerXmlHandler::Handle_wxWrapSizer() } +bool wxSizerXmlHandler::ValidateGridSizerChildren() +{ + int rows = GetLong("rows"); + int cols = GetLong("cols"); + + if ( rows && cols ) + { + // fixed number of cells, need to verify children count + int children = 0; + for ( wxXmlNode *n = m_node->GetChildren(); n; n = n->GetNext() ) + { + if ( n->GetType() == wxXML_ELEMENT_NODE && + (n->GetName() == "object" || n->GetName() == "object_ref") ) + { + children++; + } + } + + if ( children > rows * cols ) + { + ReportError + ( + wxString::Format + ( + "too many children in grid sizer: %d > %d x %d" + " (consider omitting the number of rows or columns)", + children, + cols, + rows + ) + ); + return false; + } + } + + return true; +} + void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer, const wxChar* param, bool rows) { + int nrows, ncols; + sizer->CalcRowsCols(nrows, ncols); + const int nslots = rows ? nrows : ncols; + wxStringTokenizer tkn; - unsigned long l; tkn.SetString(GetParamValue(param), wxT(",")); + while (tkn.HasMoreTokens()) { + unsigned long l; if (!tkn.GetNextToken().ToULong(&l)) { ReportParamError @@ -355,6 +410,24 @@ void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer, break; } + if ( (int)l >= nslots ) + { + ReportParamError + ( + param, + wxString::Format + ( + "invalid %s index %d: must be less than %d", + rows ? "row" : "column", + l, + nslots + ) + ); + + // ignore incorrect value, still try to process the rest + continue; + } + if (rows) sizer->AddGrowableRow(l); else -- 2.45.2