mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1778489 - Define window.indexedDB as null in Private Browsing Mode r=twisniewski,asuth
https://www.msn.com/ja-jp/feed accesses `indexedDB` as a global variable and thus it throws undefined identifier error when it's not defined. Returning null fixes the regression. Differential Revision: https://phabricator.services.mozilla.com/D151373
This commit is contained in:
parent
28609ba87e
commit
f4fcfcd045
@ -5047,7 +5047,14 @@ Storage* nsGlobalWindowInner::GetLocalStorage(ErrorResult& aError) {
|
||||
return mLocalStorage;
|
||||
}
|
||||
|
||||
IDBFactory* nsGlobalWindowInner::GetIndexedDB(ErrorResult& aError) {
|
||||
IDBFactory* nsGlobalWindowInner::GetIndexedDB(JSContext* aCx,
|
||||
ErrorResult& aError) {
|
||||
if (!IDBFactory::IsEnabled(aCx, AsGlobal()->GetGlobalJSObject())) {
|
||||
// Let window.indexedDB be an attribute with a null value, to prevent
|
||||
// undefined identifier error
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!mIndexedDB) {
|
||||
// This may keep mIndexedDB null without setting an error.
|
||||
auto res = IDBFactory::CreateForWindow(this);
|
||||
|
@ -744,7 +744,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
||||
mozilla::dom::Storage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Storage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::IDBFactory* GetIndexedDB(JSContext* aCx,
|
||||
mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsICSSDeclaration> GetComputedStyle(
|
||||
mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
|
||||
mozilla::ErrorResult& aError) override;
|
||||
|
@ -2,66 +2,107 @@
|
||||
|
||||
const isWorker = typeof DedicatedWorkerGlobalScope === "function";
|
||||
|
||||
function check(content, expected, item) {
|
||||
const exposed = expected ? "is exposed without" : "is not exposed with";
|
||||
const worker = isWorker ? "in worker" : "in window";
|
||||
is(
|
||||
content.eval(`!!globalThis.${item}`),
|
||||
expected,
|
||||
`${item} ${exposed} pbmode ${worker}`
|
||||
);
|
||||
}
|
||||
|
||||
function checkCaches(content, expected) {
|
||||
check(content, expected, "caches");
|
||||
check(content, expected, "Cache");
|
||||
check(content, expected, "CacheStorage");
|
||||
}
|
||||
|
||||
function checkIDB(content, expected) {
|
||||
check(content, expected, "indexedDB");
|
||||
check(content, expected, "IDBFactory");
|
||||
check(content, expected, "IDBKeyRange");
|
||||
check(content, expected, "IDBOpenDBRequest");
|
||||
check(content, expected, "IDBRequest");
|
||||
check(content, expected, "IDBVersionChangeEvent");
|
||||
|
||||
// These are always accessed by jakearchibald/idb@v3 without existence checks.
|
||||
// https://github.com/jakearchibald/idb/blob/e1c7c44dbba38415745afc782b8e247da8c833f2/lib/idb.mjs#L152
|
||||
check(content, true, "IDBCursor");
|
||||
check(content, true, "IDBDatabase");
|
||||
check(content, true, "IDBIndex");
|
||||
check(content, true, "IDBObjectStore");
|
||||
check(content, true, "IDBTransaction");
|
||||
}
|
||||
|
||||
function checkSW(content, expected) {
|
||||
if (isWorker) {
|
||||
// Currently not supported. Bug 1131324
|
||||
return;
|
||||
function checkAll(content, inPrivateBrowsing) {
|
||||
function check(
|
||||
item,
|
||||
{ valueExpected, enumerationExpected, parent = "globalThis" }
|
||||
) {
|
||||
const exposed = valueExpected ? "is exposed" : "is not exposed";
|
||||
const pbmode = inPrivateBrowsing ? "with pbmode" : "without pbmode";
|
||||
const enumerated = enumerationExpected
|
||||
? "is enumerated"
|
||||
: "is not enumerated";
|
||||
const worker = isWorker ? "in worker" : "in window";
|
||||
is(
|
||||
content.eval(`!!${parent}.${item}`),
|
||||
valueExpected,
|
||||
`${parent}.${item} ${exposed} ${pbmode} ${worker}`
|
||||
);
|
||||
is(
|
||||
content.eval(`"${item}" in ${parent}`),
|
||||
enumerationExpected,
|
||||
`${parent}.${item} ${enumerated} ${pbmode} ${worker}`
|
||||
);
|
||||
}
|
||||
check(content, expected, "navigator.serviceWorker");
|
||||
check(content, expected, "ServiceWorker");
|
||||
check(content, expected, "ServiceWorkerContainer");
|
||||
check(content, expected, "ServiceWorkerRegistration");
|
||||
check(content, expected, "NavigationPreloadManager");
|
||||
check(content, expected, "PushManager");
|
||||
check(content, expected, "PushSubscription");
|
||||
check(content, expected, "PushSubscriptionOptions");
|
||||
}
|
||||
|
||||
function checkAll(content, expected) {
|
||||
checkCaches(content, expected);
|
||||
checkIDB(content, expected);
|
||||
checkSW(content, expected);
|
||||
function checkNotExposedInPBM(item, parent) {
|
||||
check(item, {
|
||||
valueExpected: !inPrivateBrowsing,
|
||||
enumerationExpected: !inPrivateBrowsing,
|
||||
parent,
|
||||
});
|
||||
}
|
||||
|
||||
function checkCaches() {
|
||||
checkNotExposedInPBM("caches");
|
||||
checkNotExposedInPBM("Cache");
|
||||
checkNotExposedInPBM("CacheStorage");
|
||||
}
|
||||
|
||||
function checkIDB() {
|
||||
checkNotExposedInPBM("IDBFactory");
|
||||
checkNotExposedInPBM("IDBKeyRange");
|
||||
checkNotExposedInPBM("IDBOpenDBRequest");
|
||||
checkNotExposedInPBM("IDBRequest");
|
||||
checkNotExposedInPBM("IDBVersionChangeEvent");
|
||||
|
||||
// These are always accessed by jakearchibald/idb@v3 without existence checks.
|
||||
// https://github.com/jakearchibald/idb/blob/e1c7c44dbba38415745afc782b8e247da8c833f2/lib/idb.mjs#L152
|
||||
check("IDBCursor", {
|
||||
valueExpected: true,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
check("IDBDatabase", {
|
||||
valueExpected: true,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
check("IDBIndex", {
|
||||
valueExpected: true,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
check("IDBObjectStore", {
|
||||
valueExpected: true,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
check("IDBTransaction", {
|
||||
valueExpected: true,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
|
||||
// https://www.msn.com/feed accesses indexedDB as a global variable without existence check
|
||||
// We need to always expose the attribute itself
|
||||
check("indexedDB", {
|
||||
valueExpected: !inPrivateBrowsing,
|
||||
enumerationExpected: true,
|
||||
});
|
||||
}
|
||||
|
||||
function checkSW() {
|
||||
if (isWorker) {
|
||||
// Currently not supported. Bug 1131324
|
||||
return;
|
||||
}
|
||||
checkNotExposedInPBM("serviceWorker", "navigator");
|
||||
checkNotExposedInPBM("ServiceWorker");
|
||||
checkNotExposedInPBM("ServiceWorkerContainer");
|
||||
checkNotExposedInPBM("ServiceWorkerRegistration");
|
||||
checkNotExposedInPBM("NavigationPreloadManager");
|
||||
checkNotExposedInPBM("PushManager");
|
||||
checkNotExposedInPBM("PushSubscription");
|
||||
checkNotExposedInPBM("PushSubscriptionOptions");
|
||||
}
|
||||
|
||||
checkCaches();
|
||||
checkIDB();
|
||||
checkSW();
|
||||
}
|
||||
|
||||
if (isWorker) {
|
||||
importScripts("/tests/SimpleTest/WorkerSimpleTest.js");
|
||||
|
||||
globalThis.onmessage = ev => {
|
||||
const { expected } = ev.data;
|
||||
checkAll(globalThis, expected);
|
||||
const { inPrivateBrowsing } = ev.data;
|
||||
checkAll(globalThis, inPrivateBrowsing);
|
||||
postMessage({
|
||||
kind: "info",
|
||||
next: true,
|
||||
|
@ -27,11 +27,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
function runWorkerTest(content, expected) {
|
||||
function runWorkerTest(content, inPrivateBrowsing) {
|
||||
return new Promise((resolve, reject) => {
|
||||
/** @type {Worker} */
|
||||
const worker = content.eval("new Worker('/chrome/dom/base/test/chrome/file_hide_in_pbmode.js')");
|
||||
worker.postMessage({ expected });
|
||||
worker.postMessage({ inPrivateBrowsing });
|
||||
worker.onerror = reject;
|
||||
listenForTests(worker);
|
||||
worker.addEventListener("message", ev => {
|
||||
@ -46,13 +46,13 @@
|
||||
async function runTest() {
|
||||
// sanity check
|
||||
let win = await openBrowserWindow(contentPage, { private: false });
|
||||
checkAll(win.content, true);
|
||||
await runWorkerTest(win.content, true);
|
||||
checkAll(win.content, false);
|
||||
await runWorkerTest(win.content, false);
|
||||
win.close();
|
||||
|
||||
win = await openBrowserWindow(contentPage, { private: true });
|
||||
checkAll(win.content, false);
|
||||
await runWorkerTest(win.content, false);
|
||||
checkAll(win.content, true);
|
||||
await runWorkerTest(win.content, true);
|
||||
win.close();
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -1600,7 +1600,7 @@ DOMInterfaces = {
|
||||
'nativeType': 'nsGlobalWindowInner',
|
||||
'headerFile': 'nsGlobalWindow.h',
|
||||
'implicitJSContext': [
|
||||
'requestIdleCallback'
|
||||
'requestIdleCallback', 'indexedDB'
|
||||
],
|
||||
},
|
||||
|
||||
@ -1627,7 +1627,7 @@ DOMInterfaces = {
|
||||
|
||||
'WorkerGlobalScope': {
|
||||
'headerFile': 'mozilla/dom/WorkerScope.h',
|
||||
'implicitJSContext': [ 'importScripts' ],
|
||||
'implicitJSContext': [ 'importScripts', 'indexedDB' ],
|
||||
},
|
||||
|
||||
'Worklet': {
|
||||
|
@ -70,7 +70,7 @@ partial interface mixin WindowOrWorkerGlobalScope {
|
||||
// http://w3c.github.io/IndexedDB/#factory-interface
|
||||
partial interface mixin WindowOrWorkerGlobalScope {
|
||||
// readonly attribute IDBFactory indexedDB; // bug 1776789
|
||||
[Throws, Func="IDBFactory::IsEnabled"]
|
||||
[Throws]
|
||||
readonly attribute IDBFactory? indexedDB;
|
||||
};
|
||||
|
||||
|
@ -676,9 +676,15 @@ already_AddRefed<Promise> WorkerGlobalScope::Fetch(
|
||||
}
|
||||
|
||||
already_AddRefed<IDBFactory> WorkerGlobalScope::GetIndexedDB(
|
||||
ErrorResult& aErrorResult) {
|
||||
JSContext* aCx, ErrorResult& aErrorResult) {
|
||||
AssertIsOnWorkerThread();
|
||||
|
||||
if (!IDBFactory::IsEnabled(aCx, GetGlobalJSObject())) {
|
||||
// Let window.indexedDB be an attribute with a null value, to prevent
|
||||
// undefined identifier error
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDBFactory> indexedDB = mIndexedDB;
|
||||
|
||||
if (!indexedDB) {
|
||||
|
@ -312,7 +312,8 @@ class WorkerGlobalScope : public WorkerGlobalScopeBase {
|
||||
|
||||
bool IsSecureContext() const;
|
||||
|
||||
already_AddRefed<IDBFactory> GetIndexedDB(ErrorResult& aErrorResult);
|
||||
already_AddRefed<IDBFactory> GetIndexedDB(JSContext* aCx,
|
||||
ErrorResult& aErrorResult);
|
||||
|
||||
already_AddRefed<cache::CacheStorage> GetCaches(ErrorResult& aRv);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user