Commit 1257ea7e authored by John Rummell's avatar John Rummell Committed by Commit Bot

Check for context destroyed in MediaKeys

Don't allow calls to proceed once the associated content has been
destroyed.

Bug: 1121414
Test: example in the bug no longer crashes
Change-Id: I3bdeb86f2020f684958b624fcc30438babfb5004
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2378889Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarXiaohan Wang <xhwang@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805561}
parent eaac9a29
...@@ -221,6 +221,13 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state, ...@@ -221,6 +221,13 @@ MediaKeySession* MediaKeys::createSession(ScriptState* script_state,
DVLOG(MEDIA_KEYS_LOG_LEVEL) DVLOG(MEDIA_KEYS_LOG_LEVEL)
<< __func__ << "(" << this << ") " << session_type_string; << __func__ << "(" << this << ") " << session_type_string;
// If the context for MediaKeys has been destroyed, fail.
if (!GetExecutionContext()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
"The context provided is invalid.");
return nullptr;
}
// [RuntimeEnabled] does not work with enum values. So we have to check it // [RuntimeEnabled] does not work with enum values. So we have to check it
// here. See https://crbug.com/871867 for details. // here. See https://crbug.com/871867 for details.
if (!RuntimeEnabledFeatures:: if (!RuntimeEnabledFeatures::
...@@ -267,6 +274,13 @@ ScriptPromise MediaKeys::setServerCertificate( ...@@ -267,6 +274,13 @@ ScriptPromise MediaKeys::setServerCertificate(
ScriptState* script_state, ScriptState* script_state,
const DOMArrayPiece& server_certificate, const DOMArrayPiece& server_certificate,
ExceptionState& exception_state) { ExceptionState& exception_state) {
// If the context for MediaKeys has been destroyed, fail.
if (!GetExecutionContext()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
"The context provided is invalid.");
return ScriptPromise();
}
// From https://w3c.github.io/encrypted-media/#setServerCertificate // From https://w3c.github.io/encrypted-media/#setServerCertificate
// The setServerCertificate(serverCertificate) method provides a server // The setServerCertificate(serverCertificate) method provides a server
// certificate to be used to encrypt messages to the license server. // certificate to be used to encrypt messages to the license server.
...@@ -309,6 +323,15 @@ void MediaKeys::SetServerCertificateTask( ...@@ -309,6 +323,15 @@ void MediaKeys::SetServerCertificateTask(
ContentDecryptionModuleResult* result) { ContentDecryptionModuleResult* result) {
DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")"; DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")";
// If the context has been destroyed, don't proceed. Try to have the promise
// be rejected.
if (!GetExecutionContext()) {
result->CompleteWithError(
kWebContentDecryptionModuleExceptionInvalidStateError, 0,
"The context provided is invalid.");
return;
}
// 5.1 Let cdm be the cdm during the initialization of this object. // 5.1 Let cdm be the cdm during the initialization of this object.
WebContentDecryptionModule* cdm = ContentDecryptionModule(); WebContentDecryptionModule* cdm = ContentDecryptionModule();
...@@ -325,7 +348,15 @@ void MediaKeys::SetServerCertificateTask( ...@@ -325,7 +348,15 @@ void MediaKeys::SetServerCertificateTask(
ScriptPromise MediaKeys::getStatusForPolicy( ScriptPromise MediaKeys::getStatusForPolicy(
ScriptState* script_state, ScriptState* script_state,
const MediaKeysPolicy* media_keys_policy) { const MediaKeysPolicy* media_keys_policy,
ExceptionState& exception_state) {
// If the context for MediaKeys has been destroyed, fail.
if (!GetExecutionContext()) {
exception_state.ThrowDOMException(DOMExceptionCode::kInvalidAccessError,
"The context provided is invalid.");
return ScriptPromise();
}
// TODO(xhwang): Pass MediaKeysPolicy classes all the way to Chromium when // TODO(xhwang): Pass MediaKeysPolicy classes all the way to Chromium when
// we have more than one policy to check. // we have more than one policy to check.
String min_hdcp_version = media_keys_policy->minHdcpVersion(); String min_hdcp_version = media_keys_policy->minHdcpVersion();
...@@ -349,6 +380,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version, ...@@ -349,6 +380,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version,
ContentDecryptionModuleResult* result) { ContentDecryptionModuleResult* result) {
DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << ": " << min_hdcp_version; DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << ": " << min_hdcp_version;
// If the context has been destroyed, don't proceed. Try to have the promise
// be rejected.
if (!GetExecutionContext()) {
result->CompleteWithError(
kWebContentDecryptionModuleExceptionInvalidStateError, 0,
"The context provided is invalid.");
return;
}
WebContentDecryptionModule* cdm = ContentDecryptionModule(); WebContentDecryptionModule* cdm = ContentDecryptionModule();
cdm->GetStatusForPolicy(min_hdcp_version, result->Result()); cdm->GetStatusForPolicy(min_hdcp_version, result->Result());
} }
......
...@@ -70,9 +70,11 @@ class MediaKeys : public ScriptWrappable, ...@@ -70,9 +70,11 @@ class MediaKeys : public ScriptWrappable,
ScriptPromise setServerCertificate(ScriptState*, ScriptPromise setServerCertificate(ScriptState*,
const DOMArrayPiece& server_certificate, const DOMArrayPiece& server_certificate,
ExceptionState& exception_state); ExceptionState&);
ScriptPromise getStatusForPolicy(ScriptState*, const MediaKeysPolicy*); ScriptPromise getStatusForPolicy(ScriptState*,
const MediaKeysPolicy*,
ExceptionState&);
// Indicates that the provided HTMLMediaElement wants to use this object. // Indicates that the provided HTMLMediaElement wants to use this object.
// Returns true if no other HTMLMediaElement currently references this // Returns true if no other HTMLMediaElement currently references this
......
...@@ -14,10 +14,12 @@ namespace blink { ...@@ -14,10 +14,12 @@ namespace blink {
ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy( ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy(
ScriptState* script_state, ScriptState* script_state,
MediaKeys& media_keys, MediaKeys& media_keys,
const MediaKeysPolicy* media_keys_policy) { const MediaKeysPolicy* media_keys_policy,
ExceptionState& exception_state) {
DVLOG(1) << __func__; DVLOG(1) << __func__;
return media_keys.getStatusForPolicy(script_state, media_keys_policy); return media_keys.getStatusForPolicy(script_state, media_keys_policy,
exception_state);
} }
} // namespace blink } // namespace blink
...@@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy { ...@@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy {
public: public:
static ScriptPromise getStatusForPolicy(ScriptState*, static ScriptPromise getStatusForPolicy(ScriptState*,
MediaKeys&, MediaKeys&,
const MediaKeysPolicy*); const MediaKeysPolicy*,
ExceptionState&);
}; };
} // namespace blink } // namespace blink
......
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
ImplementedAs=MediaKeysGetStatusForPolicy, ImplementedAs=MediaKeysGetStatusForPolicy,
SecureContext SecureContext
] partial interface MediaKeys { ] partial interface MediaKeys {
[Measure, CallWith=ScriptState] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy); [Measure, CallWith=ScriptState, RaisesException] Promise<MediaKeyStatus> getStatusForPolicy(MediaKeysPolicy policy);
}; };
<!DOCTYPE html>
<html>
<head>
<title>Test context destruction.</title>
<script src="encrypted-media-utils.js"></script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
function allociframe() {
iframe = document.createElement('iframe');
iframe.height = 50;
iframe.width = 50;
document.body.appendChild(iframe);
return iframe;
}
async_test(async function(test)
{
iframe = allociframe();
keySystemAccess = await iframe.contentWindow.navigator.requestMediaKeySystemAccess('org.w3.clearkey', getSimpleConfiguration());
keys = await keySystemAccess.createMediaKeys();
document.body.removeChild(iframe);
keys.getStatusForPolicy({minHdcpVersion : '1.0'}).then(function(result) {
assert_unreached('getStatusforPolicy() should fail');
}, function(error) {
test.done();
});
}, 'Test context destruction.');
</script>
</body>
</html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment