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
	
	 Julian Descottes
						Julian Descottes