Index: chrome/renderer/render_view.cc |
=================================================================== |
--- chrome/renderer/render_view.cc (revision 3394) |
+++ chrome/renderer/render_view.cc (working copy) |
@@ -93,6 +93,9 @@ |
// globally unique in the renderer. |
static int32 next_page_id_ = 1; |
+// The maximum number of popups that can be spawned from one page. |
+static const int kMaximumNumberOfUnacknowledgedPopups = 25; |
+ |
static const char* const kUnreachableWebDataURL = |
"chrome-resource://chromewebdata/"; |
@@ -150,7 +153,8 @@ |
history_back_list_count_(0), |
history_forward_list_count_(0), |
disable_popup_blocking_(false), |
- has_unload_listener_(false) { |
+ has_unload_listener_(false), |
+ decrement_shared_popup_at_destruction_(false) { |
resource_dispatcher_ = new ResourceDispatcher(this); |
#ifdef CHROME_PERSONALIZATION |
personalization_ = Personalization::CreateRendererPersonalization(); |
@@ -158,6 +162,9 @@ |
} |
RenderView::~RenderView() { |
+ if (decrement_shared_popup_at_destruction_) |
+ shared_popup_counter_->data--; |
+ |
resource_dispatcher_->ClearMessageSender(); |
// Clear any back-pointers that might still be held by plugins. |
PluginDelegateList::iterator it = plugin_delegates_.begin(); |
@@ -175,17 +182,20 @@ |
} |
/*static*/ |
-RenderView* RenderView::Create(HWND parent_hwnd, |
- HANDLE modal_dialog_event, |
- int32 opener_id, |
- const WebPreferences& webkit_prefs, |
- int32 routing_id) { |
+RenderView* RenderView::Create( |
+ HWND parent_hwnd, |
+ HANDLE modal_dialog_event, |
+ int32 opener_id, |
+ const WebPreferences& webkit_prefs, |
+ SharedRenderViewCounter* counter, |
+ int32 routing_id) { |
DCHECK(routing_id != MSG_ROUTING_NONE); |
scoped_refptr<RenderView> view = new RenderView(); |
view->Init(parent_hwnd, |
modal_dialog_event, |
opener_id, |
webkit_prefs, |
+ counter, |
routing_id); // adds reference |
return view; |
} |
@@ -225,12 +235,22 @@ |
HANDLE modal_dialog_event, |
int32 opener_id, |
const WebPreferences& webkit_prefs, |
+ SharedRenderViewCounter* counter, |
int32 routing_id) { |
DCHECK(!webview()); |
if (opener_id != MSG_ROUTING_NONE) |
opener_id_ = opener_id; |
+ if (counter) { |
+ shared_popup_counter_ = counter; |
+ shared_popup_counter_->data++; |
+ decrement_shared_popup_at_destruction_ = true; |
+ } else { |
+ shared_popup_counter_ = new SharedRenderViewCounter(0); |
+ decrement_shared_popup_at_destruction_ = false; |
+ } |
+ |
// Avoid a leak here by not assigning, since WebView::Create addrefs for us. |
WebWidget* view = WebView::Create(this, webkit_prefs); |
webwidget_.swap(&view); |
@@ -340,6 +360,8 @@ |
#endif |
IPC_MESSAGE_HANDLER(ViewMsg_HandleMessageFromExternalHost, |
OnMessageFromExternalHost) |
+ IPC_MESSAGE_HANDLER(ViewMsg_DisassociateFromPopupCount, |
+ OnDisassociateFromPopupCount) |
// Have the super handle all other messages. |
IPC_MESSAGE_UNHANDLED(RenderWidget::OnMessageReceived(message)) |
IPC_END_MESSAGE_MAP() |
@@ -1646,6 +1668,10 @@ |
} |
WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) { |
+ // Check to make sure we aren't overloading on popups. |
+ if (shared_popup_counter_->data > kMaximumNumberOfUnacknowledgedPopups) |
+ return NULL; |
+ |
int32 routing_id = MSG_ROUTING_NONE; |
HANDLE modal_dialog_event = NULL; |
bool result = RenderThread::current()->Send( |
@@ -1659,7 +1685,8 @@ |
// The WebView holds a reference to this new RenderView |
const WebPreferences& prefs = webview->GetPreferences(); |
RenderView* view = RenderView::Create(NULL, modal_dialog_event, routing_id_, |
- prefs, routing_id); |
+ prefs, shared_popup_counter_, |
+ routing_id); |
view->set_opened_by_user_gesture(user_gesture); |
// Copy over the alternate error page URL so we can have alt error pages in |
@@ -2556,6 +2583,13 @@ |
main_frame->LoadRequest(request.get()); |
} |
+void RenderView::OnDisassociateFromPopupCount() { |
+ if (decrement_shared_popup_at_destruction_) |
+ shared_popup_counter_->data--; |
+ shared_popup_counter_ = new SharedRenderViewCounter(0); |
+ decrement_shared_popup_at_destruction_ = false; |
+} |
+ |
std::string RenderView::GetAltHTMLForTemplate( |
const DictionaryValue& error_strings, int template_resource_id) const { |
const StringPiece template_html( |
@@ -2570,4 +2604,3 @@ |
return jstemplate_builder::GetTemplateHtml( |
template_html, &error_strings, "t"); |
} |
- |