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.
5 #include "base/path_service.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "content/browser/child_process_security_policy_impl.h"
8 #include "content/browser/frame_host/render_frame_host_impl.h"
9 #include "content/browser/gpu/gpu_surface_tracker.h"
10 #include "content/browser/renderer_host/render_message_filter.h"
11 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
12 #include "content/browser/renderer_host/render_widget_helper.h"
13 #include "content/common/frame_messages.h"
14 #include "content/common/input_messages.h"
15 #include "content/common/view_messages.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/common/bindings_policy.h"
19 #include "content/public/common/drop_data.h"
20 #include "content/public/common/url_constants.h"
21 #include "content/public/test/mock_render_process_host.h"
22 #include "content/test/test_content_browser_client.h"
23 #include "content/test/test_render_view_host.h"
24 #include "content/test/test_web_contents.h"
25 #include "net/base/filename_util.h"
26 #include "third_party/WebKit/public/web/WebDragOperation.h"
27 #include "ui/base/page_transition_types.h"
31 class RenderViewHostTestBrowserClient
: public TestContentBrowserClient
{
33 RenderViewHostTestBrowserClient() {}
34 ~RenderViewHostTestBrowserClient() override
{}
36 bool IsHandledURL(const GURL
& url
) override
{
37 return url
.scheme() == url::kFileScheme
;
41 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestBrowserClient
);
44 class RenderViewHostTest
: public RenderViewHostImplTestHarness
{
46 RenderViewHostTest() : old_browser_client_(NULL
) {}
47 ~RenderViewHostTest() override
{}
49 void SetUp() override
{
50 RenderViewHostImplTestHarness::SetUp();
51 old_browser_client_
= SetBrowserClientForTesting(&test_browser_client_
);
54 void TearDown() override
{
55 SetBrowserClientForTesting(old_browser_client_
);
56 RenderViewHostImplTestHarness::TearDown();
60 RenderViewHostTestBrowserClient test_browser_client_
;
61 ContentBrowserClient
* old_browser_client_
;
63 DISALLOW_COPY_AND_ASSIGN(RenderViewHostTest
);
66 // All about URLs reported by the renderer should get rewritten to about:blank.
67 // See RenderViewHost::OnNavigate for a discussion.
68 TEST_F(RenderViewHostTest
, FilterAbout
) {
69 main_test_rfh()->NavigateAndCommitRendererInitiated(
70 1, true, GURL("about:cache"));
71 ASSERT_TRUE(controller().GetVisibleEntry());
72 EXPECT_EQ(GURL(url::kAboutBlankURL
),
73 controller().GetVisibleEntry()->GetURL());
76 // Create a full screen popup RenderWidgetHost and View.
77 TEST_F(RenderViewHostTest
, CreateFullscreenWidget
) {
78 int32 routing_id
= process()->GetNextRoutingID();
79 int32 surface_id
= GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
80 process()->GetID(), routing_id
);
81 test_rvh()->CreateNewFullscreenWidget(routing_id
, surface_id
);
84 // Ensure we do not grant bindings to a process shared with unprivileged views.
85 TEST_F(RenderViewHostTest
, DontGrantBindingsToSharedProcess
) {
86 // Create another view in the same process.
87 scoped_ptr
<TestWebContents
> new_web_contents(
88 TestWebContents::Create(browser_context(), rvh()->GetSiteInstance()));
90 rvh()->AllowBindings(BINDINGS_POLICY_WEB_UI
);
91 EXPECT_FALSE(rvh()->GetEnabledBindings() & BINDINGS_POLICY_WEB_UI
);
94 class MockDraggingRenderViewHostDelegateView
95 : public RenderViewHostDelegateView
{
97 ~MockDraggingRenderViewHostDelegateView() override
{}
98 void StartDragging(const DropData
& drop_data
,
99 blink::WebDragOperationsMask allowed_ops
,
100 const gfx::ImageSkia
& image
,
101 const gfx::Vector2d
& image_offset
,
102 const DragEventSourceInfo
& event_info
) override
{
103 drag_url_
= drop_data
.url
;
104 html_base_url_
= drop_data
.html_base_url
;
106 void UpdateDragCursor(blink::WebDragOperation operation
) override
{}
107 void GotFocus() override
{}
108 void TakeFocus(bool reverse
) override
{}
109 virtual void UpdatePreferredSize(const gfx::Size
& pref_size
) {}
115 GURL
html_base_url() {
116 return html_base_url_
;
124 TEST_F(RenderViewHostTest
, StartDragging
) {
125 TestWebContents
* web_contents
= contents();
126 MockDraggingRenderViewHostDelegateView delegate_view
;
127 web_contents
->set_delegate_view(&delegate_view
);
130 GURL file_url
= GURL("file:///home/user/secrets.txt");
131 drop_data
.url
= file_url
;
132 drop_data
.html_base_url
= file_url
;
133 test_rvh()->TestOnStartDragging(drop_data
);
134 EXPECT_EQ(GURL(url::kAboutBlankURL
), delegate_view
.drag_url());
135 EXPECT_EQ(GURL(url::kAboutBlankURL
), delegate_view
.html_base_url());
137 GURL http_url
= GURL("http://www.domain.com/index.html");
138 drop_data
.url
= http_url
;
139 drop_data
.html_base_url
= http_url
;
140 test_rvh()->TestOnStartDragging(drop_data
);
141 EXPECT_EQ(http_url
, delegate_view
.drag_url());
142 EXPECT_EQ(http_url
, delegate_view
.html_base_url());
144 GURL https_url
= GURL("https://www.domain.com/index.html");
145 drop_data
.url
= https_url
;
146 drop_data
.html_base_url
= https_url
;
147 test_rvh()->TestOnStartDragging(drop_data
);
148 EXPECT_EQ(https_url
, delegate_view
.drag_url());
149 EXPECT_EQ(https_url
, delegate_view
.html_base_url());
151 GURL javascript_url
= GURL("javascript:alert('I am a bookmarklet')");
152 drop_data
.url
= javascript_url
;
153 drop_data
.html_base_url
= http_url
;
154 test_rvh()->TestOnStartDragging(drop_data
);
155 EXPECT_EQ(javascript_url
, delegate_view
.drag_url());
156 EXPECT_EQ(http_url
, delegate_view
.html_base_url());
159 TEST_F(RenderViewHostTest
, DragEnteredFileURLsStillBlocked
) {
160 DropData dropped_data
;
161 gfx::Point client_point
;
162 gfx::Point screen_point
;
163 // We use "//foo/bar" path (rather than "/foo/bar") since dragged paths are
164 // expected to be absolute on any platforms.
165 base::FilePath
highlighted_file_path(FILE_PATH_LITERAL("//tmp/foo.html"));
166 base::FilePath
dragged_file_path(FILE_PATH_LITERAL("//tmp/image.jpg"));
167 base::FilePath
sensitive_file_path(FILE_PATH_LITERAL("//etc/passwd"));
168 GURL highlighted_file_url
= net::FilePathToFileURL(highlighted_file_path
);
169 GURL dragged_file_url
= net::FilePathToFileURL(dragged_file_path
);
170 GURL sensitive_file_url
= net::FilePathToFileURL(sensitive_file_path
);
171 dropped_data
.url
= highlighted_file_url
;
172 dropped_data
.filenames
.push_back(
173 ui::FileInfo(dragged_file_path
, base::FilePath()));
175 rvh()->DragTargetDragEnter(dropped_data
, client_point
, screen_point
,
176 blink::WebDragOperationNone
, 0);
178 int id
= process()->GetID();
179 ChildProcessSecurityPolicyImpl
* policy
=
180 ChildProcessSecurityPolicyImpl::GetInstance();
182 EXPECT_FALSE(policy
->CanRequestURL(id
, highlighted_file_url
));
183 EXPECT_FALSE(policy
->CanReadFile(id
, highlighted_file_path
));
184 EXPECT_TRUE(policy
->CanRequestURL(id
, dragged_file_url
));
185 EXPECT_TRUE(policy
->CanReadFile(id
, dragged_file_path
));
186 EXPECT_FALSE(policy
->CanRequestURL(id
, sensitive_file_url
));
187 EXPECT_FALSE(policy
->CanReadFile(id
, sensitive_file_path
));
190 TEST_F(RenderViewHostTest
, MessageWithBadHistoryItemFiles
) {
191 base::FilePath file_path
;
192 EXPECT_TRUE(PathService::Get(base::DIR_TEMP
, &file_path
));
193 file_path
= file_path
.AppendASCII("foo");
194 EXPECT_EQ(0, process()->bad_msg_count());
195 test_rvh()->TestOnUpdateStateWithFile(-1, file_path
);
196 EXPECT_EQ(1, process()->bad_msg_count());
198 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
199 process()->GetID(), file_path
);
200 test_rvh()->TestOnUpdateStateWithFile(-1, file_path
);
201 EXPECT_EQ(1, process()->bad_msg_count());
205 void SetBadFilePath(const GURL
& url
,
206 const base::FilePath
& file_path
,
207 FrameHostMsg_DidCommitProvisionalLoad_Params
* params
) {
209 PageState::CreateForTesting(url
, false, "data", &file_path
);
213 TEST_F(RenderViewHostTest
, NavigationWithBadHistoryItemFiles
) {
214 GURL
url("http://www.google.com");
215 base::FilePath file_path
;
216 EXPECT_TRUE(PathService::Get(base::DIR_TEMP
, &file_path
));
217 file_path
= file_path
.AppendASCII("bar");
218 auto set_bad_file_path_callback
= base::Bind(SetBadFilePath
, url
, file_path
);
220 EXPECT_EQ(0, process()->bad_msg_count());
221 main_test_rfh()->SendRendererInitiatedNavigationRequest(url
, false);
222 main_test_rfh()->PrepareForCommit();
223 contents()->GetMainFrame()->SendNavigateWithModificationCallback(
224 1, 1, true, url
, set_bad_file_path_callback
);
225 EXPECT_EQ(1, process()->bad_msg_count());
227 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
228 process()->GetID(), file_path
);
229 main_test_rfh()->SendRendererInitiatedNavigationRequest(url
, false);
230 main_test_rfh()->PrepareForCommit();
231 contents()->GetMainFrame()->SendNavigateWithModificationCallback(
232 2, 2, true, url
, set_bad_file_path_callback
);
233 EXPECT_EQ(1, process()->bad_msg_count());
236 TEST_F(RenderViewHostTest
, RoutingIdSane
) {
237 RenderFrameHostImpl
* root_rfh
=
238 contents()->GetFrameTree()->root()->current_frame_host();
239 EXPECT_EQ(contents()->GetMainFrame(), root_rfh
);
240 EXPECT_EQ(test_rvh()->GetProcess(), root_rfh
->GetProcess());
241 EXPECT_NE(test_rvh()->GetRoutingID(), root_rfh
->routing_id());
244 class TestSaveImageFromDataURL
: public RenderMessageFilter
{
246 TestSaveImageFromDataURL(
247 BrowserContext
* context
)
248 : RenderMessageFilter(
251 context
->GetRequestContext(),
260 url_string_
= std::string();
261 is_downloaded_
= false;
264 std::string
& UrlString() const {
268 bool IsDownloaded() const {
269 return is_downloaded_
;
272 void Test(const std::string
& url
) {
273 OnMessageReceived(ViewHostMsg_SaveImageFromDataURL(0, 0, url
));
277 ~TestSaveImageFromDataURL() override
{}
278 void DownloadUrl(int render_view_id
,
281 const Referrer
& referrer
,
282 const base::string16
& suggested_name
,
283 const bool use_prompt
) const override
{
284 url_string_
= url
.spec();
285 is_downloaded_
= true;
289 mutable std::string url_string_
;
290 mutable bool is_downloaded_
;
293 TEST_F(RenderViewHostTest
, SaveImageFromDataURL
) {
294 scoped_refptr
<TestSaveImageFromDataURL
> tester(
295 new TestSaveImageFromDataURL(browser_context()));
298 tester
->Test("http://non-data-url.com");
299 EXPECT_EQ(tester
->UrlString(), "");
300 EXPECT_FALSE(tester
->IsDownloaded());
302 const std::string data_url
= "data:image/gif;base64,"
303 "R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=";
306 tester
->Test(data_url
);
307 EXPECT_EQ(tester
->UrlString(), data_url
);
308 EXPECT_TRUE(tester
->IsDownloaded());
311 } // namespace content