claudepache / es-legacy-function-reflection

JavaScript: Legacy reflection features on functions needed for web compatibility
Creative Commons Zero v1.0 Universal
3 stars 2 forks source link

Test which restrictions are currently implemented in browsers #1

Closed claudepache closed 4 years ago

claudepache commented 5 years ago

Current implementations may or may not add restrictions on the following kinds of (mostly post-ES3) function:

Moreover, there are two kinds of restriction that may apply:

  1. Attempting to access the caller or the arguments property on such a function object:
    1. throws a TypeError, or
    2. returns null or undefined.
  2. When the caller property is about to return such a function object:
    1. throws a TypeError, or
    2. returns null or undefined.
littledan commented 5 years ago

Hmm, it'd be interesting to see how these restrictions are implemented across various JS engines. This could be tested via eshost and jsvu, if anyone is interested.

claudepache commented 5 years ago

Preliminary tests on Firefox, Chrome, Safari and Edge:

  1. When attempting to access caller or arguments on:
    • a strict, built-in, bound, arrow, generator, async function: everyone: throw a TypeError
    • an object method or getter: Firefox, Chrome, Safari: throw a TypeError
    • a proxied function: Firefox: throw a TypeError
  2. When caller is about to return:
    • a strict function: Firefox, Edge, Safari: throw a TypeError; Chrome: return null
    • a built-in function: Firefox, Chrome, Safari: return null ; Edge: return that function đź‘Ž
    • a generator or an async function : Safari: throw a TypeError

Note: When testing Safari, we should be aware that, because of PTC, the caller may not be the one that you think:

function getCaller() { return getCaller.caller }

;(function() { "use strict"; var r = getCaller(); return r })()
// TypeError: Function.caller used to retrieve strict caller

;(function() { "use strict"; return getCaller() })()
// PTC applies; no error (unless executed from within a strict-mode environment, of course)
claudepache commented 5 years ago

So, roughly, for case 1, we can distinguish two classes of functions:

  1. “ES3 functions” (e.g. non-strict functions constructed with the ”function” keyword) — accessing .arguments or .caller property on those functions is allowed;
  2. other functions — attempting to access .arguments or .caller on those functions throws a TypeError.

Edge treats methods and getters in object literals as “ES3 functions”, other engines as “other functions”.

And for case 2, we can distinguish three or four classes of functions:

  1. sloppy-mode functions — revealing them through .caller is allowed;
  2. strict-mode functions — revealing them through .caller is forbidden: either throw a TypeErrror or return null;
    • Safari does also throw a TypeError for generators and async functions;
  3. built-in functions — revealing them through .caller is either forbidden (returning null); or allowed (which is objectionable).