all repos — fluxbox @ e868ff5928af2badd1418006b4a46889fea3eb57

custom fork of the fluxbox windowmanager

bug fix: make fluxbox work under nxserver, closes #2813828

nxserver-3.x creates a XExposeEvent for the unmapped FbTk::Menu(), which is
not configured completely yet (hence unmapped). this causes a call to
FbTk::Menu::clearItem() which then uses a value of 0 for m_rows_per_column
to divide the current index which triggers a SIGFPE.

it is still unclear, why nxserver-3.x creates the XExposeEvent for the
unmapped (menu) window. doing nothing if the menu is unmapped 'fixes'
the problem for now.

many thanks to Lars Engels (bsd-geek.de) to assist me in debugging this
issue.
Mathias Gumz akira at fluxbox dot org
commit

e868ff5928af2badd1418006b4a46889fea3eb57

parent

7f6d03e7bf575cfa2b61378e33a4fb991ff342a9

1 files changed, 50 insertions(+), 0 deletions(-)

jump to
M src/FbTk/Menu.ccsrc/FbTk/Menu.cc

@@ -702,6 +702,14 @@ item->submenu()->m_parent = this;

item->submenu()->setScreen(m_screen_x, m_screen_y, m_screen_width, m_screen_height); + // ensure we do not divide by 0 and thus cause a SIGFPE + if (m_rows_per_column == 0) { +#if DEBUG + cout << "Error: m_rows_per_column == 0 in FbTk::Menu::clearItem()\n"; +#endif + return; + } + int column = index / m_rows_per_column; int row = index - (column * m_rows_per_column); int new_x = x() + ((m_item_w * (column + 1)) + m_window.borderWidth());

@@ -768,6 +776,14 @@ return 0;

MenuItem *item = menuitems[index]; if (! item) return 0; + + // ensure we do not divide by 0 and thus cause a SIGFPE + if (m_rows_per_column == 0) { +#if DEBUG + cout << "Error: m_rows_per_column == 0 in FbTk::Menu::clearItem()\n"; +#endif + return 0; + } int column = index / m_rows_per_column; int row = index - (column * m_rows_per_column);

@@ -999,6 +1015,15 @@ }

void Menu::exposeEvent(XExposeEvent &ee) { + + // some xservers (eg: nxserver) send XExposeEvent for the unmapped menu. + // this caused a SIGFPE in ::clearItem(), since m_rows_per_column is + // still 0 -> division by 0. + // + // it is still unclear, why nxserver behaves this way + if (!isVisible()) + return; + if (ee.window == m_title) { m_title.clearArea(ee.x, ee.y, ee.width, ee.height); } else if (ee.window == m_frame) {

@@ -1241,6 +1266,14 @@ void Menu::clearItem(int index, bool clear, int search_index) {

if (!validIndex(index)) return; + // ensure we do not divide by 0 and thus cause a SIGFPE + if (m_rows_per_column == 0) { +#if DEBUG + cout << "Error: m_rows_per_column == 0 in FbTk::Menu::clearItem()\n"; +#endif + return; + } + int column = index / m_rows_per_column; int row = index - (column * m_rows_per_column); unsigned int item_w = m_item_w;

@@ -1276,6 +1309,15 @@ }

// Area must have been cleared before calling highlight void Menu::highlightItem(int index) { + + // ensure we do not divide by 0 and thus cause a SIGFPE + if (m_rows_per_column == 0) { +#if DEBUG + cout << "Error: m_rows_per_column == 0 in FbTk::Menu::clearItem()\n"; +#endif + return; + } + int column = index / m_rows_per_column; int row = index - (column * m_rows_per_column); unsigned int item_w = m_item_w;

@@ -1332,6 +1374,14 @@ // underline menuitem[index] with respect to matchstringsize size

void Menu::drawLine(int index, int size){ if (!validIndex(index)) return; + + // ensure we do not divide by 0 and thus cause a SIGFPE + if (m_rows_per_column == 0) { +#if DEBUG + cout << "Error: m_rows_per_column == 0 in FbTk::Menu::clearItem()\n"; +#endif + return; + } int column = index / m_rows_per_column; int row = index - (column * m_rows_per_column);