| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |