Commit 45cde148 authored by Andreas Butler's avatar Andreas Butler Committed by Commit Bot

IndexedDB: Handle the opaque origin case for IDBFactory.databases()

Implemented the proper throwing behaviour for handling the case of an
opaque origin for IDBFactory.databases(). Also included is a WPT for
verifying the behaviour written by jsbell@.

Spec PR: https://github.com/w3c/IndexedDB/pull/250

Change-Id: I506f82bf69b27d34b499eacbe12aaa18a69b63be
Reviewed-on: https://chromium-review.googlesource.com/c/1344629
Commit-Queue: Andreas Butler <andreasbutler@google.com>
Reviewed-by: default avatarJoshua Bell <jsbell@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610143}
parent 7ad78edc
<!DOCTYPE html>
<meta charset=utf-8>
<title>IDBFactory.databases() and opaque origins</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function load_iframe(src, sandbox) {
return new Promise(resolve => {
const iframe = document.createElement('iframe');
iframe.onload = () => { resolve(iframe); };
if (sandbox)
iframe.sandbox = sandbox;
iframe.srcdoc = src;
iframe.style.display = 'none';
document.documentElement.appendChild(iframe);
});
}
function wait_for_message(iframe) {
return new Promise(resolve => {
self.addEventListener('message', function listener(e) {
if (e.source === iframe.contentWindow) {
resolve(e.data);
self.removeEventListener('message', listener);
}
});
});
}
const script =
'<script>' +
' window.onmessage = () => {' +
' indexedDB.databases().then(' +
' () => window.parent.postMessage({result: "no exception"}, "*"),' +
' ex => window.parent.postMessage({result: ex.name}, "*"));' +
' };' +
'<\/script>';
promise_test(async t => {
const iframe = await load_iframe(script);
iframe.contentWindow.postMessage({}, '*');
const message = await wait_for_message(iframe);
assert_equals(message.result, 'no exception',
'IDBFactory.databases() should not reject');
}, 'IDBFactory.databases() in non-sandboxed iframe should not reject');
promise_test(async t => {
const iframe = await load_iframe(script, 'allow-scripts');
iframe.contentWindow.postMessage({}, '*');
const message = await wait_for_message(iframe);
assert_equals(message.result, 'SecurityError',
'Exception should be SecurityError');
}, 'IDBFactory.databases() in sandboxed iframe should reject');
</script>
...@@ -202,6 +202,16 @@ WebIDBFactory* IDBFactory::GetFactory() { ...@@ -202,6 +202,16 @@ WebIDBFactory* IDBFactory::GetFactory() {
ScriptPromise IDBFactory::GetDatabaseInfo(ScriptState* script_state, ScriptPromise IDBFactory::GetDatabaseInfo(ScriptState* script_state,
ExceptionState& exception_state) { ExceptionState& exception_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
if (!ExecutionContext::From(script_state)
->GetSecurityOrigin()
->CanAccessDatabase()) {
exception_state.ThrowSecurityError(
"Access to the IndexedDB API is denied in this context.");
resolver->Reject();
return resolver->Promise();
}
GetFactory()->GetDatabaseInfo( GetFactory()->GetDatabaseInfo(
WebIDBGetDBNamesCallbacksImpl::Create(resolver).release(), WebIDBGetDBNamesCallbacksImpl::Create(resolver).release(),
WebSecurityOrigin( WebSecurityOrigin(
......
...@@ -58,8 +58,10 @@ ACTION_TEMPLATE(SaveUniquePointer, ...@@ -58,8 +58,10 @@ ACTION_TEMPLATE(SaveUniquePointer,
*unique_pointer = base::WrapUnique(std::get<k>(args)); *unique_pointer = base::WrapUnique(std::get<k>(args));
} }
TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksResolvesPromise) { TEST_F(IDBFactoryTest, WebIDBGetDBInfoCallbacksResolvesPromise) {
V8TestingScope scope; V8TestingScope scope;
scope.GetDocument().SetSecurityOrigin(
SecurityOrigin::Create(KURL("https://example.com")));
std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create(); std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create();
std::unique_ptr<WebIDBCallbacks> wc; std::unique_ptr<WebIDBCallbacks> wc;
EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_)) EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_))
...@@ -93,6 +95,8 @@ TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksResolvesPromise) { ...@@ -93,6 +95,8 @@ TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksResolvesPromise) {
TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksRejectsPromise) { TEST_F(IDBFactoryTest, WebIDBGetDBNamesCallbacksRejectsPromise) {
V8TestingScope scope; V8TestingScope scope;
scope.GetDocument().SetSecurityOrigin(
SecurityOrigin::Create(KURL("https://example.com")));
std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create(); std::unique_ptr<MockWebIDBFactory> web_factory = MockWebIDBFactory::Create();
std::unique_ptr<WebIDBCallbacks> wc; std::unique_ptr<WebIDBCallbacks> wc;
EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_)) EXPECT_CALL(*web_factory, GetDatabaseInfo(testing::_, testing::_, testing::_))
......
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