forked from mirrors/gecko-dev
Bug 1788861 - [bidi] Deserialization of remote references should not create new objects r=Sasha,webdriver-reviewers,whimboo
Depends on D156691 Differential Revision: https://phabricator.services.mozilla.com/D156717
This commit is contained in:
parent
15d5e42d5f
commit
f52f1c98c3
2 changed files with 58 additions and 18 deletions
|
|
@ -85,6 +85,19 @@ class Realm {
|
|||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the provided object can be used within this realm.
|
||||
|
||||
* @param {Object} object
|
||||
* Any non-primitive object.
|
||||
|
||||
* @return {Object}
|
||||
* An object usable in the current realm.
|
||||
*/
|
||||
cloneIntoRealm(obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the reference corresponding to the provided unique handle.
|
||||
*
|
||||
|
|
@ -187,16 +200,8 @@ class WindowRealm extends Realm {
|
|||
return this.#window.origin;
|
||||
}
|
||||
|
||||
#cloneAsDebuggerObject(obj) {
|
||||
// To use an object created in the priviledged Debugger compartment from
|
||||
// the content compartment, we need to first clone it into the target
|
||||
// compartment and then retrieve the corresponding Debugger.Object wrapper.
|
||||
const proxyObject = Cu.cloneInto(
|
||||
obj,
|
||||
this.#globalObjectReference.unsafeDereference()
|
||||
);
|
||||
|
||||
return this.#globalObjectReference.makeDebuggeeValue(proxyObject);
|
||||
#createDebuggerObject(obj) {
|
||||
return this.#globalObjectReference.makeDebuggeeValue(obj);
|
||||
}
|
||||
|
||||
#createSandbox() {
|
||||
|
|
@ -211,6 +216,20 @@ class WindowRealm extends Realm {
|
|||
return new Cu.Sandbox(win, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the provided object into the scope of this Realm (either a window
|
||||
* global, or a sandbox).
|
||||
*
|
||||
* @param {Object} obj
|
||||
* Any non-primitive object.
|
||||
*
|
||||
* @return {Object}
|
||||
* The cloned object.
|
||||
*/
|
||||
cloneIntoRealm(obj) {
|
||||
return Cu.cloneInto(obj, this.#globalObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a provided expression in the context of the current realm.
|
||||
*
|
||||
|
|
@ -254,11 +273,16 @@ class WindowRealm extends Realm {
|
|||
) {
|
||||
const expression = `(${functionDeclaration}).apply(__bidi_this, __bidi_args)`;
|
||||
|
||||
const args = this.cloneIntoRealm([]);
|
||||
for (const arg of functionArguments) {
|
||||
args.push(arg);
|
||||
}
|
||||
|
||||
return this.#globalObjectReference.executeInGlobalWithBindings(
|
||||
expression,
|
||||
{
|
||||
__bidi_args: this.#cloneAsDebuggerObject(functionArguments),
|
||||
__bidi_this: this.#cloneAsDebuggerObject(thisParameter),
|
||||
__bidi_args: this.#createDebuggerObject(args),
|
||||
__bidi_this: this.#createDebuggerObject(thisParameter),
|
||||
},
|
||||
{
|
||||
url: this.#window.document.baseURI,
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ function checkDateTimeString(dateString) {
|
|||
*
|
||||
* @see https://w3c.github.io/webdriver-bidi/#deserialize-value-list
|
||||
*
|
||||
* @param {Realm} realm
|
||||
* The Realm in which the value is deserialized.
|
||||
* @param {Array} serializedValueList
|
||||
* List of serialized values.
|
||||
*
|
||||
|
|
@ -165,6 +167,8 @@ function deserializeValueList(realm, serializedValueList) {
|
|||
*
|
||||
* @see https://w3c.github.io/webdriver-bidi/#deserialize-key-value-list
|
||||
*
|
||||
* @param {Realm} realm
|
||||
* The Realm in which the value is deserialized.
|
||||
* @param {Array} serializedKeyValueList
|
||||
* List of serialized key-value.
|
||||
*
|
||||
|
|
@ -206,6 +210,8 @@ function deserializeKeyValueList(realm, serializedKeyValueList) {
|
|||
*
|
||||
* @see https://w3c.github.io/webdriver-bidi/#deserialize-local-value
|
||||
*
|
||||
* @param {Realm} realm
|
||||
* The Realm in which the value is deserialized.
|
||||
* @param {Object} serializedValue
|
||||
* Value of any type to be deserialized.
|
||||
*
|
||||
|
|
@ -279,17 +285,25 @@ function deserialize(realm, serializedValue) {
|
|||
|
||||
// Non-primitive protocol values
|
||||
case "array":
|
||||
return deserializeValueList(realm, value);
|
||||
const array = realm.cloneIntoRealm([]);
|
||||
deserializeValueList(realm, value).forEach(v => array.push(v));
|
||||
return array;
|
||||
case "date":
|
||||
// We want to support only Date Time String format,
|
||||
// check if the value follows it.
|
||||
checkDateTimeString(value);
|
||||
|
||||
return new Date(value);
|
||||
return realm.cloneIntoRealm(new Date(value));
|
||||
case "map":
|
||||
return new Map(deserializeKeyValueList(realm, value));
|
||||
const map = realm.cloneIntoRealm(new Map());
|
||||
deserializeKeyValueList(realm, value).forEach(([k, v]) => map.set(k, v));
|
||||
return map;
|
||||
case "object":
|
||||
return Object.fromEntries(deserializeKeyValueList(realm, value));
|
||||
const object = realm.cloneIntoRealm({});
|
||||
deserializeKeyValueList(realm, value).forEach(
|
||||
([k, v]) => (object[k] = v)
|
||||
);
|
||||
return object;
|
||||
case "regexp":
|
||||
lazy.assert.object(
|
||||
value,
|
||||
|
|
@ -307,14 +321,16 @@ function deserialize(realm, serializedValue) {
|
|||
);
|
||||
}
|
||||
try {
|
||||
return new RegExp(pattern, flags);
|
||||
return realm.cloneIntoRealm(new RegExp(pattern, flags));
|
||||
} catch (e) {
|
||||
throw new lazy.error.InvalidArgumentError(
|
||||
`Failed to deserialize value as RegExp: ${value}`
|
||||
);
|
||||
}
|
||||
case "set":
|
||||
return new Set(deserializeValueList(realm, value));
|
||||
const set = realm.cloneIntoRealm(new Set());
|
||||
deserializeValueList(realm, value).forEach(v => set.add(v));
|
||||
return set;
|
||||
}
|
||||
|
||||
lazy.logger.warn(`Unsupported type for local value ${type}`);
|
||||
|
|
|
|||
Loading…
Reference in a new issue