Bug 531341 Stack overflow crash related to scrolling with trackpad and plugins [@ nsWindow::HandleScrollingPlugins] [@ _SEH_prolog4 ] r=VYV03354
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 28 Jan 2010 17:39:51 +0900
changeset 37600 57f9a74ab7d3760c825488c7fa6212394b186fbf
parent 37599 d96f5ba97233629f07ccac3d4a6abd96175b3be7
child 37601 027ad991923707d3e5a56dbff97eb4d186c9fafe
push idunknown
push userunknown
push dateunknown
reviewersVYV03354
bugs531341
milestone1.9.3a1pre
Bug 531341 Stack overflow crash related to scrolling with trackpad and plugins [@ nsWindow::HandleScrollingPlugins] [@ _SEH_prolog4 ] r=VYV03354
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -376,17 +376,16 @@ nsWindow::nsWindow() : nsBaseWidget()
   mPrevWndProc          = nsnull;
   mOldIMC               = nsnull;
   mNativeDragTarget     = nsnull;
   mInDtor               = PR_FALSE;
   mIsVisible            = PR_FALSE;
   mHas3DBorder          = PR_FALSE;
   mIsInMouseCapture     = PR_FALSE;
   mIsTopWidgetWindow    = PR_FALSE;
-  mInScrollProcessing   = PR_FALSE;
   mUnicodeWidget        = PR_TRUE;
   mWindowType           = eWindowType_child;
   mBorderStyle          = eBorderStyle_default;
   mPopupType            = ePopupTypeAny;
   mDisplayPanFeedback   = PR_FALSE;
   mLastPoint.x          = 0;
   mLastPoint.y          = 0;
   mLastSize.width       = 0;
@@ -6046,16 +6045,21 @@ PRBool nsWindow::HandleScrollingPlugins(
   // The scroll event will be dispatched to the toplevel
   // window.  We need to give it to the child window
   aQuitProcessing = PR_FALSE; // default is to not stop processing
   POINT point;
   DWORD dwPoints = ::GetMessagePos();
   point.x = GET_X_LPARAM(dwPoints);
   point.y = GET_Y_LPARAM(dwPoints);
 
+  static PRBool sIsProcessing = PR_FALSE;
+  if (sIsProcessing) {
+    return PR_TRUE;  // the caller should handle this.
+  }
+
   static PRBool sMayBeUsingLogitechMouse = PR_FALSE;
   if (aMsg == WM_MOUSEHWHEEL) {
     // Logitech (Logicool) mouse driver (confirmed with 4.82.11 and MX-1100)
     // always sets 0 to the lParam of WM_MOUSEHWHEEL.  The driver SENDs one
     // message at first time, this time, ::GetMessagePos works fine.
     // Then, we will return 0 (0 means we process it) to the message. Then, the
     // driver will POST the same messages continuously during the wheel tilted.
     // But ::GetMessagePos API always returns (0, 0), even if the actual mouse
@@ -6110,40 +6114,37 @@ PRBool nsWindow::HandleScrollingPlugins(
     while (parentWnd) {
       nsWindow* parentWindow = GetNSWindowPtr(parentWnd);
       if (parentWindow) {
         // We have a child window - quite possibly a plugin window.
         // However, not all plugins are created equal - some will handle this 
         // message themselves, some will forward directly back to us, while 
         // others will call DefWndProc, which itself still forwards back to us.
         // So if we have sent it once, we need to handle it ourself.
-        if (mInScrollProcessing) {
-          destWnd = parentWnd;
-          destWindow = parentWindow;
-        } else {
-          // First time we have seen this message.
-          // Call the child - either it will consume it, or
-          // it will wind it's way back to us,triggering the destWnd case above
-          // either way,when the call returns,we are all done with the message,
-          mInScrollProcessing = PR_TRUE;
-          if (0 == ::SendMessageW(destWnd, aMsg, aWParam, aLParam))
-            aHandled = PR_TRUE;
-          destWnd = nsnull;
-          mInScrollProcessing = PR_FALSE;
-        }
+
+        // First time we have seen this message.
+        // Call the child - either it will consume it, or
+        // it will wind it's way back to us,triggering the destWnd case above
+        // either way,when the call returns,we are all done with the message,
+        sIsProcessing = PR_TRUE;
+        if (0 == ::SendMessageW(destWnd, aMsg, aWParam, aLParam))
+          aHandled = PR_TRUE;
+        sIsProcessing = PR_FALSE;
         return PR_FALSE; // break, but continue processing
       }
       parentWnd = ::GetParent(parentWnd);
     } // while parentWnd
   }
   if (destWnd == nsnull)
     return PR_FALSE;
   if (destWnd != mWnd) {
     if (destWindow) {
+      sIsProcessing = PR_TRUE;
       aHandled = destWindow->ProcessMessage(aMsg, aWParam, aLParam, aRetValue);
+      sIsProcessing = PR_FALSE;
       aQuitProcessing = PR_TRUE;
       return PR_FALSE; // break, and stop processing
     }
   #ifdef DEBUG
     else
       printf("WARNING: couldn't get child window for SCROLL event\n");
   #endif
   }
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -411,17 +411,16 @@ protected:
   HWND                  mWnd;
   WNDPROC               mPrevWndProc;
   HBRUSH                mBrush;
   PRPackedBool          mIsTopWidgetWindow;
   PRPackedBool          mHas3DBorder;
   PRPackedBool          mInDtor;
   PRPackedBool          mIsVisible;
   PRPackedBool          mIsInMouseCapture;
-  PRPackedBool          mInScrollProcessing;
   PRPackedBool          mUnicodeWidget;
   PRPackedBool          mPainting;
   char                  mLeadByte;
   PRUint32              mBlurSuppressLevel;
   nsContentType         mContentType;
   PRInt32               mMenuCmdId;
   DWORD_PTR             mOldStyle;
   DWORD_PTR             mOldExStyle;