mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-20 00:20:37 +00:00
Bug 1186213 - Add an API to deep-freeze the result of Cu.cloneInto. r=gkrizsanits
This commit is contained in:
parent
06c3dd1246
commit
4dac367856
@ -271,7 +271,17 @@ StackScopedClone(JSContext* cx, StackScopedCloneOptions& options,
|
||||
}
|
||||
|
||||
// Now recreate the clones in the target compartment.
|
||||
return buffer.read(cx, val, &gStackScopedCloneCallbacks, &data);
|
||||
if (!buffer.read(cx, val, &gStackScopedCloneCallbacks, &data))
|
||||
return false;
|
||||
|
||||
// Deep-freeze if requested.
|
||||
if (options.deepFreeze && val.isObject()) {
|
||||
RootedObject obj(cx, &val.toObject());
|
||||
if (!JS_DeepFreezeObject(cx, obj))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Note - This function mirrors the logic of CheckPassToChrome in
|
||||
|
@ -3567,11 +3567,13 @@ public:
|
||||
: OptionsBase(cx, options)
|
||||
, wrapReflectors(false)
|
||||
, cloneFunctions(false)
|
||||
, deepFreeze(false)
|
||||
{ }
|
||||
|
||||
virtual bool Parse() {
|
||||
return ParseBoolean("wrapReflectors", &wrapReflectors) &&
|
||||
ParseBoolean("cloneFunctions", &cloneFunctions);
|
||||
ParseBoolean("cloneFunctions", &cloneFunctions) &&
|
||||
ParseBoolean("deepFreeze", &deepFreeze);
|
||||
}
|
||||
|
||||
// When a reflector is encountered, wrap it rather than aborting the clone.
|
||||
@ -3580,6 +3582,9 @@ public:
|
||||
// When a function is encountered, clone it (exportFunction-style) rather than
|
||||
// aborting the clone.
|
||||
bool cloneFunctions;
|
||||
|
||||
// If true, the resulting object is deep-frozen after being cloned.
|
||||
bool deepFreeze;
|
||||
};
|
||||
|
||||
JSObject*
|
||||
|
33
js/xpconnect/tests/unit/test_deepFreezeClone.js
Normal file
33
js/xpconnect/tests/unit/test_deepFreezeClone.js
Normal file
@ -0,0 +1,33 @@
|
||||
const Cu = Components.utils;
|
||||
|
||||
function checkThrows(f, rgxp) { try { f(); do_check_false(); } catch (e) { do_check_true(rgxp.test(e)); } }
|
||||
|
||||
var o = { foo: 42, bar : { tick: 'tock' } };
|
||||
function checkClone(clone, frozen) {
|
||||
var waived = Cu.waiveXrays(clone);
|
||||
function touchFoo() { "use strict"; waived.foo = 12; do_check_eq(waived.foo, 12); }
|
||||
function touchBar() { "use strict"; waived.bar.tick = 'tack'; do_check_eq(waived.bar.tick, 'tack'); }
|
||||
function addProp() { "use strict"; waived.newProp = 100; do_check_eq(waived.newProp, 100); }
|
||||
if (!frozen) {
|
||||
touchFoo();
|
||||
touchBar();
|
||||
addProp();
|
||||
} else {
|
||||
checkThrows(touchFoo, /read-only/);
|
||||
checkThrows(touchBar, /read-only/);
|
||||
checkThrows(addProp, /extensible/);
|
||||
}
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(waived, 'foo');
|
||||
do_check_eq(desc.writable, !frozen);
|
||||
do_check_eq(desc.configurable, !frozen);
|
||||
desc = Object.getOwnPropertyDescriptor(waived.bar, 'tick');
|
||||
do_check_eq(desc.writable, !frozen);
|
||||
do_check_eq(desc.configurable, !frozen);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
var sb = new Cu.Sandbox(null);
|
||||
checkClone(Cu.waiveXrays(Cu.cloneInto(o, sb)), false);
|
||||
checkClone(Cu.cloneInto(o, sb, { deepFreeze: true }), true);
|
||||
}
|
@ -62,6 +62,7 @@ support-files =
|
||||
[test_bug1170311.js]
|
||||
[test_bug_442086.js]
|
||||
[test_callFunctionWithAsyncStack.js]
|
||||
[test_deepFreezeClone.js]
|
||||
[test_file.js]
|
||||
[test_blob.js]
|
||||
[test_blob2.js]
|
||||
|
Loading…
x
Reference in New Issue
Block a user