Changeset 225577 in webkit
- Timestamp:
- Dec 6, 2017 10:40:05 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r225576 r225577 1 2017-12-06 Chris Dumez <cdumez@apple.com> 2 3 ServiceWorkers API should reject promises when calling objects inside detached frames 4 https://bugs.webkit.org/show_bug.cgi?id=180444 5 6 Reviewed by Youenn Fablet. 7 8 * TestExpectations: 9 Unskip test that no longer times out and starts passing a few checks. 10 11 * fast/dom/navigator-detached-no-crash-expected.txt: 12 Rebaseline test now that promise is rejected. 13 14 * http/tests/media/media-stream/disconnected-frame-permission-denied-expected.txt: 15 * http/tests/media/media-stream/disconnected-frame-permission-denied.html: 16 Update and rebaseline test now that the promise is rejected. I verified that this 17 behavior is consistent with Chrome. 18 1 19 2017-12-06 Matt Lewis <jlewis3@apple.com> 2 20 -
trunk/LayoutTests/TestExpectations
r225566 r225577 146 146 # Skip service worker tests that are timing out. 147 147 imported/w3c/web-platform-tests/fetch/api/abort/general-serviceworker.https.html [ Skip ] 148 imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https.html [ Skip ]149 148 imported/w3c/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html [ Skip ] 150 149 imported/w3c/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-partial-stream.https.html [ Skip ] -
trunk/LayoutTests/fast/dom/navigator-detached-no-crash-expected.txt
r222958 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments 1 2 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 2 3 Check Navigator -
trunk/LayoutTests/http/tests/media/media-stream/disconnected-frame-expected.txt
r176011 r225577 1 frame "<!--framePath //<!--frame0-->-->" - has 1 onunload handler(s)2 1 Tests that when a request is made on a UserMedia object and its Frame is disconnected before a callback is made, the error callback is invoked with the correct error message. 3 2 -
trunk/LayoutTests/http/tests/media/media-stream/disconnected-frame-permission-denied-expected.txt
r201080 r225577 1 frame "<!--framePath //<!--frame0-->-->" - has 1 onunload handler(s)2 1 Tests that when a getUserMedia request is made, permission is denied and its Frame is disconnected before a callback is made, the error callback is invoked with PERMISSION_DENIED. 3 2 … … 7 6 PASS error.name is "NotAllowedError" 8 7 9 PASS No callbacksinvoked8 PASS Error callback invoked 10 9 PASS successfullyParsed is true 11 10 -
trunk/LayoutTests/http/tests/media/media-stream/disconnected-frame-permission-denied.html
r211962 r225577 18 18 function onIframeLoaded() { 19 19 iframeNavigator = iframe.contentWindow.navigator; 20 iframe.contentWindow.onunload = onIframeUnloaded; 20 21 iframeNavigator.mediaDevices.getUserMedia(options) 21 22 .then(stream => { … … 39 40 }) 40 41 .catch(err => { 41 test Failed('Error callback invoked unexpectedly');42 testPassed('Error callback invoked'); 42 43 finishJSTest(); 43 44 }); 44 45 setTimeout(function() { 45 test Passed('No callbacks invoked');46 testFailed('No callbacks invoked'); 46 47 finishJSTest(); 47 48 }, 100); -
trunk/LayoutTests/http/tests/media/media-stream/disconnected-frame.html
r211962 r225577 14 14 function onIframeLoaded() { 15 15 iframeNavigator = iframe.contentWindow.navigator; 16 iframe.src = 'data:text/html,This frame should be visible when the test completes'; 16 iframe.remove(); 17 onIframeUnloaded(); 17 18 } 18 19 -
trunk/LayoutTests/http/tests/media/media-stream/resources/disconnected-frame-inner.html
r176011 r225577 3 3 <head> 4 4 </head> 5 <body onload="window.parent.onIframeLoaded()" onunload="window.parent.onIframeUnloaded();">5 <body onload="window.parent.onIframeLoaded()"> 6 6 <p>This frame should be replaced before the test ends</p> 7 7 </body> -
trunk/LayoutTests/imported/w3c/ChangeLog
r225574 r225577 1 2017-12-06 Chris Dumez <cdumez@apple.com> 2 3 ServiceWorkers API should reject promises when calling objects inside detached frames 4 https://bugs.webkit.org/show_bug.cgi?id=180444 5 6 Reviewed by Youenn Fablet. 7 8 Rebaseline test now that it is passing some checks. 9 10 * web-platform-tests/service-workers/service-worker/detached-context.https-expected.txt: 11 * web-platform-tests/service-workers/service-worker/register-closed-window.https-expected.txt: 12 1 13 2017-12-06 Youenn Fablet <youenn@apple.com> 2 14 -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/detached-context.https-expected.txt
r224730 r225577 1 1 2 Harness Error (TIMEOUT), message = null3 2 4 TIMEOUT accessing a ServiceWorkerRegistration from a removed iframe Test timed out 5 NOTRUNaccessing a ServiceWorker object from a removed iframe6 NOTRUNaccessing navigator.serviceWorker on a detached iframe3 PASS accessing a ServiceWorkerRegistration from a removed iframe 4 PASS accessing a ServiceWorker object from a removed iframe 5 PASS accessing navigator.serviceWorker on a detached iframe 7 6 FAIL accessing navigator on a removed frame assert_throws: function "() => get_navigator()" did not throw 8 7 FAIL accessing navigator.serviceWorker on a removed about:blank frame undefined is not an object (evaluating 'get_navigator().serviceWorker') -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ready.https-expected.txt
r225531 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: InvalidStateError: The object is in an invalid state. 2 CONSOLE MESSAGE: Unhandled Promise Rejection: InvalidStateError: The object is in an invalid state. 1 3 2 4 PASS ready returns the same Promise object -
trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/register-closed-window.https-expected.txt
r224132 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: serviceWorker.register() must be called with a valid relative script URL 1 2 2 3 PASS Call register() on ServiceWorkerContainer owned by closed window. -
trunk/LayoutTests/platform/gtk/fast/dom/navigator-detached-no-crash-expected.txt
r219403 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments 1 2 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 2 3 Check Navigator -
trunk/LayoutTests/platform/mac-elcapitan-wk2/fast/dom/navigator-detached-no-crash-expected.txt
r222958 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments 1 2 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 2 3 Check Navigator -
trunk/LayoutTests/platform/mac-wk1/fast/dom/navigator-detached-no-crash-expected.txt
r224833 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments 1 2 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 2 3 Check Navigator -
trunk/LayoutTests/platform/win/fast/dom/navigator-detached-no-crash-expected.txt
r220507 r225577 1 CONSOLE MESSAGE: Unhandled Promise Rejection: TypeError: Not enough arguments 1 2 This tests that the navigator object of a deleted frame is disconnected properly. Accessing fields or methods shouldn't crash the browser. 2 3 Check Navigator -
trunk/Source/WebCore/ChangeLog
r225575 r225577 1 2017-12-06 Chris Dumez <cdumez@apple.com> 2 3 ServiceWorkers API should reject promises when calling objects inside detached frames 4 https://bugs.webkit.org/show_bug.cgi?id=180444 5 6 Reviewed by Youenn Fablet. 7 8 ServiceWorkers API should reject promises when calling objects inside detached frames. 9 10 No new tests, rebaselined existing test. 11 12 * bindings/js/JSDOMPromiseDeferred.h: 13 (WebCore::callPromiseFunction): 14 Use the caller's globalObject instead of the lexicalGlobalObject when constructing the 15 deferred promise. The bug became visible when working on this service worker bug since 16 rejecting the promise when the frame is detached did not actually work. The issue is 17 that since the promise was created with the detached frame's globalObject, then it was 18 suspended and would not run script. 19 20 * bindings/js/JSDOMWindowBase.cpp: 21 (WebCore::callerGlobalObject): 22 (WebCore::incumbentDOMWindow): 23 * bindings/js/JSDOMWindowBase.h: 24 Add convenience function to get the caller's globalObject. It was carved out of 25 incumbentDOMWindow(). 26 27 * workers/service/ServiceWorker.cpp: 28 (WebCore::ServiceWorker::postMessage): 29 * workers/service/ServiceWorkerContainer.cpp: 30 (WebCore::ServiceWorkerContainer::addRegistration): 31 (WebCore::ServiceWorkerContainer::getRegistration): 32 (WebCore::ServiceWorkerContainer::getRegistrations): 33 * workers/service/ServiceWorkerRegistration.cpp: 34 (WebCore::ServiceWorkerRegistration::update): 35 (WebCore::ServiceWorkerRegistration::unregister): 36 Reject the promise when m_isStopped flag is set (i.e. ActiveDOMObject::stop() 37 has been called). 38 1 39 2017-12-06 Said Abou-Hallawa <sabouhallawa@apple.com> 2 40 -
trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
r223728 r225577 272 272 } 273 273 274 JSDOMGlobalObject& callerGlobalObject(ExecState& state) 275 { 276 class GetCallerGlobalObjectFunctor { 277 public: 278 GetCallerGlobalObjectFunctor() = default; 279 280 StackVisitor::Status operator()(StackVisitor& visitor) const 281 { 282 if (!m_hasSkippedFirstFrame) { 283 m_hasSkippedFirstFrame = true; 284 return StackVisitor::Continue; 285 } 286 287 if (auto* codeBlock = visitor->codeBlock()) 288 m_globalObject = codeBlock->globalObject(); 289 else { 290 ASSERT(visitor->callee().rawPtr()); 291 // FIXME: Callee is not an object if the caller is Web Assembly. 292 // Figure out what to do here. We can probably get the global object 293 // from the top-most Wasm Instance. https://bugs.webkit.org/show_bug.cgi?id=165721 294 if (visitor->callee().isCell() && visitor->callee().asCell()->isObject()) 295 m_globalObject = jsCast<JSObject*>(visitor->callee().asCell())->globalObject(); 296 } 297 return StackVisitor::Done; 298 } 299 300 JSGlobalObject* globalObject() const { return m_globalObject; } 301 302 private: 303 mutable bool m_hasSkippedFirstFrame { false }; 304 mutable JSGlobalObject* m_globalObject { nullptr }; 305 }; 306 307 GetCallerGlobalObjectFunctor iter; 308 state.iterate(iter); 309 return *jsCast<JSDOMGlobalObject*>(iter.globalObject() ? iter.globalObject() : state.vmEntryGlobalObject()); 310 } 311 274 312 } // namespace WebCore -
trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h
r218342 r225577 130 130 JSDOMGlobalObject* toJSDOMGlobalObject(ScriptExecutionContext*, DOMWrapperWorld&); 131 131 132 WEBCORE_EXPORT JSDOMGlobalObject& callerGlobalObject(JSC::ExecState&); 133 132 134 } // namespace WebCore -
trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.h
r221849 r225577 265 265 auto scope = DECLARE_CATCH_SCOPE(vm); 266 266 267 JSDOMGlobalObject& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject());267 auto& globalObject = callerGlobalObject(state); 268 268 JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, &globalObject); 269 269 … … 285 285 auto scope = DECLARE_CATCH_SCOPE(vm); 286 286 287 JSDOMGlobalObject& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject());287 auto& globalObject = callerGlobalObject(state); 288 288 JSC::JSPromiseDeferred* promiseDeferred = JSC::JSPromiseDeferred::create(&state, &globalObject); 289 289 -
trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp
r224736 r225577 290 290 DOMWindow& incumbentDOMWindow(ExecState& state) 291 291 { 292 class GetCallerGlobalObjectFunctor { 293 public: 294 GetCallerGlobalObjectFunctor() = default; 295 296 StackVisitor::Status operator()(StackVisitor& visitor) const 297 { 298 if (!m_hasSkippedFirstFrame) { 299 m_hasSkippedFirstFrame = true; 300 return StackVisitor::Continue; 301 } 302 303 if (auto* codeBlock = visitor->codeBlock()) 304 m_globalObject = codeBlock->globalObject(); 305 else { 306 ASSERT(visitor->callee().rawPtr()); 307 // FIXME: Callee is not an object if the caller is Web Assembly. 308 // Figure out what to do here. We can probably get the global object 309 // from the top-most Wasm Instance. https://bugs.webkit.org/show_bug.cgi?id=165721 310 if (visitor->callee().isCell() && visitor->callee().asCell()->isObject()) 311 m_globalObject = jsCast<JSObject*>(visitor->callee().asCell())->globalObject(); 312 } 313 return StackVisitor::Done; 314 } 315 316 JSGlobalObject* globalObject() const { return m_globalObject; } 317 318 private: 319 mutable bool m_hasSkippedFirstFrame { false }; 320 mutable JSGlobalObject* m_globalObject { nullptr }; 321 }; 322 323 GetCallerGlobalObjectFunctor iter; 324 state.iterate(iter); 325 return iter.globalObject() ? asJSDOMWindow(iter.globalObject())->wrapped() : firstDOMWindow(state); 292 return asJSDOMWindow(&callerGlobalObject(state))->wrapped(); 326 293 } 327 294 -
trunk/Source/WebCore/workers/service/ServiceWorker.cpp
r225462 r225577 89 89 ExceptionOr<void> ServiceWorker::postMessage(ScriptExecutionContext& context, JSC::JSValue messageValue, Vector<JSC::Strong<JSC::JSObject>>&& transfer) 90 90 { 91 if (m_isStopped) 92 return Exception { InvalidStateError }; 93 91 94 if (state() == State::Redundant) 92 95 return Exception { InvalidStateError, ASCIILiteral("Service Worker state is redundant") }; -
trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp
r225531 r225577 112 112 { 113 113 auto* context = scriptExecutionContext(); 114 if (!context || !context->sessionID().isValid()) { 115 ASSERT_NOT_REACHED(); 114 if (m_isStopped || !context->sessionID().isValid()) { 116 115 promise->reject(Exception(InvalidStateError)); 117 116 return; … … 235 234 void ServiceWorkerContainer::getRegistration(const String& clientURL, Ref<DeferredPromise>&& promise) 236 235 { 237 auto* context = scriptExecutionContext(); 238 if (!context) { 239 ASSERT_NOT_REACHED(); 236 if (m_isStopped) { 240 237 promise->reject(Exception { InvalidStateError }); 241 238 return; 242 239 } 243 240 244 URL parsedURL = context->completeURL(clientURL); 245 if (!protocolHostAndPortAreEqual(parsedURL, context->url())) { 241 ASSERT(scriptExecutionContext()); 242 auto& context = *scriptExecutionContext(); 243 244 URL parsedURL = context.completeURL(clientURL); 245 if (!protocolHostAndPortAreEqual(parsedURL, context.url())) { 246 246 promise->reject(Exception { SecurityError, ASCIILiteral("Origin of clientURL is not client's origin") }); 247 247 return; … … 253 253 254 254 auto contextIdentifier = this->contextIdentifier(); 255 callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context ->topOrigin().isolatedCopy(), parsedURL = parsedURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable {255 callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context.topOrigin().isolatedCopy(), parsedURL = parsedURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable { 256 256 connection->matchRegistration(topOrigin, parsedURL, [this, contextIdentifier, pendingPromiseIdentifier] (auto&& result) mutable { 257 257 ScriptExecutionContext::postTaskTo(contextIdentifier, [this, pendingPromiseIdentifier, result = crossThreadCopy(result)](ScriptExecutionContext&) mutable { … … 301 301 void ServiceWorkerContainer::getRegistrations(Ref<DeferredPromise>&& promise) 302 302 { 303 auto* context = scriptExecutionContext(); 304 if (!context) { 303 if (m_isStopped) { 305 304 promise->reject(Exception { InvalidStateError }); 306 305 return; 307 306 } 307 308 ASSERT(scriptExecutionContext()); 309 auto& context = *scriptExecutionContext(); 308 310 309 311 uint64_t pendingPromiseIdentifier = ++m_lastPendingPromiseIdentifier; … … 312 314 313 315 auto contextIdentifier = this->contextIdentifier(); 314 auto contextURL = context ->url();315 callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context ->topOrigin().isolatedCopy(), contextURL = contextURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable {316 auto contextURL = context.url(); 317 callOnMainThread([connection = makeRef(ensureSWClientConnection()), this, topOrigin = context.topOrigin().isolatedCopy(), contextURL = contextURL.isolatedCopy(), contextIdentifier, pendingPromiseIdentifier]() mutable { 316 318 connection->getRegistrations(topOrigin, contextURL, [this, contextIdentifier, pendingPromiseIdentifier] (auto&& registrationDatas) mutable { 317 319 ScriptExecutionContext::postTaskTo(contextIdentifier, [this, pendingPromiseIdentifier, registrationDatas = crossThreadCopy(registrationDatas)](ScriptExecutionContext&) mutable { -
trunk/Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
r225456 r225577 115 115 void ServiceWorkerRegistration::update(Ref<DeferredPromise>&& promise) 116 116 { 117 auto* context = scriptExecutionContext(); 118 if (!context) { 117 if (m_isStopped) { 119 118 promise->reject(Exception(InvalidStateError)); 120 119 return; … … 133 132 void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise) 134 133 { 135 auto* context = scriptExecutionContext(); 136 if (!context) { 134 if (m_isStopped) { 137 135 promise->reject(Exception(InvalidStateError)); 138 136 return;
Note: See TracChangeset
for help on using the changeset viewer.