@@ -109,13 +109,22 @@ void CWebCore::DestroyWebView(CWebViewInterface* pWebViewInterface)
109109 CefRefPtr<CWebView> pWebView = dynamic_cast <CWebView*>(pWebViewInterface);
110110 if (pWebView)
111111 {
112+ // Mark as being destroyed to prevent new events/tasks
113+ pWebView->SetBeingDestroyed (true );
114+
112115 // Ensure that no attached events or tasks are in the queue
113116 RemoveWebViewEvents (pWebView.get ());
114117 RemoveWebViewTasks (pWebView.get ());
115118
119+ // Remove from list before closing to break reference cycles early
116120 m_WebViews.remove (pWebView);
117- // pWebView->Release(); // Do not release since other references get corrupted then
121+
122+ // CloseBrowser will eventually trigger OnBeforeClose which clears m_pWebView
123+ // This breaks the circular reference: CWebView -> CefBrowser -> CWebView
118124 pWebView->CloseBrowser ();
125+
126+ // Note: Do not call Release() - let CefRefPtr manage the lifecycle
127+ // The circular reference is broken via OnBeforeClose setting m_pWebView = nullptr
119128 }
120129}
121130
@@ -164,6 +173,18 @@ void CWebCore::AddEventToEventQueue(std::function<void()> event, CWebView* pWebV
164173
165174 std::lock_guard<std::mutex> lock (m_EventQueueMutex);
166175
176+ // Prevent unbounded queue growth - drop oldest events if queue is too large
177+ if (m_EventQueue.size () >= MAX_EVENT_QUEUE_SIZE)
178+ {
179+ // Log warning even in release builds as this indicates a serious issue
180+ g_pCore->GetConsole ()->Printf (" WARNING: Browser event queue size limit reached (%d), dropping oldest events" , MAX_EVENT_QUEUE_SIZE);
181+
182+ // Remove oldest 10% of events to make room
183+ auto removeCount = MAX_EVENT_QUEUE_SIZE / 10 ;
184+ for (size_t i = 0 ; i < removeCount && !m_EventQueue.empty (); ++i)
185+ m_EventQueue.pop_front ();
186+ }
187+
167188#ifndef MTA_DEBUG
168189 m_EventQueue.push_back (EventEntry (event, pWebView));
169190#else
@@ -215,6 +236,22 @@ void CWebCore::WaitForTask(std::function<void(bool)> task, CWebView* webView)
215236 std::future<void > result;
216237 {
217238 std::scoped_lock lock (m_TaskQueueMutex);
239+
240+ // Prevent unbounded queue growth - if queue is too large, oldest tasks will be dropped during pulse
241+ if (m_TaskQueue.size () >= MAX_TASK_QUEUE_SIZE)
242+ {
243+ #ifdef MTA_DEBUG
244+ g_pCore->GetConsole ()->Printf (" Warning: Task queue size limit reached (%d), task will be aborted" , MAX_TASK_QUEUE_SIZE);
245+ #endif
246+ // Must still queue the task to fulfill the future, but it will be aborted during processing
247+ // Removing oldest task to make room
248+ if (!m_TaskQueue.empty ())
249+ {
250+ m_TaskQueue.front ().task (true ); // Abort oldest task
251+ m_TaskQueue.pop_front ();
252+ }
253+ }
254+
218255 m_TaskQueue.emplace_back (TaskEntry{task, webView});
219256 result = m_TaskQueue.back ().task .get_future ();
220257 }
@@ -358,13 +395,39 @@ void CWebCore::AddAllowedPage(const SString& strURL, eWebFilterType filterType)
358395{
359396 std::lock_guard<std::recursive_mutex> lock (m_FilterMutex);
360397
398+ // Prevent unbounded whitelist growth - remove old REQUEST entries if limit reached
399+ if (m_Whitelist.size () >= MAX_WHITELIST_SIZE)
400+ {
401+ // Remove WEBFILTER_REQUEST entries (temporary session entries)
402+ for (auto iter = m_Whitelist.begin (); iter != m_Whitelist.end ();)
403+ {
404+ if (iter->second .second == eWebFilterType::WEBFILTER_REQUEST)
405+ m_Whitelist.erase (iter++);
406+ else
407+ ++iter;
408+ }
409+ }
410+
361411 m_Whitelist[strURL] = std::pair<bool , eWebFilterType>(true , filterType);
362412}
363413
364414void CWebCore::AddBlockedPage (const SString& strURL, eWebFilterType filterType)
365415{
366416 std::lock_guard<std::recursive_mutex> lock (m_FilterMutex);
367417
418+ // Prevent unbounded whitelist growth - remove old REQUEST entries if limit reached
419+ if (m_Whitelist.size () >= MAX_WHITELIST_SIZE)
420+ {
421+ // Remove WEBFILTER_REQUEST entries (temporary session entries)
422+ for (auto iter = m_Whitelist.begin (); iter != m_Whitelist.end ();)
423+ {
424+ if (iter->second .second == eWebFilterType::WEBFILTER_REQUEST)
425+ m_Whitelist.erase (iter++);
426+ else
427+ ++iter;
428+ }
429+ }
430+
368431 m_Whitelist[strURL] = std::pair<bool , eWebFilterType>(false , filterType);
369432}
370433
0 commit comments