Browse Source

KonvergoWindow: log/avoid potential event handling stack overflows

No doubt makes me feel awful.
Vincent Lang 7 years ago
parent
commit
a360c60f4d
2 changed files with 42 additions and 13 deletions
  1. 40 13
      src/ui/KonvergoWindow.cpp
  2. 2 0
      src/ui/KonvergoWindow.h

+ 40 - 13
src/ui/KonvergoWindow.cpp

@@ -21,6 +21,20 @@
 #include "Globals.h"
 #include "EventFilter.h"
 
+#define MAX_RECURSION_DEPTH 50
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+class ScopedDecrementer
+{
+  Q_DISABLE_COPY(ScopedDecrementer)
+
+  int* m_value;
+
+public:
+  ScopedDecrementer(int* value) : m_value(value) {}
+  ~ScopedDecrementer() { (*m_value)--; }
+};
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 KonvergoWindow::KonvergoWindow(QWindow* parent) :
   QQuickWindow(parent),
@@ -28,7 +42,8 @@ KonvergoWindow::KonvergoWindow(QWindow* parent) :
   m_lastWindowScale(-1), m_lastWebScale(-1), m_tvUIw(-1), m_tvUIh(-1),
   m_ignoreFullscreenSettingsChange(0),
   m_showedUpdateDialog(false),
-  m_osxPresentationOptions(0)
+  m_osxPresentationOptions(0),
+  m_eventRecursionDepth(0)
 {
   // NSWindowCollectionBehaviorFullScreenPrimary is only set on OSX if Qt::WindowFullscreenButtonHint is set on the window.
   setFlags(flags() | Qt::WindowFullscreenButtonHint);
@@ -342,6 +357,14 @@ void KonvergoWindow::playerWindowVisible(bool visible)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 void KonvergoWindow::updateMainSectionSettings(const QVariantMap& values)
 {
+  m_eventRecursionDepth++;
+  ScopedDecrementer decrement(&m_eventRecursionDepth);
+  if (m_eventRecursionDepth > MAX_RECURSION_DEPTH)
+  {
+    QLOG_ERROR() << "Maximum recursion depth reached! (updateMainSectionSettings)";
+    return;
+  }
+
   // update mouse visibility if needed
   if (values.find("disablemouse") != values.end())
   {
@@ -467,18 +490,6 @@ void KonvergoWindow::updateWindowState(bool saveGeo)
   InputComponent::Get().cancelAutoRepeat();
 }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-class ScopedDecrementer
-{
-  Q_DISABLE_COPY(ScopedDecrementer)
-
-  int* m_value;
-
-public:
-  ScopedDecrementer(int* value) : m_value(value) {}
-  ~ScopedDecrementer() { (*m_value)--; }
-};
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 QScreen* KonvergoWindow::findCurrentScreen()
 {
@@ -505,6 +516,14 @@ void KonvergoWindow::onVisibilityChanged(QWindow::Visibility visibility)
 {
   QLOG_DEBUG() << "QWindow visibility set to" << visibility;
 
+  m_eventRecursionDepth++;
+  ScopedDecrementer decrement(&m_eventRecursionDepth);
+  if (m_eventRecursionDepth > MAX_RECURSION_DEPTH)
+  {
+    QLOG_ERROR() << "Maximum recursion depth reached! (onVisibilityChanged)";
+    return;
+  }
+
 #ifdef Q_OS_WIN32
   if (visibility == QWindow::Windowed)
   {
@@ -632,6 +651,14 @@ void KonvergoWindow::toggleDebug()
 /////////////////////////////////////////////////////////////////////////////////////////
 void KonvergoWindow::updateSizeDependendProperties(const QSize& size)
 {
+  m_eventRecursionDepth++;
+  ScopedDecrementer decrement(&m_eventRecursionDepth);
+  if (m_eventRecursionDepth > MAX_RECURSION_DEPTH)
+  {
+    QLOG_ERROR() << "Maximum recursion depth reached! (updateSizeDependendProperties)";
+    return;
+  }
+
   qreal windowScale = CalculateScale(size);
   if (windowScale != m_lastWindowScale)
   {

+ 2 - 0
src/ui/KonvergoWindow.h

@@ -159,6 +159,8 @@ private:
   unsigned long m_osxPresentationOptions;
   QString m_currentScreenName;
 
+  int m_eventRecursionDepth;
+
   void setWebMode(bool newDesktopMode, bool fullscreen);
 
   static qreal CalculateScale(const QSize& size);