Merge pull request #1650 from alexcrichton/less-csp

Use static accessors if possible to get global object
This commit is contained in:
Nick Fitzgerald 2019-07-10 09:37:56 -07:00 committed by GitHub
commit d02e115fd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 6 deletions

View File

@ -4439,7 +4439,55 @@ extern "C" {
/// This allows access to the global properties and global names by accessing
/// the `Object` returned.
pub fn global() -> Object {
thread_local!(static GLOBAL: Object = {
thread_local!(static GLOBAL: Object = get_global_object());
return GLOBAL.with(|g| g.clone());
fn get_global_object() -> Object {
// This is a bit wonky, but we're basically using `#[wasm_bindgen]`
// attributes to synthesize imports so we can access properties of the
// form:
//
// * `globalThis.globalThis`
// * `self.self`
// * ... (etc)
//
// Accessing the global object is not an easy thing to do, and what we
// basically want is `globalThis` but we can't rely on that existing
// everywhere. In the meantime we've got the fallbacks mentioned in:
//
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
//
// Note that this is pretty heavy code-size wise but it at least gets
// the job largely done for now and avoids the `Function` constructor at
// the end which triggers CSP errors.
#[wasm_bindgen]
extern "C" {
type Global;
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = globalThis, js_name = globalThis)]
fn get_global_this() -> Result<Object, JsValue>;
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = self, js_name = self)]
fn get_self() -> Result<Object, JsValue>;
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = window, js_name = window)]
fn get_window() -> Result<Object, JsValue>;
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = global, js_name = global)]
fn get_global() -> Result<Object, JsValue>;
}
let static_object = Global::get_global_this()
.or_else(|_| Global::get_self())
.or_else(|_| Global::get_window())
.or_else(|_| Global::get_global());
if let Ok(obj) = static_object {
if !obj.is_undefined() {
return obj;
}
}
// According to StackOverflow you can access the global object via:
//
// const global = Function('return this')();
@ -4462,9 +4510,7 @@ pub fn global() -> Object {
Some(this) => this.unchecked_into(),
None => JsValue::undefined().unchecked_into(),
}
});
GLOBAL.with(|g| g.clone())
}
}
macro_rules! arrays {

View File

@ -69,7 +69,7 @@ exports.return_three = function() { return 3; };
exports.underscore = function(x) {};
exports.self = function() { return 2; };
exports.pub = function() { return 2; };
exports.bar = { foo: 3 };

View File

@ -30,7 +30,7 @@ extern "C" {
fn underscore(_: u8);
#[wasm_bindgen(js_name = self)]
#[wasm_bindgen(js_name = pub)]
fn js_function_named_rust_keyword() -> u32;
type bar;