Commit 7e529a20 authored by Chase Phillips's avatar Chase Phillips Committed by Commit Bot

IndexedDB: Cache result of sync AllowIndexedDB() call

This replays the cache solution from CacheStorage implemented
in https://crrev.com/c/1518592.

Bug: 941118
Change-Id: Id3f41cb2abed2efe8ced2525b0122965b44e22e3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1759321Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarBen Kelly <wanderview@chromium.org>
Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Commit-Queue: Chase Phillips <cmp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#688358}
parent e5f1b06d
......@@ -471,6 +471,47 @@ IN_PROC_BROWSER_TEST_P(CookieSettingsTest, BlockCookiesAlsoBlocksCacheStorage) {
}
}
IN_PROC_BROWSER_TEST_P(CookieSettingsTest, BlockCookiesAlsoBlocksIndexedDB) {
ui_test_utils::NavigateToURL(browser(), GetPageURL());
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(browser()->profile()).get();
settings->SetCookieSetting(GetPageURL(), CONTENT_SETTING_BLOCK);
content::WebContents* tab =
browser()->tab_strip_model()->GetActiveWebContents();
const char kBaseScript[] =
"(async function() {"
" const name = `%s`;"
" function wrap(req) {"
" return new Promise((resolve, reject) => {"
" req.onerror = function() { reject(req.error); };"
" req.onsuccess = function() { resolve(); };"
" });"
" }"
" try {"
" await wrap(%s);"
" } catch(e) {"
" return `${name} - ${e.toString()}`;"
" }"
" return `${name} - success`;"
"}())";
const std::vector<std::string> kTestOps({
"indexedDB.open('foo', 1)",
"indexedDB.deleteDatabase('foo')",
});
const char kBaseExpected[] =
"%s - UnknownError: The user denied permission to access the database.";
for (auto& op : kTestOps) {
EXPECT_EQ(
base::StringPrintf(kBaseExpected, op.data()),
EvalJs(tab, base::StringPrintf(kBaseScript, op.data(), op.data())));
}
}
INSTANTIATE_TEST_SUITE_P(
/* no prefix */,
CookieSettingsTest,
......
......@@ -268,7 +268,7 @@ IDBRequest* IDBFactory::GetDatabaseNames(ScriptState* script_state,
WebFeature::kFileAccessedDatabase);
}
if (!AllowIndexedDB(ExecutionContext::From(script_state))) {
if (!CachedAllowIndexedDB(script_state)) {
request->HandleResponse(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage));
return request;
......@@ -330,7 +330,7 @@ IDBOpenDBRequest* IDBFactory::OpenInternal(ScriptState* script_state,
script_state, database_callbacks, std::move(transaction_backend),
transaction_id, version, std::move(metrics));
if (!AllowIndexedDB(ExecutionContext::From(script_state))) {
if (!CachedAllowIndexedDB(script_state)) {
request->HandleResponse(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage));
return request;
......@@ -397,7 +397,7 @@ IDBOpenDBRequest* IDBFactory::DeleteDatabaseInternal(
script_state, nullptr, /*IDBTransactionAssociatedPtr=*/nullptr, 0,
IDBDatabaseMetadata::kDefaultVersion, std::move(metrics));
if (!AllowIndexedDB(ExecutionContext::From(script_state))) {
if (!CachedAllowIndexedDB(script_state)) {
request->HandleResponse(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kUnknownError, kPermissionDeniedErrorMessage));
return request;
......@@ -444,7 +444,8 @@ int16_t IDBFactory::cmp(ScriptState* script_state,
return static_cast<int16_t>(first->Compare(second.get()));
}
bool IDBFactory::AllowIndexedDB(ExecutionContext* execution_context) {
bool IDBFactory::AllowIndexedDB(ScriptState* script_state) {
ExecutionContext* execution_context = ExecutionContext::From(script_state);
DCHECK(execution_context->IsContextThread());
SECURITY_DCHECK(execution_context->IsDocument() ||
execution_context->IsWorkerGlobalScope());
......@@ -453,6 +454,7 @@ bool IDBFactory::AllowIndexedDB(ExecutionContext* execution_context) {
if (!frame)
return false;
if (auto* settings_client = frame->GetContentSettingsClient()) {
// This triggers a sync IPC.
return settings_client->AllowIndexedDB(
WebSecurityOrigin(execution_context->GetSecurityOrigin()));
}
......@@ -463,8 +465,17 @@ bool IDBFactory::AllowIndexedDB(ExecutionContext* execution_context) {
To<WorkerGlobalScope>(execution_context)->ContentSettingsClient();
if (!content_settings_client)
return true;
// This triggers a sync IPC.
return content_settings_client->AllowIndexedDB(
WebSecurityOrigin(execution_context->GetSecurityOrigin()));
}
bool IDBFactory::CachedAllowIndexedDB(ScriptState* script_state) {
if (!cached_allowed_.has_value()) {
// Cache the AllowIndexedDB() call because it triggers a sync IPC.
cached_allowed_.emplace(AllowIndexedDB(script_state));
}
return cached_allowed_.value();
}
} // namespace blink
......@@ -84,9 +84,11 @@ class MODULES_EXPORT IDBFactory final : public ScriptWrappable {
ExceptionState&,
bool);
bool AllowIndexedDB(ExecutionContext* execution_context);
bool AllowIndexedDB(ScriptState* script_state);
bool CachedAllowIndexedDB(ScriptState* script_state);
std::unique_ptr<WebIDBFactory> web_idb_factory_;
base::Optional<bool> cached_allowed_;
};
} // namespace blink
......
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