From 3441261346fcee4efb6ba27764384d141b2c4f7e Mon Sep 17 00:00:00 2001
From: Mathias Gumz <akira at fluxbox dot org>
Date: Wed, 15 Oct 2008 08:31:10 +0200
Subject: don't allow resizing to negative dimensions

this fixes a problem when the user resizes a window over the opposite border.
as a result a signed overflow occured which lead to quite huge windows.
---
 ChangeLog     |  2 ++
 src/Window.cc | 40 +++++++++++++++++++++++++---------------
 src/Window.hh | 14 +++++++-------
 3 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5eeda89..67ee11d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
  (Format: Year/Month/Day)
 Changes for 1.1.2
 *08/10/15:
+   * Don't allow resizing to negative dimensions (Mathias)
+     Window.cc/hh
    * Ignore XRandr events that don't change the screen size (Mark)
      Screen.cc FbTk/FbWindow.cc/hh
 *08/10/13:
diff --git a/src/Window.cc b/src/Window.cc
index d23bf44..4b4d1dc 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -2433,19 +2433,15 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
         int borderw = frame().window().borderWidth();
         //!! TODO(tabs): the below test ought to be in FbWinFrame
         // if mouse is currently on the window border, ignore it
-        if ( ! insideBorder(frame(),
-                            me.x_root, me.y_root, borderw)  &&
+        if ( ! insideBorder(frame(), me.x_root, me.y_root, borderw)  &&
              ( !frame().externalTabMode() ||
-               ! insideBorder(frame().tabcontainer(),
-                              me.x_root, me.y_root, borderw) )
+               ! insideBorder(frame().tabcontainer(), me.x_root, me.y_root, borderw) )
 
              || // or if mouse was on border when it was last clicked
 
-             ! insideBorder(frame(),
-                            m_last_button_x, m_last_button_y, borderw) &&
+             ! insideBorder(frame(), m_last_button_x, m_last_button_y, borderw) &&
              ( ! frame().externalTabMode() ||
-               ! insideBorder(frame().tabcontainer(),
-                              m_last_button_x, m_last_button_y, borderw ) ) ) {
+               ! insideBorder(frame().tabcontainer(), m_last_button_x, m_last_button_y, borderw ) ) ) {
             return;
         }
     }
@@ -2563,11 +2559,12 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
 
             int old_resize_x = m_last_resize_x;
             int old_resize_y = m_last_resize_y;
-            unsigned int old_resize_w = m_last_resize_w;
-            unsigned int old_resize_h = m_last_resize_h;
+            int old_resize_w = m_last_resize_w;
+            int old_resize_h = m_last_resize_h;
 
             int dx = me.x - m_button_grab_x;
             int dy = me.y - m_button_grab_y;
+
             if (m_resize_corner == LEFTTOP || m_resize_corner == LEFTBOTTOM ||
                 m_resize_corner == LEFT) {
                 m_last_resize_w = frame().width() - dx;
@@ -2598,7 +2595,7 @@ void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
                 }
             }
 
-            fixsize();
+            fixSize();
             frame().displaySize(m_last_resize_w, m_last_resize_h);
 
             if (old_resize_x != m_last_resize_x ||
@@ -3107,7 +3104,7 @@ void FluxboxWindow::startResizing(int x, int y, ReferenceCorner dir) {
     m_last_resize_w = frame().width();
     m_last_resize_h = frame().height();
 
-    fixsize();
+    fixSize();
     frame().displaySize(m_last_resize_w, m_last_resize_h);
 
     parent().drawRectangle(screen().rootTheme()->opGC(),
@@ -3127,7 +3124,7 @@ void FluxboxWindow::stopResizing(bool interrupted) {
     screen().hideGeometry();
 
     if (!interrupted) {
-        fixsize();
+        fixSize();
 
         moveResize(m_last_resize_x, m_last_resize_y,
                    m_last_resize_w, m_last_resize_h);
@@ -3375,8 +3372,21 @@ bool FluxboxWindow::isTransient() const {
 
 int FluxboxWindow::initialState() const { return m_client->initial_state; }
 
-void FluxboxWindow::fixsize() {
-    frame().applySizeHints(m_last_resize_w, m_last_resize_h);
+void FluxboxWindow::fixSize() {
+
+    // m_last_resize_w / m_last_resize_h could be negative
+    // due to user interactions. check here and limit
+    unsigned int w = 1;
+    unsigned int h = 1;
+    if (m_last_resize_w > 0)
+        w = m_last_resize_w;
+    if (m_last_resize_h > 0)
+        h = m_last_resize_h;
+
+    frame().applySizeHints(w, h);
+
+    m_last_resize_w = w;
+    m_last_resize_h = h;
 
     // move X if necessary
     if (m_resize_corner == LEFTTOP || m_resize_corner == LEFTBOTTOM ||
diff --git a/src/Window.hh b/src/Window.hh
index 97ece55..bf177b4 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -507,7 +507,7 @@ private:
     // modifies left and top if snap is necessary
     void doSnapping(int &left, int &top);
     // user_w/h return the values that should be shown to the user
-    void fixsize();
+    void fixSize();
     void moveResizeClient(WinClient &client);
     /// sends configurenotify to all clients
     void sendConfigureNotify();
@@ -547,7 +547,7 @@ private:
     int m_button_grab_x, m_button_grab_y; // handles last button press event for move
     int m_last_resize_x, m_last_resize_y; // handles last button press event for resize
     int m_last_move_x, m_last_move_y; // handles last pos for non opaque moving
-    unsigned int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window"
+    int m_last_resize_h, m_last_resize_w; // handles height/width for resize "window"
 
     timeval m_last_keypress_time;
 
@@ -562,16 +562,16 @@ private:
     Client2ButtonMap m_labelbuttons;
 
     SizeHints m_size_hint;
-    struct _decorations {
-        bool titlebar, handle, border, iconify,
-            maximize, close, menu, sticky, shade, tab, enabled;
+    struct {
+        bool titlebar:1, handle:1, border:1, iconify:1,
+            maximize:1, close:1, menu:1, sticky:1, shade:1, tab:1, enabled:1;
     } decorations;
 
     std::vector<WinButton::Type> m_titlebar_buttons[2];
     bool m_toggled_decos;
 
-    struct _functions {
-        bool resize, move, iconify, maximize, close, tabable;
+    struct {
+        bool resize:1, move:1, iconify:1, maximize:1, close:1, tabable:1;
     } functions;
 
     typedef FbTk::ConstObjectAccessor<bool, FocusControl> BoolAcc;
-- 
cgit v0.11.2