Skip to content

Commit d746e14

Browse files
committed
Repro for RFC#1070 - none of the default globals are accessible in eval-mode
1 parent e9a718c commit d746e14

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

packages/@ember/-internals/glimmer/tests/integration/components/runtime-template-compiler-explicit-test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { template } from '@ember/template-compiler/runtime';
2+
import { ALLOWED_GLOBALS } from '@ember/template-compiler';
23
import { RenderingTestCase, defineSimpleModifier, moduleFor } from 'internal-test-helpers';
34
import GlimmerishComponent from '../../utils/glimmerish-component';
45
import { on } from '@ember/modifier/on';
@@ -336,3 +337,25 @@ moduleFor(
336337
}
337338
}
338339
);
340+
341+
moduleFor(
342+
'Strict Mode - Runtime Template Compiler (explicit) - allowed globals from RFC#1070',
343+
class AllowedGlobalsTest extends RenderingTestCase {
344+
static {
345+
for (let globalName of ALLOWED_GLOBALS) {
346+
if (!(globalName in globalThis)) continue;
347+
348+
// @ts-expect-error - this *is* generally unsafe
349+
this.prototype[`@test Can use ${globalName}`] = async function () {
350+
await this.renderComponentModule(() => {
351+
return template(`{{if ${globalName} "exists"}}`, {
352+
scope: () => ({}),
353+
});
354+
});
355+
356+
this.assertStableRerender();
357+
};
358+
}
359+
}
360+
}
361+
);

packages/@ember/-internals/glimmer/tests/integration/components/runtime-template-compiler-implicit-test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { template } from '@ember/template-compiler/runtime';
2+
import { ALLOWED_GLOBALS } from '@ember/template-compiler';
23
import { RenderingTestCase, defineSimpleModifier, moduleFor } from 'internal-test-helpers';
34
import GlimmerishComponent from '../../utils/glimmerish-component';
45
import { on } from '@ember/modifier/on';
@@ -466,6 +467,30 @@ moduleFor(
466467
}
467468
);
468469

470+
moduleFor(
471+
'Strict Mode - Runtime Template Compiler (implicit) - allowed globals from RFC#1070',
472+
class AllowedGlobalsTest extends RenderingTestCase {
473+
static {
474+
for (let globalName of ALLOWED_GLOBALS) {
475+
if (!(globalName in globalThis)) continue;
476+
477+
// @ts-expect-error - this *is* generally unsafe
478+
AllowedGlobalsTest.prototype[`@test Can use ${globalName}`] = async function () {
479+
await this.renderComponentModule(() => {
480+
return template(`{{if ${globalName} "exists"}}`, {
481+
eval() {
482+
return eval(arguments[0]);
483+
},
484+
});
485+
});
486+
487+
this.assertStableRerender();
488+
};
489+
}
490+
}
491+
}
492+
);
493+
469494
/**
470495
* This function is used to hide a variable from the transpiler, so that it
471496
* doesn't get removed as "unused". It does not actually do anything with the
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
export * from './lib/public-api';
2+
3+
export { ALLOWED_GLOBALS } from './lib/plugins/allowed-globals';
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @private
3+
*
4+
* RFC: https://github.com/emberjs/rfcs/pull/1070
5+
*
6+
* Criteria for inclusion in this list:
7+
*
8+
* Any of:
9+
* - begins with an uppercase letter
10+
* - guaranteed to never be added to glimmer as a keyword (e.g.: globalThis)
11+
*
12+
* And:
13+
* - must not need new to invoke
14+
* - must not require lifetime management (e.g.: setTimeout)
15+
* - must not be a single-word lower-case API, because of potential collision with future new HTML elements
16+
* - if the API is a function, the return value should not be a promise
17+
* - must be one one of these lists:
18+
* - https://tc39.es/ecma262/#sec-global-object
19+
* - https://tc39.es/ecma262/#sec-function-properties-of-the-global-object
20+
* - https://html.spec.whatwg.org/multipage/nav-history-apis.html#window
21+
* - https://html.spec.whatwg.org/multipage/indices.html#all-interfaces
22+
* - https://html.spec.whatwg.org/multipage/webappapis.html
23+
*/
24+
export const ALLOWED_GLOBALS = new Set([
25+
// ////////////////
26+
// namespaces
27+
// ////////////////
28+
// TC39
29+
'globalThis',
30+
'Atomics',
31+
'JSON',
32+
'Math',
33+
'Reflect',
34+
// WHATWG
35+
'localStorage',
36+
'sessionStorage',
37+
'URL',
38+
// ////////////////
39+
// functions / utilities
40+
// ////////////////
41+
// TC39
42+
'isNaN',
43+
'isFinite',
44+
'parseInt',
45+
'parseFloat',
46+
'decodeURI',
47+
'decodeURIComponent',
48+
'encodeURI',
49+
'encodeURIComponent',
50+
// WHATWG
51+
'postMessage',
52+
'structuredClone',
53+
// ////////////////
54+
// new-less Constructors (still functions)
55+
// ////////////////
56+
// TC39
57+
'Array', // different behavior from (array)
58+
'BigInt',
59+
'Boolean',
60+
'Date',
61+
'Number',
62+
'Object', // different behavior from (hash)
63+
'String',
64+
// ////////////////
65+
// Values
66+
// ////////////////
67+
// TC39
68+
'Infinity',
69+
'NaN',
70+
// WHATWG
71+
'isSecureContext',
72+
]);

0 commit comments

Comments
 (0)