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");
|
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,
|
||||||
|
|
|
||||||
|
|
@ -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}`);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue