Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: chrome/browser/extensions/api/web_navigation/frame_navigation_state.cc

Issue 380213003: Harden WebNavigation API against invalid navigation callbacks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/browser/extensions/api/web_navigation/frame_navigation_state.h" 5 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/user_metrics.h"
8 #include "chrome/common/url_constants.h" 9 #include "chrome/common/url_constants.h"
9 #include "extensions/common/constants.h" 10 #include "extensions/common/constants.h"
10 11
11 namespace extensions { 12 namespace extensions {
12 13
13 namespace { 14 namespace {
14 15
15 // URL schemes for which we'll send events. 16 // URL schemes for which we'll send events.
16 const char* kValidSchemes[] = { 17 const char* kValidSchemes[] = {
17 content::kChromeUIScheme, 18 content::kChromeUIScheme,
18 url::kHttpScheme, 19 url::kHttpScheme,
19 url::kHttpsScheme, 20 url::kHttpsScheme,
20 url::kFileScheme, 21 url::kFileScheme,
21 url::kFtpScheme, 22 url::kFtpScheme,
22 url::kJavaScriptScheme, 23 url::kJavaScriptScheme,
23 url::kDataScheme, 24 url::kDataScheme,
24 url::kFileSystemScheme, 25 url::kFileSystemScheme,
25 }; 26 };
26 27
28 void ReportInvalidFrameID() {
29 base::RecordAction(
30 base::UserMetricsAction("Extensions.WebNavigation.InvalidFrameID"));
31 NOTREACHED();
32 }
33
27 } // namespace 34 } // namespace
28 35
29 FrameNavigationState::FrameID::FrameID() 36 FrameNavigationState::FrameID::FrameID()
30 : frame_num(-1), 37 : frame_num(-1),
31 render_view_host(NULL) { 38 render_view_host(NULL) {
32 } 39 }
33 40
34 FrameNavigationState::FrameID::FrameID( 41 FrameNavigationState::FrameID::FrameID(
35 int64 frame_num, 42 int64 frame_num,
36 content::RenderViewHost* render_view_host) 43 content::RenderViewHost* render_view_host)
(...skipping 26 matching lines...) Expand all
63 70
64 FrameNavigationState::FrameNavigationState() {} 71 FrameNavigationState::FrameNavigationState() {}
65 72
66 FrameNavigationState::~FrameNavigationState() {} 73 FrameNavigationState::~FrameNavigationState() {}
67 74
68 bool FrameNavigationState::CanSendEvents(FrameID frame_id) const { 75 bool FrameNavigationState::CanSendEvents(FrameID frame_id) const {
69 FrameIdToStateMap::const_iterator frame_state = 76 FrameIdToStateMap::const_iterator frame_state =
70 frame_state_map_.find(frame_id); 77 frame_state_map_.find(frame_id);
71 if (frame_state == frame_state_map_.end() || 78 if (frame_state == frame_state_map_.end() ||
72 frame_state->second.error_occurred) { 79 frame_state->second.error_occurred) {
80 if (frame_state == frame_state_map_.end())
81 ReportInvalidFrameID();
73 return false; 82 return false;
74 } 83 }
75 return IsValidUrl(frame_state->second.url); 84 return IsValidUrl(frame_state->second.url);
76 } 85 }
77 86
78 bool FrameNavigationState::IsValidUrl(const GURL& url) const { 87 bool FrameNavigationState::IsValidUrl(const GURL& url) const {
79 for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) { 88 for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) {
80 if (url.scheme() == kValidSchemes[i]) 89 if (url.scheme() == kValidSchemes[i])
81 return true; 90 return true;
82 } 91 }
(...skipping 26 matching lines...) Expand all
109 } else { 118 } else {
110 DCHECK_EQ(-1, parent_frame_id.frame_num); 119 DCHECK_EQ(-1, parent_frame_id.frame_num);
111 frame_state.parent_frame_num = -1; 120 frame_state.parent_frame_num = -1;
112 } 121 }
113 frame_ids_.insert(frame_id); 122 frame_ids_.insert(frame_id);
114 } 123 }
115 124
116 void FrameNavigationState::FrameDetached(FrameID frame_id) { 125 void FrameNavigationState::FrameDetached(FrameID frame_id) {
117 FrameIdToStateMap::const_iterator frame_state = 126 FrameIdToStateMap::const_iterator frame_state =
118 frame_state_map_.find(frame_id); 127 frame_state_map_.find(frame_id);
119 if (frame_state == frame_state_map_.end()) 128 if (frame_state == frame_state_map_.end()) {
129 ReportInvalidFrameID();
120 return; 130 return;
131 }
121 if (frame_id == main_frame_id_) 132 if (frame_id == main_frame_id_)
122 main_frame_id_ = FrameID(); 133 main_frame_id_ = FrameID();
123 frame_state_map_.erase(frame_id); 134 frame_state_map_.erase(frame_id);
124 frame_ids_.erase(frame_id); 135 frame_ids_.erase(frame_id);
125 #ifndef NDEBUG 136 #ifndef NDEBUG
126 // Check that the deleted frame was not the parent of any other frame. WebKit 137 // Check that the deleted frame was not the parent of any other frame. WebKit
127 // should always detach frames starting with the children. 138 // should always detach frames starting with the children.
128 for (FrameIdToStateMap::const_iterator frame = frame_state_map_.begin(); 139 for (FrameIdToStateMap::const_iterator frame = frame_state_map_.begin();
129 frame != frame_state_map_.end(); ++frame) { 140 frame != frame_state_map_.end(); ++frame) {
130 if (frame->first.render_view_host != frame_id.render_view_host) 141 if (frame->first.render_view_host != frame_id.render_view_host)
(...skipping 19 matching lines...) Expand all
150 if (frame_id == main_frame_id_) 161 if (frame_id == main_frame_id_)
151 main_frame_id_ = FrameID(); 162 main_frame_id_ = FrameID();
152 frame_state_map_.erase(frame_id); 163 frame_state_map_.erase(frame_id);
153 frame_ids_.erase(frame_id); 164 frame_ids_.erase(frame_id);
154 } 165 }
155 } 166 }
156 167
157 void FrameNavigationState::UpdateFrame(FrameID frame_id, const GURL& url) { 168 void FrameNavigationState::UpdateFrame(FrameID frame_id, const GURL& url) {
158 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id); 169 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
159 if (frame_state == frame_state_map_.end()) { 170 if (frame_state == frame_state_map_.end()) {
160 NOTREACHED(); 171 ReportInvalidFrameID();
161 return; 172 return;
162 } 173 }
163 frame_state->second.url = url; 174 frame_state->second.url = url;
164 } 175 }
165 176
166 bool FrameNavigationState::IsValidFrame(FrameID frame_id) const { 177 bool FrameNavigationState::IsValidFrame(FrameID frame_id) const {
167 FrameIdToStateMap::const_iterator frame_state = 178 FrameIdToStateMap::const_iterator frame_state =
168 frame_state_map_.find(frame_id); 179 frame_state_map_.find(frame_id);
169 return (frame_state != frame_state_map_.end()); 180 return (frame_state != frame_state_map_.end());
170 } 181 }
171 182
172 GURL FrameNavigationState::GetUrl(FrameID frame_id) const { 183 GURL FrameNavigationState::GetUrl(FrameID frame_id) const {
173 FrameIdToStateMap::const_iterator frame_state = 184 FrameIdToStateMap::const_iterator frame_state =
174 frame_state_map_.find(frame_id); 185 frame_state_map_.find(frame_id);
175 if (frame_state == frame_state_map_.end()) { 186 if (frame_state == frame_state_map_.end()) {
176 NOTREACHED(); 187 ReportInvalidFrameID();
177 return GURL(); 188 return GURL();
178 } 189 }
179 if (frame_state->second.is_iframe_srcdoc) 190 if (frame_state->second.is_iframe_srcdoc)
180 return GURL(content::kAboutSrcDocURL); 191 return GURL(content::kAboutSrcDocURL);
181 return frame_state->second.url; 192 return frame_state->second.url;
182 } 193 }
183 194
184 bool FrameNavigationState::IsMainFrame(FrameID frame_id) const { 195 bool FrameNavigationState::IsMainFrame(FrameID frame_id) const {
185 FrameIdToStateMap::const_iterator frame_state = 196 FrameIdToStateMap::const_iterator frame_state =
186 frame_state_map_.find(frame_id); 197 frame_state_map_.find(frame_id);
198 if (frame_state == frame_state_map_.end())
199 ReportInvalidFrameID();
187 return (frame_state != frame_state_map_.end() && 200 return (frame_state != frame_state_map_.end() &&
188 frame_state->second.is_main_frame); 201 frame_state->second.is_main_frame);
189 } 202 }
190 203
191 FrameNavigationState::FrameID FrameNavigationState::GetMainFrameID() const { 204 FrameNavigationState::FrameID FrameNavigationState::GetMainFrameID() const {
192 return main_frame_id_; 205 return main_frame_id_;
193 } 206 }
194 207
195 FrameNavigationState::FrameID FrameNavigationState::GetParentFrameID( 208 FrameNavigationState::FrameID FrameNavigationState::GetParentFrameID(
196 FrameID frame_id) const { 209 FrameID frame_id) const {
197 FrameIdToStateMap::const_iterator frame_state = 210 FrameIdToStateMap::const_iterator frame_state =
198 frame_state_map_.find(frame_id); 211 frame_state_map_.find(frame_id);
199 if (frame_state == frame_state_map_.end()) { 212 if (frame_state == frame_state_map_.end()) {
200 NOTREACHED(); 213 ReportInvalidFrameID();
201 return FrameID(); 214 return FrameID();
202 } 215 }
203 return FrameID(frame_state->second.parent_frame_num, 216 return FrameID(frame_state->second.parent_frame_num,
204 frame_id.render_view_host); 217 frame_id.render_view_host);
205 } 218 }
206 219
207 void FrameNavigationState::SetErrorOccurredInFrame(FrameID frame_id) { 220 void FrameNavigationState::SetErrorOccurredInFrame(FrameID frame_id) {
208 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); 221 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
209 frame_state_map_[frame_id].error_occurred = true; 222 if (frame_state == frame_state_map_.end())
223 ReportInvalidFrameID();
224 else
225 frame_state->second.error_occurred = true;
210 } 226 }
211 227
212 bool FrameNavigationState::GetErrorOccurredInFrame(FrameID frame_id) const { 228 bool FrameNavigationState::GetErrorOccurredInFrame(FrameID frame_id) const {
213 FrameIdToStateMap::const_iterator frame_state = 229 FrameIdToStateMap::const_iterator frame_state =
214 frame_state_map_.find(frame_id); 230 frame_state_map_.find(frame_id);
231 if (frame_state == frame_state_map_.end())
232 ReportInvalidFrameID();
215 return (frame_state == frame_state_map_.end() || 233 return (frame_state == frame_state_map_.end() ||
216 frame_state->second.error_occurred); 234 frame_state->second.error_occurred);
217 } 235 }
218 236
219 void FrameNavigationState::SetNavigationCompleted(FrameID frame_id) { 237 void FrameNavigationState::SetNavigationCompleted(FrameID frame_id) {
220 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); 238 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
221 frame_state_map_[frame_id].is_navigating = false; 239 if (frame_state == frame_state_map_.end())
240 ReportInvalidFrameID();
241 else
242 frame_state->second.is_navigating = false;
222 } 243 }
223 244
224 bool FrameNavigationState::GetNavigationCompleted(FrameID frame_id) const { 245 bool FrameNavigationState::GetNavigationCompleted(FrameID frame_id) const {
225 FrameIdToStateMap::const_iterator frame_state = 246 FrameIdToStateMap::const_iterator frame_state =
226 frame_state_map_.find(frame_id); 247 frame_state_map_.find(frame_id);
248 if (frame_state == frame_state_map_.end())
249 ReportInvalidFrameID();
227 return (frame_state == frame_state_map_.end() || 250 return (frame_state == frame_state_map_.end() ||
228 !frame_state->second.is_navigating); 251 !frame_state->second.is_navigating);
229 } 252 }
230 253
231 void FrameNavigationState::SetParsingFinished(FrameID frame_id) { 254 void FrameNavigationState::SetParsingFinished(FrameID frame_id) {
232 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); 255 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
233 frame_state_map_[frame_id].is_parsing = false; 256 if (frame_state == frame_state_map_.end())
257 ReportInvalidFrameID();
258 else
259 frame_state->second.is_parsing = false;
234 } 260 }
235 261
236 bool FrameNavigationState::GetParsingFinished(FrameID frame_id) const { 262 bool FrameNavigationState::GetParsingFinished(FrameID frame_id) const {
237 FrameIdToStateMap::const_iterator frame_state = 263 FrameIdToStateMap::const_iterator frame_state =
238 frame_state_map_.find(frame_id); 264 frame_state_map_.find(frame_id);
265 if (frame_state == frame_state_map_.end())
266 ReportInvalidFrameID();
239 return (frame_state == frame_state_map_.end() || 267 return (frame_state == frame_state_map_.end() ||
240 !frame_state->second.is_parsing); 268 !frame_state->second.is_parsing);
241 } 269 }
242 270
243 void FrameNavigationState::SetNavigationCommitted(FrameID frame_id) { 271 void FrameNavigationState::SetNavigationCommitted(FrameID frame_id) {
244 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); 272 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
245 frame_state_map_[frame_id].is_committed = true; 273 if (frame_state == frame_state_map_.end()) {
246 if (frame_state_map_[frame_id].is_main_frame) 274 ReportInvalidFrameID();
247 main_frame_id_ = frame_id; 275 } else {
276 frame_state->second.is_committed = true;
277 if (frame_state->second.is_main_frame)
278 main_frame_id_ = frame_id;
279 }
248 } 280 }
249 281
250 bool FrameNavigationState::GetNavigationCommitted(FrameID frame_id) const { 282 bool FrameNavigationState::GetNavigationCommitted(FrameID frame_id) const {
251 FrameIdToStateMap::const_iterator frame_state = 283 FrameIdToStateMap::const_iterator frame_state =
252 frame_state_map_.find(frame_id); 284 frame_state_map_.find(frame_id);
285 if (frame_state == frame_state_map_.end())
286 ReportInvalidFrameID();
253 return (frame_state != frame_state_map_.end() && 287 return (frame_state != frame_state_map_.end() &&
254 frame_state->second.is_committed); 288 frame_state->second.is_committed);
255 } 289 }
256 290
257 void FrameNavigationState::SetIsServerRedirected(FrameID frame_id) { 291 void FrameNavigationState::SetIsServerRedirected(FrameID frame_id) {
258 DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end()); 292 FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
259 frame_state_map_[frame_id].is_server_redirected = true; 293 if (frame_state == frame_state_map_.end())
294 ReportInvalidFrameID();
295 else
296 frame_state->second.is_server_redirected = true;
260 } 297 }
261 298
262 bool FrameNavigationState::GetIsServerRedirected(FrameID frame_id) const { 299 bool FrameNavigationState::GetIsServerRedirected(FrameID frame_id) const {
263 FrameIdToStateMap::const_iterator frame_state = 300 FrameIdToStateMap::const_iterator frame_state =
264 frame_state_map_.find(frame_id); 301 frame_state_map_.find(frame_id);
302 if (frame_state == frame_state_map_.end())
303 ReportInvalidFrameID();
265 return (frame_state != frame_state_map_.end() && 304 return (frame_state != frame_state_map_.end() &&
266 frame_state->second.is_server_redirected); 305 frame_state->second.is_server_redirected);
267 } 306 }
268 307
269 } // namespace extensions 308 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/extensions/api/web_navigation/web_navigation_api.cc » ('j') | tools/metrics/actions/actions.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698