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,
DVLOG(MEDIA_KEYS_LOG_LEVEL)
<< __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
// here. See https://crbug.com/871867 for details.
if (!RuntimeEnabledFeatures::
......@@ -267,6 +274,13 @@ ScriptPromise MediaKeys::setServerCertificate(
ScriptState* script_state,
const DOMArrayPiece& server_certificate,
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
// The setServerCertificate(serverCertificate) method provides a server
// certificate to be used to encrypt messages to the license server.
......@@ -309,6 +323,15 @@ void MediaKeys::SetServerCertificateTask(
ContentDecryptionModuleResult* result) {
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.
WebContentDecryptionModule* cdm = ContentDecryptionModule();
......@@ -325,7 +348,15 @@ void MediaKeys::SetServerCertificateTask(
ScriptPromise MediaKeys::getStatusForPolicy(
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
// we have more than one policy to check.
String min_hdcp_version = media_keys_policy->minHdcpVersion();
......@@ -349,6 +380,15 @@ void MediaKeys::GetStatusForPolicyTask(const String& min_hdcp_version,
ContentDecryptionModuleResult* result) {
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();
cdm->GetStatusForPolicy(min_hdcp_version, result->Result());
}
......
......@@ -70,9 +70,11 @@ class MediaKeys : public ScriptWrappable,
ScriptPromise setServerCertificate(ScriptState*,
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.
// Returns true if no other HTMLMediaElement currently references this
......
......@@ -14,10 +14,12 @@ namespace blink {
ScriptPromise MediaKeysGetStatusForPolicy::getStatusForPolicy(
ScriptState* script_state,
MediaKeys& media_keys,
const MediaKeysPolicy* media_keys_policy) {
const MediaKeysPolicy* media_keys_policy,
ExceptionState& exception_state) {
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
......@@ -20,7 +20,8 @@ class MediaKeysGetStatusForPolicy {
public:
static ScriptPromise getStatusForPolicy(ScriptState*,
MediaKeys&,
const MediaKeysPolicy*);
const MediaKeysPolicy*,
ExceptionState&);
};
} // namespace blink
......
......@@ -8,5 +8,5 @@
ImplementedAs=MediaKeysGetStatusForPolicy,
SecureContext
] 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