mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1176434 - Enabling indexedDB for content JS sandboxes, r=bent
This commit is contained in:
parent
742b0e4f95
commit
c1cec6411f
@ -180,18 +180,26 @@ IDBFactory::CreateForWindow(nsPIDOMWindow* aWindow,
|
||||
|
||||
// static
|
||||
nsresult
|
||||
IDBFactory::CreateForChromeJS(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aOwningObject,
|
||||
IDBFactory** aFactory)
|
||||
IDBFactory::CreateForMainThreadJS(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aOwningObject,
|
||||
IDBFactory** aFactory)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
|
||||
nsAutoPtr<PrincipalInfo> principalInfo(
|
||||
new PrincipalInfo(SystemPrincipalInfo()));
|
||||
nsAutoPtr<PrincipalInfo> principalInfo(new PrincipalInfo());
|
||||
nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(aOwningObject);
|
||||
MOZ_ASSERT(principal);
|
||||
bool isSystem;
|
||||
if (!AllowedForPrincipal(principal, &isSystem)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
CreateForMainThreadJSInternal(aCx, aOwningObject, principalInfo, aFactory);
|
||||
nsresult rv = PrincipalToPrincipalInfo(principal, principalInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = CreateForMainThreadJSInternal(aCx, aOwningObject, principalInfo, aFactory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -86,9 +86,9 @@ public:
|
||||
IDBFactory** aFactory);
|
||||
|
||||
static nsresult
|
||||
CreateForChromeJS(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aOwningObject,
|
||||
IDBFactory** aFactory);
|
||||
CreateForMainThreadJS(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aOwningObject,
|
||||
IDBFactory** aFactory);
|
||||
|
||||
static nsresult
|
||||
CreateForDatastore(JSContext* aCx,
|
||||
|
@ -582,7 +582,6 @@ IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGlobal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsCallerChrome(), "Only for chrome!");
|
||||
MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL,
|
||||
"Passed object is not a global object!");
|
||||
|
||||
@ -609,9 +608,9 @@ IndexedDatabaseManager::DefineIndexedDB(JSContext* aCx,
|
||||
}
|
||||
|
||||
nsRefPtr<IDBFactory> factory;
|
||||
if (NS_FAILED(IDBFactory::CreateForChromeJS(aCx,
|
||||
aGlobal,
|
||||
getter_AddRefs(factory)))) {
|
||||
if (NS_FAILED(IDBFactory::CreateForMainThreadJS(aCx,
|
||||
aGlobal,
|
||||
getter_AddRefs(factory)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -940,7 +939,7 @@ IndexedDatabaseManager::LoggingModePrefChangedCallback(
|
||||
return;
|
||||
}
|
||||
|
||||
bool useProfiler =
|
||||
bool useProfiler =
|
||||
#if defined(DEBUG) || defined(MOZ_ENABLE_PROFILER_SPS)
|
||||
Preferences::GetBool(kPrefLoggingProfiler);
|
||||
#if !defined(MOZ_ENABLE_PROFILER_SPS)
|
||||
|
@ -332,6 +332,8 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || (buildapp == 'mulet') # Bug 931116 # TC: Bug 1144079 - Re-enable Mulet mochitests and reftests taskcluster-specific disables.
|
||||
[test_request_readyState.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_sandbox.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_setVersion.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_setVersion_abort.html]
|
||||
|
101
dom/indexedDB/test/test_sandbox.html
Normal file
101
dom/indexedDB/test/test_sandbox.html
Normal file
@ -0,0 +1,101 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>indexedDB in JS Sandbox</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"></link>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// This runs inside a same-origin sandbox.
|
||||
// The intent being to show that the data store is the same.
|
||||
function storeValue() {
|
||||
function createDB_inner() {
|
||||
var op = indexedDB.open('db');
|
||||
op.onupgradeneeded = e => {
|
||||
var db = e.target.result;
|
||||
db.createObjectStore('store');
|
||||
};
|
||||
return new Promise(resolve => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
});
|
||||
}
|
||||
|
||||
function add(k, v) {
|
||||
return createDB_inner().then(db => {
|
||||
var tx = db.transaction('store', 'readwrite');
|
||||
var store = tx.objectStore('store');
|
||||
var op = store.add(v, k);
|
||||
return new Promise((resolve, reject) => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
op.onerror = _ => reject(op.error);
|
||||
tx.onabort = _ => reject(tx.error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return add('x', [ 10, {} ])
|
||||
.then(_ => step_done(),
|
||||
_ => ok(false, 'failed to store'));
|
||||
}
|
||||
|
||||
function createDB_outer() {
|
||||
var op = indexedDB.open('db');
|
||||
op.onupgradeneeded = e => {
|
||||
ok(false, 'upgrade should not be needed');
|
||||
var db = e.target.result;
|
||||
db.createObjectStore('store');
|
||||
};
|
||||
return new Promise(resolve => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
});
|
||||
}
|
||||
|
||||
function get(k) {
|
||||
return createDB_outer().then(db => {
|
||||
var tx = db.transaction('store', 'readonly');
|
||||
var store = tx.objectStore('store');
|
||||
var op = store.get(k);
|
||||
return new Promise((resolve, reject) => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
op.onerror = _ => reject(op.error);
|
||||
tx.onabort = _ => reject(tx.error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function runInSandbox(sandbox, testFunc) {
|
||||
is(typeof testFunc, 'function');
|
||||
var resolvePromise;
|
||||
var testPromise = new Promise(r => resolvePromise = r);
|
||||
SpecialPowers.Cu.exportFunction(_ => resolvePromise(), sandbox,
|
||||
{ defineAs: 'step_done' });
|
||||
SpecialPowers.Cu.evalInSandbox('(' + testFunc.toSource() + ')()' +
|
||||
'.then(step_done);', sandbox);
|
||||
return testPromise;
|
||||
}
|
||||
|
||||
// Use the window principal for the sandbox; location.origin is not sufficient.
|
||||
var sb = new SpecialPowers.Cu.Sandbox(window,
|
||||
{ wantGlobalProperties: ['indexedDB'] });
|
||||
|
||||
sb.ok = SpecialPowers.Cu.exportFunction(ok, sb);
|
||||
|
||||
Promise.resolve()
|
||||
.then(_ => runInSandbox(sb, storeValue))
|
||||
.then(_ => get('x'))
|
||||
.then(x => {
|
||||
ok(x, 'a value should be present');
|
||||
is(x.length, 2);
|
||||
is(x[0], 10);
|
||||
is(typeof x[1], 'object');
|
||||
is(Object.keys(x[1]).length, 0);
|
||||
})
|
||||
.then(_ => SimpleTest.finish());
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
78
dom/indexedDB/test/unit/test_sandbox.js
Normal file
78
dom/indexedDB/test/unit/test_sandbox.js
Normal file
@ -0,0 +1,78 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function exerciseInterface() {
|
||||
function DB(name, store) {
|
||||
this.name = name;
|
||||
this.store = store;
|
||||
this._db = this._create();
|
||||
}
|
||||
|
||||
DB.prototype = {
|
||||
_create: function() {
|
||||
var op = indexedDB.open(this.name);
|
||||
op.onupgradeneeded = e => {
|
||||
var db = e.target.result;
|
||||
db.createObjectStore(this.store);
|
||||
};
|
||||
return new Promise(resolve => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
});
|
||||
},
|
||||
|
||||
_result: function(tx, op) {
|
||||
return new Promise((resolve, reject) => {
|
||||
op.onsuccess = e => resolve(e.target.result);
|
||||
op.onerror = () => reject(op.error);
|
||||
tx.onabort = () => reject(tx.error);
|
||||
});
|
||||
},
|
||||
|
||||
get: function(k) {
|
||||
return this._db.then(db => {
|
||||
var tx = db.transaction(this.store, 'readonly');
|
||||
var store = tx.objectStore(this.store);
|
||||
return this._result(tx, store.get(k));
|
||||
});
|
||||
},
|
||||
|
||||
add: function(k, v) {
|
||||
return this._db.then(db => {
|
||||
var tx = db.transaction(this.store, 'readwrite');
|
||||
var store = tx.objectStore(this.store);
|
||||
return this._result(tx, store.add(v, k));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var db = new DB('data', 'base');
|
||||
return db.add('x', [ 10, {} ])
|
||||
.then(_ => db.get('x'))
|
||||
.then(x => {
|
||||
equal(x.length, 2);
|
||||
equal(x[0], 10);
|
||||
equal(typeof x[1], 'object');
|
||||
equal(Object.keys(x[1]).length, 0);
|
||||
});
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_get_profile();
|
||||
|
||||
let Cu = Components.utils;
|
||||
let sb = new Cu.Sandbox('https://www.example.com',
|
||||
{ wantGlobalProperties: ['indexedDB'] });
|
||||
|
||||
sb.equal = equal;
|
||||
var innerPromise = new Promise((resolve, reject) => {
|
||||
sb.test_done = resolve;
|
||||
sb.test_error = reject;
|
||||
});
|
||||
Cu.evalInSandbox('(' + exerciseInterface.toSource() + ')()' +
|
||||
'.then(test_done, test_error);', sb);
|
||||
|
||||
Cu.importGlobalProperties(['indexedDB']);
|
||||
do_test_pending();
|
||||
Promise.all([innerPromise, exerciseInterface()])
|
||||
.then(do_test_finished);
|
||||
}
|
@ -59,6 +59,7 @@ skip-if = toolkit == 'android' # bug 1079278
|
||||
[test_remove_index.js]
|
||||
[test_remove_objectStore.js]
|
||||
[test_request_readyState.js]
|
||||
[test_sandbox.js]
|
||||
[test_setVersion.js]
|
||||
[test_setVersion_abort.js]
|
||||
[test_setVersion_events.js]
|
||||
|
@ -916,7 +916,7 @@ xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj)
|
||||
if (CSS && !dom::CSSBinding::GetConstructorObject(cx, obj))
|
||||
return false;
|
||||
|
||||
if (indexedDB && AccessCheck::isChrome(obj) &&
|
||||
if (indexedDB &&
|
||||
!IndexedDatabaseManager::DefineIndexedDB(cx, obj))
|
||||
return false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user