• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/common/content_settings.h"
6 #include "chrome/common/render_messages.h"
7 #include "chrome/renderer/content_settings_observer.h"
8 #include "chrome/test/base/chrome_render_view_test.h"
9 #include "content/public/renderer/render_view.h"
10 #include "ipc/ipc_message_macros.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/WebKit/public/web/WebView.h"
14 
15 using testing::_;
16 using testing::DeleteArg;
17 
18 namespace {
19 
20 class MockContentSettingsObserver : public ContentSettingsObserver {
21  public:
22   explicit MockContentSettingsObserver(content::RenderView* render_view);
23 
24   virtual bool Send(IPC::Message* message);
25 
26   MOCK_METHOD1(OnContentBlocked,
27                void(ContentSettingsType));
28 
29   MOCK_METHOD5(OnAllowDOMStorage,
30                void(int, const GURL&, const GURL&, bool, IPC::Message*));
31   GURL image_url_;
32   std::string image_origin_;
33 };
34 
MockContentSettingsObserver(content::RenderView * render_view)35 MockContentSettingsObserver::MockContentSettingsObserver(
36     content::RenderView* render_view)
37     : ContentSettingsObserver(render_view, NULL),
38       image_url_("http://www.foo.com/image.jpg"),
39       image_origin_("http://www.foo.com") {
40 }
41 
Send(IPC::Message * message)42 bool MockContentSettingsObserver::Send(IPC::Message* message) {
43   IPC_BEGIN_MESSAGE_MAP(MockContentSettingsObserver, *message)
44     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ContentBlocked, OnContentBlocked)
45     IPC_MESSAGE_HANDLER_DELAY_REPLY(ChromeViewHostMsg_AllowDOMStorage,
46                                     OnAllowDOMStorage)
47     IPC_MESSAGE_UNHANDLED(ADD_FAILURE())
48   IPC_END_MESSAGE_MAP()
49 
50   // Our super class deletes the message.
51   return RenderViewObserver::Send(message);
52 }
53 
54 }  // namespace
55 
TEST_F(ChromeRenderViewTest,DidBlockContentType)56 TEST_F(ChromeRenderViewTest, DidBlockContentType) {
57   MockContentSettingsObserver observer(view_);
58   EXPECT_CALL(observer,
59               OnContentBlocked(CONTENT_SETTINGS_TYPE_COOKIES));
60   observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES);
61 
62   // Blocking the same content type a second time shouldn't send a notification.
63   observer.DidBlockContentType(CONTENT_SETTINGS_TYPE_COOKIES);
64   ::testing::Mock::VerifyAndClearExpectations(&observer);
65 }
66 
67 // Tests that multiple invokations of AllowDOMStorage result in a single IPC.
68 // Fails due to http://crbug.com/104300
TEST_F(ChromeRenderViewTest,DISABLED_AllowDOMStorage)69 TEST_F(ChromeRenderViewTest, DISABLED_AllowDOMStorage) {
70   // Load some HTML, so we have a valid security origin.
71   LoadHTML("<html></html>");
72   MockContentSettingsObserver observer(view_);
73   ON_CALL(observer,
74           OnAllowDOMStorage(_, _, _, _, _)).WillByDefault(DeleteArg<4>());
75   EXPECT_CALL(observer,
76               OnAllowDOMStorage(_, _, _, _, _));
77   observer.allowStorage(view_->GetWebView()->focusedFrame(), true);
78 
79   // Accessing localStorage from the same origin again shouldn't result in a
80   // new IPC.
81   observer.allowStorage(view_->GetWebView()->focusedFrame(), true);
82   ::testing::Mock::VerifyAndClearExpectations(&observer);
83 }
84 
85 // Regression test for http://crbug.com/35011
TEST_F(ChromeRenderViewTest,JSBlockSentAfterPageLoad)86 TEST_F(ChromeRenderViewTest, JSBlockSentAfterPageLoad) {
87   // 1. Load page with JS.
88   std::string html = "<html>"
89                      "<head>"
90                      "<script>document.createElement('div');</script>"
91                      "</head>"
92                      "<body>"
93                      "</body>"
94                      "</html>";
95   render_thread_->sink().ClearMessages();
96   LoadHTML(html.c_str());
97 
98   // 2. Block JavaScript.
99   RendererContentSettingRules content_setting_rules;
100   ContentSettingsForOneType& script_setting_rules =
101       content_setting_rules.script_rules;
102   script_setting_rules.push_back(
103       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
104                                   ContentSettingsPattern::Wildcard(),
105                                   CONTENT_SETTING_BLOCK,
106                                   std::string(),
107                                   false));
108   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
109   observer->SetContentSettingRules(&content_setting_rules);
110 
111   // Make sure no pending messages are in the queue.
112   ProcessPendingMessages();
113   render_thread_->sink().ClearMessages();
114 
115   // 3. Reload page.
116   std::string url_str = "data:text/html;charset=utf-8,";
117   url_str.append(html);
118   GURL url(url_str);
119   Reload(url);
120   ProcessPendingMessages();
121 
122   // 4. Verify that the notification that javascript was blocked is sent after
123   //    the navigation notifiction is sent.
124   int navigation_index = -1;
125   int block_index = -1;
126   for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
127     const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
128     if (msg->type() == GetNavigationIPCType())
129       navigation_index = i;
130     if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
131       block_index = i;
132   }
133   EXPECT_NE(-1, navigation_index);
134   EXPECT_NE(-1, block_index);
135   EXPECT_LT(navigation_index, block_index);
136 }
137 
TEST_F(ChromeRenderViewTest,PluginsTemporarilyAllowed)138 TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) {
139   // Load some HTML.
140   LoadHTML("<html>Foo</html>");
141 
142   std::string foo_plugin = "foo";
143   std::string bar_plugin = "bar";
144 
145   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
146   EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(foo_plugin));
147 
148   // Temporarily allow the "foo" plugin.
149   OnMessageReceived(ChromeViewMsg_LoadBlockedPlugins(MSG_ROUTING_NONE,
150                                                      foo_plugin));
151   EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
152   EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
153 
154   // Simulate a navigation within the page.
155   DidNavigateWithinPage(GetMainFrame(), true);
156   EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
157   EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
158 
159   // Navigate to a different page.
160   LoadHTML("<html>Bar</html>");
161   EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(foo_plugin));
162   EXPECT_FALSE(observer->IsPluginTemporarilyAllowed(bar_plugin));
163 
164   // Temporarily allow all plugins.
165   OnMessageReceived(ChromeViewMsg_LoadBlockedPlugins(MSG_ROUTING_NONE,
166                                                      std::string()));
167   EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(foo_plugin));
168   EXPECT_TRUE(observer->IsPluginTemporarilyAllowed(bar_plugin));
169 }
170 
TEST_F(ChromeRenderViewTest,ImagesBlockedByDefault)171 TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) {
172   MockContentSettingsObserver mock_observer(view_);
173 
174   // Load some HTML.
175   LoadHTML("<html>Foo</html>");
176 
177   // Set the default image blocking setting.
178   RendererContentSettingRules content_setting_rules;
179   ContentSettingsForOneType& image_setting_rules =
180       content_setting_rules.image_rules;
181   image_setting_rules.push_back(
182       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
183                                   ContentSettingsPattern::Wildcard(),
184                                   CONTENT_SETTING_BLOCK,
185                                   std::string(),
186                                   false));
187 
188   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
189   observer->SetContentSettingRules(&content_setting_rules);
190   EXPECT_CALL(mock_observer,
191               OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES));
192   EXPECT_FALSE(observer->allowImage(GetMainFrame(),
193                                     true, mock_observer.image_url_));
194   ::testing::Mock::VerifyAndClearExpectations(&observer);
195 
196   // Create an exception which allows the image.
197   image_setting_rules.insert(
198       image_setting_rules.begin(),
199       ContentSettingPatternSource(
200           ContentSettingsPattern::Wildcard(),
201           ContentSettingsPattern::FromString(mock_observer.image_origin_),
202           CONTENT_SETTING_ALLOW,
203           std::string(),
204           false));
205 
206   EXPECT_CALL(
207       mock_observer,
208       OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
209   EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
210                                    mock_observer.image_url_));
211   ::testing::Mock::VerifyAndClearExpectations(&observer);
212 }
213 
TEST_F(ChromeRenderViewTest,ImagesAllowedByDefault)214 TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) {
215   MockContentSettingsObserver mock_observer(view_);
216 
217   // Load some HTML.
218   LoadHTML("<html>Foo</html>");
219 
220   // Set the default image blocking setting.
221   RendererContentSettingRules content_setting_rules;
222   ContentSettingsForOneType& image_setting_rules =
223       content_setting_rules.image_rules;
224   image_setting_rules.push_back(
225       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
226                                   ContentSettingsPattern::Wildcard(),
227                                   CONTENT_SETTING_ALLOW,
228                                   std::string(),
229                                   false));
230 
231   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
232   observer->SetContentSettingRules(&content_setting_rules);
233   EXPECT_CALL(
234       mock_observer,
235       OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
236   EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
237                                    mock_observer.image_url_));
238   ::testing::Mock::VerifyAndClearExpectations(&observer);
239 
240   // Create an exception which blocks the image.
241   image_setting_rules.insert(
242       image_setting_rules.begin(),
243       ContentSettingPatternSource(
244           ContentSettingsPattern::Wildcard(),
245           ContentSettingsPattern::FromString(mock_observer.image_origin_),
246           CONTENT_SETTING_BLOCK,
247           std::string(),
248           false));
249   EXPECT_CALL(mock_observer,
250               OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES));
251   EXPECT_FALSE(observer->allowImage(GetMainFrame(),
252                                     true, mock_observer.image_url_));
253   ::testing::Mock::VerifyAndClearExpectations(&observer);
254 }
255 
TEST_F(ChromeRenderViewTest,ContentSettingsBlockScripts)256 TEST_F(ChromeRenderViewTest, ContentSettingsBlockScripts) {
257   // Set the content settings for scripts.
258   RendererContentSettingRules content_setting_rules;
259   ContentSettingsForOneType& script_setting_rules =
260       content_setting_rules.script_rules;
261   script_setting_rules.push_back(
262       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
263                                   ContentSettingsPattern::Wildcard(),
264                                   CONTENT_SETTING_BLOCK,
265                                   std::string(),
266                                   false));
267 
268   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
269   observer->SetContentSettingRules(&content_setting_rules);
270 
271   // Load a page which contains a script.
272   std::string html = "<html>"
273                      "<head>"
274                      "<script src='data:foo'></script>"
275                      "</head>"
276                      "<body>"
277                      "</body>"
278                      "</html>";
279   LoadHTML(html.c_str());
280 
281   // Verify that the script was blocked.
282   bool was_blocked = false;
283   for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
284     const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
285     if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
286       was_blocked = true;
287   }
288   EXPECT_TRUE(was_blocked);
289 }
290 
TEST_F(ChromeRenderViewTest,ContentSettingsAllowScripts)291 TEST_F(ChromeRenderViewTest, ContentSettingsAllowScripts) {
292   // Set the content settings for scripts.
293   RendererContentSettingRules content_setting_rules;
294   ContentSettingsForOneType& script_setting_rules =
295       content_setting_rules.script_rules;
296   script_setting_rules.push_back(
297       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
298                                   ContentSettingsPattern::Wildcard(),
299                                   CONTENT_SETTING_ALLOW,
300                                   std::string(),
301                                   false));
302 
303   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
304   observer->SetContentSettingRules(&content_setting_rules);
305 
306   // Load a page which contains a script.
307   std::string html = "<html>"
308                      "<head>"
309                      "<script src='data:foo'></script>"
310                      "</head>"
311                      "<body>"
312                      "</body>"
313                      "</html>";
314   LoadHTML(html.c_str());
315 
316   // Verify that the script was not blocked.
317   bool was_blocked = false;
318   for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
319     const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
320     if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
321       was_blocked = true;
322   }
323   EXPECT_FALSE(was_blocked);
324 }
325 
TEST_F(ChromeRenderViewTest,ContentSettingsInterstitialPages)326 TEST_F(ChromeRenderViewTest, ContentSettingsInterstitialPages) {
327   MockContentSettingsObserver mock_observer(view_);
328   // Block scripts.
329   RendererContentSettingRules content_setting_rules;
330   ContentSettingsForOneType& script_setting_rules =
331       content_setting_rules.script_rules;
332   script_setting_rules.push_back(
333       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
334                                   ContentSettingsPattern::Wildcard(),
335                                   CONTENT_SETTING_BLOCK,
336                                   std::string(),
337                                   false));
338   // Block images.
339   ContentSettingsForOneType& image_setting_rules =
340       content_setting_rules.image_rules;
341   image_setting_rules.push_back(
342       ContentSettingPatternSource(ContentSettingsPattern::Wildcard(),
343                                   ContentSettingsPattern::Wildcard(),
344                                   CONTENT_SETTING_BLOCK,
345                                   std::string(),
346                                   false));
347 
348   ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_);
349   observer->SetContentSettingRules(&content_setting_rules);
350   observer->OnSetAsInterstitial();
351 
352   // Load a page which contains a script.
353   std::string html = "<html>"
354                      "<head>"
355                      "<script src='data:foo'></script>"
356                      "</head>"
357                      "<body>"
358                      "</body>"
359                      "</html>";
360   LoadHTML(html.c_str());
361 
362   // Verify that the script was allowed.
363   bool was_blocked = false;
364   for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) {
365     const IPC::Message* msg = render_thread_->sink().GetMessageAt(i);
366     if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID)
367       was_blocked = true;
368   }
369   EXPECT_FALSE(was_blocked);
370 
371   // Verify that images are allowed.
372   EXPECT_CALL(
373       mock_observer,
374       OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
375   EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
376                                    mock_observer.image_url_));
377   ::testing::Mock::VerifyAndClearExpectations(&observer);
378 }
379