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:
Julian Descottes 2022-09-20 13:29:50 +00:00
parent 15d5e42d5f
commit f52f1c98c3
2 changed files with 58 additions and 18 deletions

View file

@ -85,6 +85,19 @@ class Realm {
throw new Error("Not implemented"); 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. * Remove the reference corresponding to the provided unique handle.
* *
@ -187,16 +200,8 @@ class WindowRealm extends Realm {
return this.#window.origin; return this.#window.origin;
} }
#cloneAsDebuggerObject(obj) { #createDebuggerObject(obj) {
// To use an object created in the priviledged Debugger compartment from return this.#globalObjectReference.makeDebuggeeValue(obj);
// 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);
} }
#createSandbox() { #createSandbox() {
@ -211,6 +216,20 @@ class WindowRealm extends Realm {
return new Cu.Sandbox(win, opts); 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. * 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 expression = `(${functionDeclaration}).apply(__bidi_this, __bidi_args)`;
const args = this.cloneIntoRealm([]);
for (const arg of functionArguments) {
args.push(arg);
}
return this.#globalObjectReference.executeInGlobalWithBindings( return this.#globalObjectReference.executeInGlobalWithBindings(
expression, expression,
{ {
__bidi_args: this.#cloneAsDebuggerObject(functionArguments), __bidi_args: this.#createDebuggerObject(args),
__bidi_this: this.#cloneAsDebuggerObject(thisParameter), __bidi_this: this.#createDebuggerObject(thisParameter),
}, },
{ {
url: this.#window.document.baseURI, url: this.#window.document.baseURI,

View file

@ -137,6 +137,8 @@ function checkDateTimeString(dateString) {
* *
* @see https://w3c.github.io/webdriver-bidi/#deserialize-value-list * @see https://w3c.github.io/webdriver-bidi/#deserialize-value-list
* *
* @param {Realm} realm
* The Realm in which the value is deserialized.
* @param {Array} serializedValueList * @param {Array} serializedValueList
* List of serialized values. * List of serialized values.
* *
@ -165,6 +167,8 @@ function deserializeValueList(realm, serializedValueList) {
* *
* @see https://w3c.github.io/webdriver-bidi/#deserialize-key-value-list * @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 * @param {Array} serializedKeyValueList
* List of serialized key-value. * List of serialized key-value.
* *
@ -206,6 +210,8 @@ function deserializeKeyValueList(realm, serializedKeyValueList) {
* *
* @see https://w3c.github.io/webdriver-bidi/#deserialize-local-value * @see https://w3c.github.io/webdriver-bidi/#deserialize-local-value
* *
* @param {Realm} realm
* The Realm in which the value is deserialized.
* @param {Object} serializedValue * @param {Object} serializedValue
* Value of any type to be deserialized. * Value of any type to be deserialized.
* *
@ -279,17 +285,25 @@ function deserialize(realm, serializedValue) {
// Non-primitive protocol values // Non-primitive protocol values
case "array": case "array":
return deserializeValueList(realm, value); const array = realm.cloneIntoRealm([]);
deserializeValueList(realm, value).forEach(v => array.push(v));
return array;
case "date": case "date":
// We want to support only Date Time String format, // We want to support only Date Time String format,
// check if the value follows it. // check if the value follows it.
checkDateTimeString(value); checkDateTimeString(value);
return new Date(value); return realm.cloneIntoRealm(new Date(value));
case "map": 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": 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": case "regexp":
lazy.assert.object( lazy.assert.object(
value, value,
@ -307,14 +321,16 @@ function deserialize(realm, serializedValue) {
); );
} }
try { try {
return new RegExp(pattern, flags); return realm.cloneIntoRealm(new RegExp(pattern, flags));
} catch (e) { } catch (e) {
throw new lazy.error.InvalidArgumentError( throw new lazy.error.InvalidArgumentError(
`Failed to deserialize value as RegExp: ${value}` `Failed to deserialize value as RegExp: ${value}`
); );
} }
case "set": 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}`); lazy.logger.warn(`Unsupported type for local value ${type}`);