Index: content/renderer/render_view_browsertest.cc |
diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc |
index fa357307a350ba0540c012431642f24d2a4a41f4..5fe5b37ebad666353680b005eea50749a5e784d9 100644 |
--- a/content/renderer/render_view_browsertest.cc |
+++ b/content/renderer/render_view_browsertest.cc |
@@ -2185,6 +2185,53 @@ TEST_F(RenderViewImplTest, HistoryIsProperlyUpdatedOnNavigation) { |
view()->historyForwardListCount() + 1); |
} |
+class ConsoleCallbackFilter : public IPC::Listener { |
+ public: |
+ explicit ConsoleCallbackFilter( |
+ base::Callback<void(const base::string16&)> callback) |
+ : callback_(callback) {} |
+ |
+ bool OnMessageReceived(const IPC::Message& msg) override { |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(ConsoleCallbackFilter, msg) |
+ IPC_MESSAGE_HANDLER(FrameHostMsg_DidAddMessageToConsole, |
+ OnDidAddMessageToConsole) |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ return handled; |
+ } |
+ |
+ void OnDidAddMessageToConsole(int32_t, |
+ const base::string16& message, |
+ int32_t, |
+ const base::string16&) { |
+ callback_.Run(message); |
+ } |
+ |
+ private: |
+ base::Callback<void(const base::string16&)> callback_; |
+}; |
+ |
+// Tests that there's no UaF after dispatchBeforeUnloadEvent. |
+// See https://crbug.com/666714. |
+TEST_F(RenderViewImplTest, DispatchBeforeUnloadCanDetachFrame) { |
+ LoadHTML( |
+ "<script>window.onbeforeunload = function() { " |
+ "window.console.log('OnBeforeUnload called'); }</script>"); |
+ std::unique_ptr<ConsoleCallbackFilter> callback_filter( |
Charlie Reis
2016/11/23 07:07:00
Nice. Let's add a comment explaining what this is
lfg
2016/11/23 16:48:02
Done. Can you do a quick sanity check to make sure
Charlie Reis
2016/11/23 17:47:11
Thanks-- looks good.
|
+ new ConsoleCallbackFilter(base::Bind( |
+ [](RenderFrameImpl* frame, const base::string16& msg) { |
+ EXPECT_EQ(base::UTF8ToUTF16("OnBeforeUnload called"), msg); |
+ frame->OnMessageReceived(FrameMsg_SwapOut( |
+ frame->GetRoutingID(), 1, false, FrameReplicationState())); |
+ }, |
+ base::Unretained(frame())))); |
+ render_thread_->sink().AddFilter(callback_filter.get()); |
+ frame()->OnMessageReceived( |
+ FrameMsg_BeforeUnload(frame()->GetRoutingID(), false)); |
+ render_thread_->sink().RemoveFilter(callback_filter.get()); |
+} |
+ |
TEST_F(RenderViewImplBlinkSettingsTest, Default) { |
DoSetUp(); |
EXPECT_FALSE(settings()->viewportEnabled()); |