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

Side by Side Diff: Source/WebCore/loader/FrameLoader.cpp

Issue 9963061: Merge 112184 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1025/
Patch Set: Created 8 years, 8 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
« no previous file with comments | « Source/WebCore/loader/FrameLoader.h ('k') | Source/WebCore/loader/NavigationScheduler.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed. 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv ed.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/) 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t orchmobile.com/)
5 * Copyright (C) 2008 Alp Toker <alp@atoker.com> 5 * Copyright (C) 2008 Alp Toker <alp@atoker.com>
6 * Copyright (C) Research In Motion Limited 2009. All rights reserved. 6 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com> 7 * Copyright (C) 2011 Kris Jordan <krisjordan@gmail.com>
8 * Copyright (C) 2011 Google Inc. All rights reserved. 8 * Copyright (C) 2011 Google Inc. All rights reserved.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 m_suppressOpenerInNewFrame = false; 286 m_suppressOpenerInNewFrame = false;
287 } 287 }
288 288
289 void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission) 289 void FrameLoader::submitForm(PassRefPtr<FormSubmission> submission)
290 { 290 {
291 ASSERT(submission->method() == FormSubmission::PostMethod || submission->met hod() == FormSubmission::GetMethod); 291 ASSERT(submission->method() == FormSubmission::PostMethod || submission->met hod() == FormSubmission::GetMethod);
292 292
293 // FIXME: Find a good spot for these. 293 // FIXME: Find a good spot for these.
294 ASSERT(submission->data()); 294 ASSERT(submission->data());
295 ASSERT(submission->state()); 295 ASSERT(submission->state());
296 ASSERT(submission->state()->sourceFrame() == m_frame); 296 ASSERT(!submission->state()->sourceDocument()->frame() || submission->state( )->sourceDocument()->frame() == m_frame);
297 297
298 if (!m_frame->page()) 298 if (!m_frame->page())
299 return; 299 return;
300 300
301 if (submission->action().isEmpty()) 301 if (submission->action().isEmpty())
302 return; 302 return;
303 303
304 if (isDocumentSandboxed(m_frame, SandboxForms)) 304 if (isDocumentSandboxed(m_frame, SandboxForms))
305 return; 305 return;
306 306
307 if (protocolIsJavaScript(submission->action())) { 307 if (protocolIsJavaScript(submission->action())) {
308 m_isExecutingJavaScriptFormAction = true; 308 m_isExecutingJavaScriptFormAction = true;
309 m_frame->script()->executeIfJavaScriptURL(submission->action(), DoNotRep laceDocumentIfJavaScriptURL); 309 m_frame->script()->executeIfJavaScriptURL(submission->action(), DoNotRep laceDocumentIfJavaScriptURL);
310 m_isExecutingJavaScriptFormAction = false; 310 m_isExecutingJavaScriptFormAction = false;
311 return; 311 return;
312 } 312 }
313 313
314 Frame* targetFrame = m_frame->tree()->find(submission->target()); 314 Frame* targetFrame = m_frame->tree()->find(submission->target());
315 if (!shouldAllowNavigation(targetFrame)) 315 if (!submission->state()->sourceDocument()->canNavigate(targetFrame))
316 return; 316 return;
317 if (!targetFrame) { 317 if (!targetFrame) {
318 if (!DOMWindow::allowPopUp(m_frame) && !ScriptController::processingUser Gesture()) 318 if (!DOMWindow::allowPopUp(m_frame) && !ScriptController::processingUser Gesture())
319 return; 319 return;
320 320
321 targetFrame = m_frame; 321 targetFrame = m_frame;
322 } else 322 } else
323 submission->clearTarget(); 323 submission->clearTarget();
324 324
325 if (!targetFrame->page()) 325 if (!targetFrame->page())
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 else 1163 else
1164 loadType = FrameLoadTypeStandard; 1164 loadType = FrameLoadTypeStandard;
1165 1165
1166 if (request.resourceRequest().httpMethod() == "POST") 1166 if (request.resourceRequest().httpMethod() == "POST")
1167 loadPostRequest(request.resourceRequest(), referrer, request.frameName() , lockHistory, loadType, event, formState.get()); 1167 loadPostRequest(request.resourceRequest(), referrer, request.frameName() , lockHistory, loadType, event, formState.get());
1168 else 1168 else
1169 loadURL(request.resourceRequest().url(), referrer, request.frameName(), lockHistory, loadType, event, formState.get()); 1169 loadURL(request.resourceRequest().url(), referrer, request.frameName(), lockHistory, loadType, event, formState.get());
1170 1170
1171 // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual 1171 // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual
1172 // load if frame names have changed. 1172 // load if frame names have changed.
1173 Frame* sourceFrame = formState ? formState->sourceFrame() : m_frame; 1173 Frame* sourceFrame = formState ? formState->sourceDocument()->frame() : m_fr ame;
1174 if (!sourceFrame)
1175 sourceFrame = m_frame;
1174 Frame* targetFrame = sourceFrame->loader()->findFrameForNavigation(request.f rameName()); 1176 Frame* targetFrame = sourceFrame->loader()->findFrameForNavigation(request.f rameName());
1175 if (targetFrame && targetFrame != sourceFrame) { 1177 if (targetFrame && targetFrame != sourceFrame) {
1176 if (Page* page = targetFrame->page()) 1178 if (Page* page = targetFrame->page())
1177 page->chrome()->focus(); 1179 page->chrome()->focus();
1178 } 1180 }
1179 } 1181 }
1180 1182
1181 void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri ng& frameName, bool lockHistory, FrameLoadType newLoadType, 1183 void FrameLoader::loadURL(const KURL& newURL, const String& referrer, const Stri ng& frameName, bool lockHistory, FrameLoadType newLoadType,
1182 PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState) 1184 PassRefPtr<Event> event, PassRefPtr<FormState> prpFormState)
1183 { 1185 {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 1491
1490 // If we're about to re-post, set up action so the application can warn the user. 1492 // If we're about to re-post, set up action so the application can warn the user.
1491 if (request.httpMethod() == "POST") 1493 if (request.httpMethod() == "POST")
1492 loader->setTriggeringAction(NavigationAction(request, NavigationTypeForm Resubmitted)); 1494 loader->setTriggeringAction(NavigationAction(request, NavigationTypeForm Resubmitted));
1493 1495
1494 loader->setOverrideEncoding(m_documentLoader->overrideEncoding()); 1496 loader->setOverrideEncoding(m_documentLoader->overrideEncoding());
1495 1497
1496 loadWithDocumentLoader(loader.get(), endToEndReload ? FrameLoadTypeReloadFro mOrigin : FrameLoadTypeReload, 0); 1498 loadWithDocumentLoader(loader.get(), endToEndReload ? FrameLoadTypeReloadFro mOrigin : FrameLoadTypeReload, 0);
1497 } 1499 }
1498 1500
1499 static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame)
1500 {
1501 // targetFrame can be NULL when we're trying to navigate a top-level frame
1502 // that has a NULL opener.
1503 if (!targetFrame)
1504 return false;
1505
1506 const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal();
1507 for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ance storFrame->tree()->parent()) {
1508 Document* ancestorDocument = ancestorFrame->document();
1509 if (!ancestorDocument)
1510 return true;
1511
1512 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit yOrigin();
1513 if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin))
1514 return true;
1515
1516 // Allow file URL descendant navigation even when allowFileAccessFromFil eURLs is false.
1517 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal())
1518 return true;
1519 }
1520
1521 return false;
1522 }
1523
1524 bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const
1525 {
1526 // The navigation change is safe if the active frame is:
1527 // - in the same security origin as the target or one of the target's
1528 // ancestors.
1529 //
1530 // Or the target frame is:
1531 // - a top-level frame in the frame hierarchy and the active frame can
1532 // navigate the target frame's opener per above or it is the opener of
1533 // the target frame.
1534
1535 if (!targetFrame)
1536 return true;
1537
1538 // Performance optimization.
1539 if (m_frame == targetFrame)
1540 return true;
1541
1542 // Let a frame navigate the top-level window that contains it. This is
1543 // important to allow because it lets a site "frame-bust" (escape from a
1544 // frame created by another web site).
1545 if (!isDocumentSandboxed(m_frame, SandboxTopNavigation) && targetFrame == m_ frame->tree()->top())
1546 return true;
1547
1548 // A sandboxed frame can only navigate itself and its descendants.
1549 if (isDocumentSandboxed(m_frame, SandboxNavigation) && !targetFrame->tree()- >isDescendantOf(m_frame))
1550 return false;
1551
1552 // Let a frame navigate its opener if the opener is a top-level window.
1553 if (!targetFrame->tree()->parent() && m_frame->loader()->opener() == targetF rame)
1554 return true;
1555
1556 Document* activeDocument = m_frame->document();
1557 ASSERT(activeDocument);
1558 const SecurityOrigin* activeSecurityOrigin = activeDocument->securityOrigin( );
1559
1560 // For top-level windows, check the opener.
1561 if (!targetFrame->tree()->parent() && canAccessAncestor(activeSecurityOrigin , targetFrame->loader()->opener()))
1562 return true;
1563
1564 // In general, check the frame's ancestors.
1565 if (canAccessAncestor(activeSecurityOrigin, targetFrame))
1566 return true;
1567
1568 Document* targetDocument = targetFrame->document();
1569 // FIXME: this error message should contain more specifics of why the naviga tion change is not allowed.
1570 String message = "Unsafe JavaScript attempt to initiate a navigation change for frame with URL " +
1571 targetDocument->url().string() + " from frame with URL " + activeDocument->url().string() + ".\n";
1572
1573 // FIXME: should we print to the console of the activeFrame as well?
1574 targetFrame->domWindow()->printErrorMessage(message);
1575
1576 return false;
1577 }
1578
1579 void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem Policy) 1501 void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem Policy)
1580 { 1502 {
1581 ASSERT(!m_frame->document() || !m_frame->document()->inPageCache()); 1503 ASSERT(!m_frame->document() || !m_frame->document()->inPageCache());
1582 if (m_pageDismissalEventBeingDispatched != NoDismissal) 1504 if (m_pageDismissalEventBeingDispatched != NoDismissal)
1583 return; 1505 return;
1584 1506
1585 // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this. 1507 // If this method is called from within this method, infinite recursion can occur (3442218). Avoid this.
1586 if (m_inStopAllLoaders) 1508 if (m_inStopAllLoaders)
1587 return; 1509 return;
1588 1510
(...skipping 1458 matching lines...) Expand 10 before | Expand all | Expand 10 after
3047 2969
3048 if (!m_didPerformFirstNavigation && page->backForward()->currentItem() && !p age->backForward()->backItem() && !page->backForward()->forwardItem()) { 2970 if (!m_didPerformFirstNavigation && page->backForward()->currentItem() && !p age->backForward()->backItem() && !page->backForward()->forwardItem()) {
3049 m_didPerformFirstNavigation = true; 2971 m_didPerformFirstNavigation = true;
3050 m_client->didPerformFirstNavigation(); 2972 m_client->didPerformFirstNavigation();
3051 } 2973 }
3052 } 2974 }
3053 2975
3054 Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) 2976 Frame* FrameLoader::findFrameForNavigation(const AtomicString& name)
3055 { 2977 {
3056 Frame* frame = m_frame->tree()->find(name); 2978 Frame* frame = m_frame->tree()->find(name);
3057 if (!shouldAllowNavigation(frame)) 2979 // FIXME: We calling canNavigate on the Document that's requesting the
2980 // navigation, not based on the document that happens to be displayed in
2981 // this Frame.
2982 if (!m_frame->document()->canNavigate(frame))
3058 return 0; 2983 return 0;
3059 return frame; 2984 return frame;
3060 } 2985 }
3061 2986
3062 void FrameLoader::loadSameDocumentItem(HistoryItem* item) 2987 void FrameLoader::loadSameDocumentItem(HistoryItem* item)
3063 { 2988 {
3064 ASSERT(item->documentSequenceNumber() == history()->currentItem()->documentS equenceNumber()); 2989 ASSERT(item->documentSequenceNumber() == history()->currentItem()->documentS equenceNumber());
3065 2990
3066 // Save user view state to the current history item here since we don't do a normal load. 2991 // Save user view state to the current history item here since we don't do a normal load.
3067 // FIXME: Does form state need to be saved here too? 2992 // FIXME: Does form state need to be saved here too?
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
3310 { 3235 {
3311 return true; 3236 return true;
3312 } 3237 }
3313 3238
3314 Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadReque st& request, const WindowFeatures& features, bool& created) 3239 Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadReque st& request, const WindowFeatures& features, bool& created)
3315 { 3240 {
3316 ASSERT(!features.dialog || request.frameName().isEmpty()); 3241 ASSERT(!features.dialog || request.frameName().isEmpty());
3317 3242
3318 if (!request.frameName().isEmpty() && request.frameName() != "_blank") { 3243 if (!request.frameName().isEmpty() && request.frameName() != "_blank") {
3319 Frame* frame = lookupFrame->tree()->find(request.frameName()); 3244 Frame* frame = lookupFrame->tree()->find(request.frameName());
3320 if (frame && openerFrame->loader()->shouldAllowNavigation(frame)) { 3245 if (frame && openerFrame->document()->canNavigate(frame)) {
3321 if (Page* page = frame->page()) 3246 if (Page* page = frame->page())
3322 page->chrome()->focus(); 3247 page->chrome()->focus();
3323 created = false; 3248 created = false;
3324 return frame; 3249 return frame;
3325 } 3250 }
3326 } 3251 }
3327 3252
3328 // Sandboxed frames cannot open new auxiliary browsing contexts. 3253 // Sandboxed frames cannot open new auxiliary browsing contexts.
3329 if (isDocumentSandboxed(openerFrame, SandboxPopups)) 3254 if (isDocumentSandboxed(openerFrame, SandboxPopups))
3330 return 0; 3255 return 0;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 windowRect.setHeight(features.height + (windowRect.height() - pageSize.h eight())); 3297 windowRect.setHeight(features.height + (windowRect.height() - pageSize.h eight()));
3373 page->chrome()->setWindowRect(windowRect); 3298 page->chrome()->setWindowRect(windowRect);
3374 3299
3375 page->chrome()->show(); 3300 page->chrome()->show();
3376 3301
3377 created = true; 3302 created = true;
3378 return frame; 3303 return frame;
3379 } 3304 }
3380 3305
3381 } // namespace WebCore 3306 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/WebCore/loader/FrameLoader.h ('k') | Source/WebCore/loader/NavigationScheduler.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698