Bug 1506614 - Fix ChromeUtils.shallowClone behavior on objects with getters and/or setters. r=kmag

Differential Revision: https://phabricator.services.mozilla.com/D11655

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Luca Greco 2018-12-17 15:19:27 +00:00
Родитель a5beaa5c57
Коммит 420d7d08e5
3 изменённых файлов: 52 добавлений и 3 удалений

Просмотреть файл

@ -185,6 +185,7 @@ namespace dom {
JS::Rooted<JS::IdVector> ids(cx, JS::IdVector(cx));
JS::AutoValueVector values(cx);
JS::AutoIdVector valuesIds(cx);
{
JS::RootedObject obj(cx, js::CheckedUnwrap(aObj));
@ -200,7 +201,8 @@ namespace dom {
JSAutoRealm ar(cx, obj);
if (!JS_Enumerate(cx, obj, &ids) || !values.reserve(ids.length())) {
if (!JS_Enumerate(cx, obj, &ids) || !values.reserve(ids.length()) ||
!valuesIds.reserve(ids.length())) {
return;
}
@ -214,6 +216,7 @@ namespace dom {
if (desc.setter() || desc.getter()) {
continue;
}
valuesIds.infallibleAppend(id);
values.infallibleAppend(desc.value());
}
}
@ -237,8 +240,8 @@ namespace dom {
JS::RootedValue value(cx);
JS::RootedId id(cx);
for (uint32_t i = 0; i < ids.length(); i++) {
id = ids[i];
for (uint32_t i = 0; i < valuesIds.length(); i++) {
id = valuesIds[i];
value = values[i];
JS_MarkCrossZoneId(cx, id);

Просмотреть файл

@ -0,0 +1,45 @@
"use strict";
add_task(function test_shallowclone() {
// Check that shallow cloning an object with regular properties,
// results into a new object with all properties from the source object.
const fullyCloneableObject = {
numProp: 123,
strProp: "str",
boolProp: true,
arrayProp: [{item1: "1", item2: "2"}],
fnProp() { return "fn result"; },
promise: Promise.resolve("promised-value"),
weakmap: new WeakMap(),
proxy: new Proxy({}, {}),
};
let clonedObject = ChromeUtils.shallowClone(fullyCloneableObject);
Assert.deepEqual(clonedObject, fullyCloneableObject,
"Got the expected cloned object for an object with regular properties");
// Check that shallow cloning an object with getters and setters properties,
// results into a new object without all the properties from the source object excluded
// its getters and setters.
const objectWithGetterAndSetter = {
get myGetter() { return "getter result"; },
set mySetter(v) {},
myFunction() { return "myFunction result"; },
};
clonedObject = ChromeUtils.shallowClone(objectWithGetterAndSetter);
Assert.deepEqual(clonedObject, {
myFunction: objectWithGetterAndSetter.myFunction,
}, "Got the expected cloned object for an object with getters and setters");
// Check that shallow cloning a proxy object raises the expected exception..
const proxyObject = new Proxy(fullyCloneableObject, {});
Assert.throws(
() => { ChromeUtils.shallowClone(proxyObject); },
/Shallow cloning a proxy object is not allowed/,
"Got the expected error on ChromeUtils.shallowClone called on a proxy object");
});

Просмотреть файл

@ -54,6 +54,7 @@ head = head_xml.js
[test_xmlserializer.js]
[test_cancelPrefetch.js]
[test_chromeutils_base64.js]
[test_chromeutils_shallowclone.js]
[test_generate_xpath.js]
head = head_xml.js
[test_js_dev_error_interceptor.js]