OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/safe_browsing/threat_dom_details.h" | 5 #include "chrome/renderer/safe_browsing/threat_dom_details.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
| 9 #include "base/strings/string_split.h" |
9 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "base/test/scoped_feature_list.h" |
10 #include "chrome/test/base/chrome_render_view_test.h" | 12 #include "chrome/test/base/chrome_render_view_test.h" |
11 #include "components/safe_browsing/common/safebrowsing_messages.h" | 13 #include "components/safe_browsing/common/safebrowsing_messages.h" |
| 14 #include "components/variations/variations_associated_data.h" |
12 #include "content/public/renderer/render_view.h" | 15 #include "content/public/renderer/render_view.h" |
13 #include "net/base/escape.h" | 16 #include "net/base/escape.h" |
| 17 #include "testing/gmock/include/gmock/gmock.h" |
14 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" | 18 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" |
15 #include "ui/native_theme/native_theme_switches.h" | 19 #include "ui/native_theme/native_theme_switches.h" |
16 | 20 |
17 typedef ChromeRenderViewTest ThreatDOMDetailsTest; | 21 namespace { |
| 22 |
| 23 std::unique_ptr<base::test::ScopedFeatureList> SetupTagAndAttributeFeature() { |
| 24 std::map<std::string, std::string> feature_params; |
| 25 feature_params[std::string(safe_browsing::kTagAndAttributeParamName)] = |
| 26 "div,foo,div,baz"; |
| 27 variations::AssociateVariationParams( |
| 28 safe_browsing::kThreatDomDetailsTagAndAttributeFeature.name, "Group", |
| 29 feature_params); |
| 30 base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial( |
| 31 safe_browsing::kThreatDomDetailsTagAndAttributeFeature.name, "Group"); |
| 32 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| 33 feature_list->InitializeFromCommandLine( |
| 34 safe_browsing::kThreatDomDetailsTagAndAttributeFeature.name, |
| 35 std::string()); |
| 36 feature_list->AssociateReportingFieldTrial( |
| 37 safe_browsing::kThreatDomDetailsTagAndAttributeFeature.name, |
| 38 base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial); |
| 39 std::unique_ptr<base::test::ScopedFeatureList> scoped_list( |
| 40 new base::test::ScopedFeatureList); |
| 41 scoped_list->InitWithFeatureList(std::move(feature_list)); |
| 42 return scoped_list; |
| 43 } |
| 44 |
| 45 } // namespace |
| 46 |
| 47 using ThreatDOMDetailsTest = ChromeRenderViewTest; |
| 48 |
| 49 using testing::ElementsAre; |
18 | 50 |
19 TEST_F(ThreatDOMDetailsTest, Everything) { | 51 TEST_F(ThreatDOMDetailsTest, Everything) { |
20 blink::WebRuntimeFeatures::enableOverlayScrollbars( | 52 blink::WebRuntimeFeatures::enableOverlayScrollbars( |
21 ui::IsOverlayScrollbarEnabled()); | 53 ui::IsOverlayScrollbarEnabled()); |
| 54 // Configure a field trial to collect divs with attribute foo. |
| 55 std::unique_ptr<base::test::ScopedFeatureList> feature_list = |
| 56 SetupTagAndAttributeFeature(); |
22 std::unique_ptr<safe_browsing::ThreatDOMDetails> details( | 57 std::unique_ptr<safe_browsing::ThreatDOMDetails> details( |
23 safe_browsing::ThreatDOMDetails::Create(view_->GetMainRenderFrame())); | 58 safe_browsing::ThreatDOMDetails::Create(view_->GetMainRenderFrame())); |
24 // Lower kMaxNodes for the test. Loading 500 subframes in a | 59 // Lower kMaxNodes for the test. Loading 500 subframes in a |
25 // debug build takes a while. | 60 // debug build takes a while. |
26 details->kMaxNodes = 50; | 61 details->kMaxNodes = 50; |
27 | 62 |
28 const char urlprefix[] = "data:text/html;charset=utf-8,"; | 63 const char urlprefix[] = "data:text/html;charset=utf-8,"; |
29 | 64 |
30 { | 65 { |
31 // A page with an internal script | 66 // A page with an internal script |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 EXPECT_TRUE(param.child_node_ids.empty()); | 106 EXPECT_TRUE(param.child_node_ids.empty()); |
72 | 107 |
73 param = params[2]; | 108 param = params[2]; |
74 EXPECT_EQ(url, param.url); | 109 EXPECT_EQ(url, param.url); |
75 EXPECT_EQ(0, param.node_id); | 110 EXPECT_EQ(0, param.node_id); |
76 EXPECT_EQ(0, param.parent_node_id); | 111 EXPECT_EQ(0, param.parent_node_id); |
77 EXPECT_TRUE(param.child_node_ids.empty()); | 112 EXPECT_TRUE(param.child_node_ids.empty()); |
78 } | 113 } |
79 | 114 |
80 { | 115 { |
81 // A page with an iframe which in turn contains an iframe. | 116 // A page with some divs containing an iframe which itself contains an |
| 117 // iframe. Tag "img foo" exists to ensure we honour both the tag name and |
| 118 // the attribute name when deciding which elements to collect. |
82 // html | 119 // html |
83 // \ iframe1 | 120 // \ div foo |
84 // \ iframe2 | 121 // \ img foo, div bar |
| 122 // \ div baz, iframe1 |
| 123 // \ iframe2 |
85 // Since ThreatDOMDetails is a RenderFrameObserver, it will only | 124 // Since ThreatDOMDetails is a RenderFrameObserver, it will only |
86 // extract resources from the frame it assigned to (in this case, | 125 // extract resources from the frame it assigned to (in this case, |
87 // the main frame). Extracting resources from all frames within a | 126 // the main frame). Extracting resources from all frames within a |
88 // page is covered in SafeBrowsingBlockingPageBrowserTest. | 127 // page is covered in SafeBrowsingBlockingPageBrowserTest. |
89 // In this example, ExtractResources() will still touch iframe1 | 128 // In this example, ExtractResources() will still touch iframe1 |
90 // since it is the direct child of the main frame, but it would not | 129 // since it is the direct child of the main frame, but it would not |
91 // go inside of iframe1. | 130 // go inside of iframe1. |
| 131 // We configure the test to collect divs with attribute foo and baz, but not |
| 132 // divs with attribute bar. So div foo will be collected and contain iframe1 |
| 133 // and div baz as children. |
92 std::string iframe2_html = "<html><body>iframe2</body></html>"; | 134 std::string iframe2_html = "<html><body>iframe2</body></html>"; |
93 GURL iframe2_url(urlprefix + iframe2_html); | 135 GURL iframe2_url(urlprefix + iframe2_html); |
94 std::string iframe1_html = "<iframe src=\"" + | 136 std::string iframe1_html = "<iframe src=\"" + |
95 net::EscapeForHTML(iframe2_url.spec()) + | 137 net::EscapeForHTML(iframe2_url.spec()) + |
96 "\"></iframe>"; | 138 "\"></iframe>"; |
97 GURL iframe1_url(urlprefix + iframe1_html); | 139 GURL iframe1_url(urlprefix + iframe1_html); |
98 std::string html = "<html><head><iframe src=\"" + | 140 std::string html = |
99 net::EscapeForHTML(iframe1_url.spec()) + | 141 "<html><head><div foo=1><img foo=1><div bar=1><div baz=1></div>" |
100 "\"></iframe></head></html>"; | 142 "<iframe src=\"" + |
| 143 net::EscapeForHTML(iframe1_url.spec()) + |
| 144 "\"></iframe></div></div></head></html>"; |
101 GURL url(urlprefix + html); | 145 GURL url(urlprefix + html); |
102 | 146 |
103 LoadHTML(html.c_str()); | 147 LoadHTML(html.c_str()); |
104 std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node> params; | 148 std::vector<SafeBrowsingHostMsg_ThreatDOMDetails_Node> params; |
105 details->ExtractResources(¶ms); | 149 details->ExtractResources(¶ms); |
106 ASSERT_EQ(2u, params.size()); | 150 ASSERT_EQ(4u, params.size()); |
107 | 151 |
108 auto& param = params[0]; | 152 auto& param = params[0]; |
| 153 EXPECT_TRUE(param.url.is_empty()); |
| 154 EXPECT_EQ(url, param.parent); |
| 155 EXPECT_EQ("DIV", param.tag_name); |
| 156 // The children field contains URLs, but this mapping is not currently |
| 157 // maintained among the interior nodes. The summary node is the parent of |
| 158 // all elements in the frame. |
| 159 EXPECT_TRUE(param.children.empty()); |
| 160 EXPECT_EQ(1, param.node_id); |
| 161 EXPECT_EQ(0, param.parent_node_id); |
| 162 EXPECT_THAT(param.child_node_ids, ElementsAre(2, 3)); |
| 163 |
| 164 param = params[1]; |
| 165 EXPECT_TRUE(param.url.is_empty()); |
| 166 EXPECT_EQ(url, param.parent); |
| 167 EXPECT_EQ("DIV", param.tag_name); |
| 168 EXPECT_TRUE(param.children.empty()); |
| 169 EXPECT_EQ(2, param.node_id); |
| 170 EXPECT_EQ(1, param.parent_node_id); |
| 171 EXPECT_TRUE(param.child_node_ids.empty()); |
| 172 |
| 173 param = params[2]; |
109 EXPECT_EQ(iframe1_url, param.url); | 174 EXPECT_EQ(iframe1_url, param.url); |
110 EXPECT_EQ(url, param.parent); | 175 EXPECT_EQ(url, param.parent); |
111 EXPECT_EQ("IFRAME", param.tag_name); | 176 EXPECT_EQ("IFRAME", param.tag_name); |
112 EXPECT_EQ(0u, param.children.size()); | 177 EXPECT_TRUE(param.children.empty()); |
113 EXPECT_EQ(1, param.node_id); | 178 EXPECT_EQ(3, param.node_id); |
114 EXPECT_EQ(0, param.parent_node_id); | 179 EXPECT_EQ(1, param.parent_node_id); |
115 EXPECT_TRUE(param.child_node_ids.empty()); | 180 EXPECT_TRUE(param.child_node_ids.empty()); |
116 | 181 |
117 param = params[1]; | 182 param = params[3]; |
118 EXPECT_EQ(url, param.url); | 183 EXPECT_EQ(url, param.url); |
119 EXPECT_EQ(GURL(), param.parent); | 184 EXPECT_EQ(GURL(), param.parent); |
120 EXPECT_EQ(1u, param.children.size()); | 185 EXPECT_THAT(param.children, ElementsAre(iframe1_url)); |
121 EXPECT_EQ(0, param.node_id); | 186 EXPECT_EQ(0, param.node_id); |
122 EXPECT_EQ(0, param.parent_node_id); | 187 EXPECT_EQ(0, param.parent_node_id); |
123 EXPECT_TRUE(param.child_node_ids.empty()); | 188 EXPECT_TRUE(param.child_node_ids.empty()); |
124 } | 189 } |
125 | 190 |
126 { | 191 { |
127 // Test >50 subframes. | 192 // Test >50 subframes. |
128 std::string html; | 193 std::string html; |
129 for (int i = 0; i < 55; ++i) { | 194 for (int i = 0; i < 55; ++i) { |
130 // The iframe contents is just a number. | 195 // The iframe contents is just a number. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 // The element nodes should all have node IDs. | 233 // The element nodes should all have node IDs. |
169 for (size_t i = 0; i < params.size() - 1; ++i) { | 234 for (size_t i = 0; i < params.size() - 1; ++i) { |
170 auto& param = params[i]; | 235 auto& param = params[i]; |
171 const int expected_id = i + 1; | 236 const int expected_id = i + 1; |
172 EXPECT_EQ(expected_id, param.node_id); | 237 EXPECT_EQ(expected_id, param.node_id); |
173 EXPECT_EQ(0, param.parent_node_id); | 238 EXPECT_EQ(0, param.parent_node_id); |
174 EXPECT_TRUE(param.child_node_ids.empty()); | 239 EXPECT_TRUE(param.child_node_ids.empty()); |
175 } | 240 } |
176 } | 241 } |
177 } | 242 } |
OLD | NEW |