Skip to content

Commit d02e115

Browse files
authored
Merge pull request #1650 from alexcrichton/less-csp
Use static accessors if possible to get global object
2 parents b64f5c0 + 0b08bba commit d02e115

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

crates/js-sys/src/lib.rs

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4439,7 +4439,55 @@ extern "C" {
44394439
/// This allows access to the global properties and global names by accessing
44404440
/// the `Object` returned.
44414441
pub fn global() -> Object {
4442-
thread_local!(static GLOBAL: Object = {
4442+
thread_local!(static GLOBAL: Object = get_global_object());
4443+
4444+
return GLOBAL.with(|g| g.clone());
4445+
4446+
fn get_global_object() -> Object {
4447+
// This is a bit wonky, but we're basically using `#[wasm_bindgen]`
4448+
// attributes to synthesize imports so we can access properties of the
4449+
// form:
4450+
//
4451+
// * `globalThis.globalThis`
4452+
// * `self.self`
4453+
// * ... (etc)
4454+
//
4455+
// Accessing the global object is not an easy thing to do, and what we
4456+
// basically want is `globalThis` but we can't rely on that existing
4457+
// everywhere. In the meantime we've got the fallbacks mentioned in:
4458+
//
4459+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
4460+
//
4461+
// Note that this is pretty heavy code-size wise but it at least gets
4462+
// the job largely done for now and avoids the `Function` constructor at
4463+
// the end which triggers CSP errors.
4464+
#[wasm_bindgen]
4465+
extern "C" {
4466+
type Global;
4467+
4468+
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = globalThis, js_name = globalThis)]
4469+
fn get_global_this() -> Result<Object, JsValue>;
4470+
4471+
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = self, js_name = self)]
4472+
fn get_self() -> Result<Object, JsValue>;
4473+
4474+
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = window, js_name = window)]
4475+
fn get_window() -> Result<Object, JsValue>;
4476+
4477+
#[wasm_bindgen(getter, catch, static_method_of = Global, js_class = global, js_name = global)]
4478+
fn get_global() -> Result<Object, JsValue>;
4479+
}
4480+
4481+
let static_object = Global::get_global_this()
4482+
.or_else(|_| Global::get_self())
4483+
.or_else(|_| Global::get_window())
4484+
.or_else(|_| Global::get_global());
4485+
if let Ok(obj) = static_object {
4486+
if !obj.is_undefined() {
4487+
return obj;
4488+
}
4489+
}
4490+
44434491
// According to StackOverflow you can access the global object via:
44444492
//
44454493
// const global = Function('return this')();
@@ -4462,9 +4510,7 @@ pub fn global() -> Object {
44624510
Some(this) => this.unchecked_into(),
44634511
None => JsValue::undefined().unchecked_into(),
44644512
}
4465-
});
4466-
4467-
GLOBAL.with(|g| g.clone())
4513+
}
44684514
}
44694515

44704516
macro_rules! arrays {

tests/wasm/imports.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ exports.return_three = function() { return 3; };
6969

7070
exports.underscore = function(x) {};
7171

72-
exports.self = function() { return 2; };
72+
exports.pub = function() { return 2; };
7373

7474
exports.bar = { foo: 3 };
7575

tests/wasm/imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern "C" {
3030

3131
fn underscore(_: u8);
3232

33-
#[wasm_bindgen(js_name = self)]
33+
#[wasm_bindgen(js_name = pub)]
3434
fn js_function_named_rust_keyword() -> u32;
3535

3636
type bar;

0 commit comments

Comments
 (0)