OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 */ | 25 */ |
26 | 26 |
27 #include "core/frame/LocalDOMWindow.h" | 27 #include "core/frame/LocalDOMWindow.h" |
28 | 28 |
29 #include "bindings/core/v8/ScriptCallStack.h" | |
30 #include "bindings/core/v8/ScriptController.h" | 29 #include "bindings/core/v8/ScriptController.h" |
| 30 #include "bindings/core/v8/SourceLocation.h" |
31 #include "core/css/CSSComputedStyleDeclaration.h" | 31 #include "core/css/CSSComputedStyleDeclaration.h" |
32 #include "core/css/CSSRuleList.h" | 32 #include "core/css/CSSRuleList.h" |
33 #include "core/css/DOMWindowCSS.h" | 33 #include "core/css/DOMWindowCSS.h" |
34 #include "core/css/MediaQueryList.h" | 34 #include "core/css/MediaQueryList.h" |
35 #include "core/css/MediaQueryMatcher.h" | 35 #include "core/css/MediaQueryMatcher.h" |
36 #include "core/css/StyleMedia.h" | 36 #include "core/css/StyleMedia.h" |
37 #include "core/css/resolver/StyleResolver.h" | 37 #include "core/css/resolver/StyleResolver.h" |
38 #include "core/dom/DOMImplementation.h" | 38 #include "core/dom/DOMImplementation.h" |
39 #include "core/dom/ExecutionContextTask.h" | 39 #include "core/dom/ExecutionContextTask.h" |
40 #include "core/dom/FrameRequestCallback.h" | 40 #include "core/dom/FrameRequestCallback.h" |
(...skipping 28 matching lines...) Expand all Loading... |
69 #include "core/page/CreateWindow.h" | 69 #include "core/page/CreateWindow.h" |
70 #include "core/page/Page.h" | 70 #include "core/page/Page.h" |
71 #include "core/page/WindowFeatures.h" | 71 #include "core/page/WindowFeatures.h" |
72 #include "core/page/scrolling/ScrollingCoordinator.h" | 72 #include "core/page/scrolling/ScrollingCoordinator.h" |
73 #include "platform/EventDispatchForbiddenScope.h" | 73 #include "platform/EventDispatchForbiddenScope.h" |
74 #include "platform/weborigin/SecurityOrigin.h" | 74 #include "platform/weborigin/SecurityOrigin.h" |
75 #include "platform/weborigin/Suborigin.h" | 75 #include "platform/weborigin/Suborigin.h" |
76 #include "public/platform/Platform.h" | 76 #include "public/platform/Platform.h" |
77 #include "public/platform/WebFrameScheduler.h" | 77 #include "public/platform/WebFrameScheduler.h" |
78 #include "public/platform/WebScreenInfo.h" | 78 #include "public/platform/WebScreenInfo.h" |
| 79 #include "wtf/PassOwnPtr.h" |
79 | 80 |
80 namespace blink { | 81 namespace blink { |
81 | 82 |
82 // Rather than simply inheriting LocalFrameLifecycleObserver like most other | 83 // Rather than simply inheriting LocalFrameLifecycleObserver like most other |
83 // classes, LocalDOMWindow hides its LocalFrameLifecycleObserver with | 84 // classes, LocalDOMWindow hides its LocalFrameLifecycleObserver with |
84 // composition. This prevents conflicting overloads between DOMWindow, which | 85 // composition. This prevents conflicting overloads between DOMWindow, which |
85 // has a frame() accessor that returns Frame* for bindings code, and | 86 // has a frame() accessor that returns Frame* for bindings code, and |
86 // LocalFrameLifecycleObserver, which has a frame() accessor that returns a | 87 // LocalFrameLifecycleObserver, which has a frame() accessor that returns a |
87 // LocalFrame*. | 88 // LocalFrame*. |
88 class LocalDOMWindow::WindowFrameObserver final : public GarbageCollected<LocalD
OMWindow::WindowFrameObserver>, public LocalFrameLifecycleObserver { | 89 class LocalDOMWindow::WindowFrameObserver final : public GarbageCollected<LocalD
OMWindow::WindowFrameObserver>, public LocalFrameLifecycleObserver { |
(...skipping 28 matching lines...) Expand all Loading... |
117 , m_window(window) | 118 , m_window(window) |
118 { | 119 { |
119 } | 120 } |
120 | 121 |
121 Member<LocalDOMWindow> m_window; | 122 Member<LocalDOMWindow> m_window; |
122 }; | 123 }; |
123 | 124 |
124 class PostMessageTimer final : public GarbageCollectedFinalized<PostMessageTimer
>, public SuspendableTimer { | 125 class PostMessageTimer final : public GarbageCollectedFinalized<PostMessageTimer
>, public SuspendableTimer { |
125 USING_GARBAGE_COLLECTED_MIXIN(PostMessageTimer); | 126 USING_GARBAGE_COLLECTED_MIXIN(PostMessageTimer); |
126 public: | 127 public: |
127 PostMessageTimer(LocalDOMWindow& window, MessageEvent* event, PassRefPtr<Sec
urityOrigin> targetOrigin, PassRefPtr<ScriptCallStack> stackTrace, UserGestureTo
ken* userGestureToken) | 128 PostMessageTimer(LocalDOMWindow& window, MessageEvent* event, PassRefPtr<Sec
urityOrigin> targetOrigin, PassOwnPtr<SourceLocation> location, UserGestureToken
* userGestureToken) |
128 : SuspendableTimer(window.document()) | 129 : SuspendableTimer(window.document()) |
129 , m_event(event) | 130 , m_event(event) |
130 , m_window(&window) | 131 , m_window(&window) |
131 , m_targetOrigin(targetOrigin) | 132 , m_targetOrigin(targetOrigin) |
132 , m_stackTrace(stackTrace) | 133 , m_location(std::move(location)) |
133 , m_userGestureToken(userGestureToken) | 134 , m_userGestureToken(userGestureToken) |
134 , m_disposalAllowed(true) | 135 , m_disposalAllowed(true) |
135 { | 136 { |
136 InspectorInstrumentation::asyncTaskScheduled(window.document(), "postMes
sage", this); | 137 InspectorInstrumentation::asyncTaskScheduled(window.document(), "postMes
sage", this); |
137 } | 138 } |
138 | 139 |
139 MessageEvent* event() const { return m_event; } | 140 MessageEvent* event() const { return m_event; } |
140 SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } | 141 SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); } |
141 ScriptCallStack* stackTrace() const { return m_stackTrace.get(); } | 142 PassOwnPtr<SourceLocation> takeLocation() { return std::move(m_location); } |
142 UserGestureToken* userGestureToken() const { return m_userGestureToken.get()
; } | 143 UserGestureToken* userGestureToken() const { return m_userGestureToken.get()
; } |
143 void stop() override | 144 void stop() override |
144 { | 145 { |
145 SuspendableTimer::stop(); | 146 SuspendableTimer::stop(); |
146 | 147 |
147 if (m_disposalAllowed) | 148 if (m_disposalAllowed) |
148 dispose(); | 149 dispose(); |
149 } | 150 } |
150 | 151 |
151 // Eager finalization is needed to promptly stop this timer object. | 152 // Eager finalization is needed to promptly stop this timer object. |
(...skipping 22 matching lines...) Expand all Loading... |
174 // Oilpan optimization: unregister as an observer right away. | 175 // Oilpan optimization: unregister as an observer right away. |
175 clearContext(); | 176 clearContext(); |
176 // Will destroy this object, now or after the next GC depending | 177 // Will destroy this object, now or after the next GC depending |
177 // on whether Oilpan is disabled or not. | 178 // on whether Oilpan is disabled or not. |
178 m_window->removePostMessageTimer(this); | 179 m_window->removePostMessageTimer(this); |
179 } | 180 } |
180 | 181 |
181 Member<MessageEvent> m_event; | 182 Member<MessageEvent> m_event; |
182 Member<LocalDOMWindow> m_window; | 183 Member<LocalDOMWindow> m_window; |
183 RefPtr<SecurityOrigin> m_targetOrigin; | 184 RefPtr<SecurityOrigin> m_targetOrigin; |
184 RefPtr<ScriptCallStack> m_stackTrace; | 185 OwnPtr<SourceLocation> m_location; |
185 RefPtr<UserGestureToken> m_userGestureToken; | 186 RefPtr<UserGestureToken> m_userGestureToken; |
186 bool m_disposalAllowed; | 187 bool m_disposalAllowed; |
187 }; | 188 }; |
188 | 189 |
189 static void updateSuddenTerminationStatus(LocalDOMWindow* domWindow, bool addedL
istener, FrameLoaderClient::SuddenTerminationDisablerType disablerType) | 190 static void updateSuddenTerminationStatus(LocalDOMWindow* domWindow, bool addedL
istener, FrameLoaderClient::SuddenTerminationDisablerType disablerType) |
190 { | 191 { |
191 Platform::current()->suddenTerminationChanged(!addedListener); | 192 Platform::current()->suddenTerminationChanged(!addedListener); |
192 if (domWindow->frame() && domWindow->frame()->loader().client()) | 193 if (domWindow->frame() && domWindow->frame()->loader().client()) |
193 domWindow->frame()->loader().client()->suddenTerminationDisablerChanged(
addedListener, disablerType); | 194 domWindow->frame()->loader().client()->suddenTerminationDisablerChanged(
addedListener, disablerType); |
194 } | 195 } |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 if (!m_navigator) | 662 if (!m_navigator) |
662 m_navigator = Navigator::create(frame()); | 663 m_navigator = Navigator::create(frame()); |
663 return m_navigator.get(); | 664 return m_navigator.get(); |
664 } | 665 } |
665 | 666 |
666 void LocalDOMWindow::schedulePostMessage(MessageEvent* event, PassRefPtr<Securit
yOrigin> target, Document* source) | 667 void LocalDOMWindow::schedulePostMessage(MessageEvent* event, PassRefPtr<Securit
yOrigin> target, Document* source) |
667 { | 668 { |
668 // Allowing unbounded amounts of messages to build up for a suspended contex
t | 669 // Allowing unbounded amounts of messages to build up for a suspended contex
t |
669 // is problematic; consider imposing a limit or other restriction if this | 670 // is problematic; consider imposing a limit or other restriction if this |
670 // surfaces often as a problem (see crbug.com/587012). | 671 // surfaces often as a problem (see crbug.com/587012). |
671 | 672 PostMessageTimer* timer = new PostMessageTimer(*this, event, target, SourceL
ocation::capture(source), UserGestureIndicator::currentToken()); |
672 // Capture stack trace only when inspector front-end is loaded as it may be
time consuming. | |
673 RefPtr<ScriptCallStack> stackTrace; | |
674 if (InspectorInstrumentation::consoleAgentEnabled(source)) | |
675 stackTrace = ScriptCallStack::capture(); | |
676 | |
677 // Schedule the message. | |
678 PostMessageTimer* timer = new PostMessageTimer(*this, event, target, stackTr
ace.release(), UserGestureIndicator::currentToken()); | |
679 timer->startOneShot(0, BLINK_FROM_HERE); | 673 timer->startOneShot(0, BLINK_FROM_HERE); |
680 timer->suspendIfNeeded(); | 674 timer->suspendIfNeeded(); |
681 m_postMessageTimers.add(timer); | 675 m_postMessageTimers.add(timer); |
682 } | 676 } |
683 | 677 |
684 void LocalDOMWindow::postMessageTimerFired(PostMessageTimer* timer) | 678 void LocalDOMWindow::postMessageTimerFired(PostMessageTimer* timer) |
685 { | 679 { |
686 if (!isCurrentlyDisplayedInFrame()) | 680 if (!isCurrentlyDisplayedInFrame()) |
687 return; | 681 return; |
688 | 682 |
689 MessageEvent* event = timer->event(); | 683 MessageEvent* event = timer->event(); |
690 | 684 |
691 UserGestureIndicator gestureIndicator(timer->userGestureToken()); | 685 UserGestureIndicator gestureIndicator(timer->userGestureToken()); |
692 | 686 |
693 event->entangleMessagePorts(document()); | 687 event->entangleMessagePorts(document()); |
694 dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->sta
ckTrace()); | 688 dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->tak
eLocation()); |
695 } | 689 } |
696 | 690 |
697 void LocalDOMWindow::removePostMessageTimer(PostMessageTimer* timer) | 691 void LocalDOMWindow::removePostMessageTimer(PostMessageTimer* timer) |
698 { | 692 { |
699 m_postMessageTimers.remove(timer); | 693 m_postMessageTimers.remove(timer); |
700 } | 694 } |
701 | 695 |
702 void LocalDOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intende
dTargetOrigin, Event* event, PassRefPtr<ScriptCallStack> stackTrace) | 696 void LocalDOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intende
dTargetOrigin, Event* event, PassOwnPtr<SourceLocation> location) |
703 { | 697 { |
704 if (intendedTargetOrigin) { | 698 if (intendedTargetOrigin) { |
705 // Check target origin now since the target document may have changed si
nce the timer was scheduled. | 699 // Check target origin now since the target document may have changed si
nce the timer was scheduled. |
706 SecurityOrigin* securityOrigin = document()->getSecurityOrigin(); | 700 SecurityOrigin* securityOrigin = document()->getSecurityOrigin(); |
707 bool validTarget = intendedTargetOrigin->isSameSchemeHostPortAndSuborigi
n(securityOrigin); | 701 bool validTarget = intendedTargetOrigin->isSameSchemeHostPortAndSuborigi
n(securityOrigin); |
708 if (securityOrigin->hasSuborigin() && securityOrigin->suborigin()->polic
yContains(Suborigin::SuboriginPolicyOptions::UnsafePostMessageReceive)) | 702 if (securityOrigin->hasSuborigin() && securityOrigin->suborigin()->polic
yContains(Suborigin::SuboriginPolicyOptions::UnsafePostMessageReceive)) |
709 validTarget = intendedTargetOrigin->isSameSchemeHostPort(securityOri
gin); | 703 validTarget = intendedTargetOrigin->isSameSchemeHostPort(securityOri
gin); |
710 | 704 |
711 if (!validTarget) { | 705 if (!validTarget) { |
712 String message = ExceptionMessages::failedToExecute("postMessage", "
DOMWindow", "The target origin provided ('" + intendedTargetOrigin->toString() +
"') does not match the recipient window's origin ('" + document()->getSecurityO
rigin()->toString() + "')."); | 706 String message = ExceptionMessages::failedToExecute("postMessage", "
DOMWindow", "The target origin provided ('" + intendedTargetOrigin->toString() +
"') does not match the recipient window's origin ('" + document()->getSecurityO
rigin()->toString() + "')."); |
713 ConsoleMessage* consoleMessage = ConsoleMessage::create(SecurityMess
ageSource, ErrorMessageLevel, message, String(), 0, 0, stackTrace); | 707 ConsoleMessage* consoleMessage = ConsoleMessage::create(SecurityMess
ageSource, ErrorMessageLevel, message, std::move(location)); |
714 frameConsole()->addMessage(consoleMessage); | 708 frameConsole()->addMessage(consoleMessage); |
715 return; | 709 return; |
716 } | 710 } |
717 } | 711 } |
718 | 712 |
719 dispatchEvent(event); | 713 dispatchEvent(event); |
720 } | 714 } |
721 | 715 |
722 DOMSelection* LocalDOMWindow::getSelection() | 716 DOMSelection* LocalDOMWindow::getSelection() |
723 { | 717 { |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 { | 1531 { |
1538 // If the LocalDOMWindow still has a frame reference, that frame must point | 1532 // If the LocalDOMWindow still has a frame reference, that frame must point |
1539 // back to this LocalDOMWindow: otherwise, it's easy to get into a situation | 1533 // back to this LocalDOMWindow: otherwise, it's easy to get into a situation |
1540 // where script execution leaks between different LocalDOMWindows. | 1534 // where script execution leaks between different LocalDOMWindows. |
1541 if (m_frameObserver->frame()) | 1535 if (m_frameObserver->frame()) |
1542 ASSERT_WITH_SECURITY_IMPLICATION(m_frameObserver->frame()->domWindow() =
= this); | 1536 ASSERT_WITH_SECURITY_IMPLICATION(m_frameObserver->frame()->domWindow() =
= this); |
1543 return m_frameObserver->frame(); | 1537 return m_frameObserver->frame(); |
1544 } | 1538 } |
1545 | 1539 |
1546 } // namespace blink | 1540 } // namespace blink |
OLD | NEW |