Bug 1551282 Comment 14 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

There are two related problems this patch is trying to address.  The first, and
simpler, one is bug 1553436: there are websites that use existing variables and
functions named "u2f" and adding a non-replaceable readonly property with that
name on Window breaks them.  The fix for this is straightforward: mark the
property [Replaceable].

The second problem, covered by bug 1551282, involves sites that use the Google
U2F polyfill.  The relevant parts of that polyfill look like this:

  'use strict';
  var u2f = u2f || {};
  u2f.register = some_function_that_only_works_right_in_Chrome;
  u2f.sign = some_function_that_only_works_right_in_Chrome;

The failure mode for that code before this fix is that the assignment to "u2f"
throws because it's a readonly property and we're in strict mode, so any code
the page concatenates in the same file after the polyfill does not get run.
That's what bug 1551282 is about.  The [Replaceable] annotation fixes that
issue, because now the polyfill gets the value of window.u2f and then redefines
the property (via the [Replaceable] setter) to be a value property with that
value.  So far, so good.

But then we need to prevent the sets of u2f.register
and u2f.sign from taking effect, because if they are allowed to happen, the
actual sign/register functionality on the page will not work in Firefox.  We
can't just make the properties readonly, because then the sets will throw due
to being in strict mode, and we still have bug 1551282.  The proposed fix is to
make these accessor properties with a no-op setter, which is exactly what
[LenientSetter] gives us.

The remaining question is what values the getters for the "register" and "sign"
properties should return.  To preserve the ability to do
u2f.register()/u2f.sign(), we want to return callable values, and we want the
call to apply Web IDL argument processing to the arguments.  The simplest way
to do this in implementation terms is to return IDL objects with a legacycaller
on them.  The other option would be to return actual JS functions defined via a
JSNative that manually implements the Web IDL argument semantics.  While this
is arguably closer to the spec for this, I doubt anyone really depends on these
objects actually being Function objects, and it would be a lot riskier to
backport that sort of handwritten binding code to beta, much less release, as I
expect we will need to do with this patch.
There are two related problems this patch is trying to address.  The first, and
simpler, one is bug 1553436: there are websites that use existing variables and
functions named "u2f" and adding a non-replaceable readonly property with that
name on Window breaks them.  The fix for this is straightforward: mark the
property [Replaceable].

The second problem, covered by bug 1551282, involves sites that use the Google
U2F polyfill.  The relevant parts of that polyfill look like this:
```
  'use strict';
  var u2f = u2f || {};
  u2f.register = some_function_that_only_works_right_in_Chrome;
  u2f.sign = some_function_that_only_works_right_in_Chrome;
```
The failure mode for that code before this fix is that the assignment to "u2f"
throws because it's a readonly property and we're in strict mode, so any code
the page concatenates in the same file after the polyfill does not get run.
That's what bug 1551282 is about.  The [Replaceable] annotation fixes that
issue, because now the polyfill gets the value of window.u2f and then redefines
the property (via the [Replaceable] setter) to be a value property with that
value.  So far, so good.

But then we need to prevent the sets of u2f.register
and u2f.sign from taking effect, because if they are allowed to happen, the
actual sign/register functionality on the page will not work in Firefox.  We
can't just make the properties readonly, because then the sets will throw due
to being in strict mode, and we still have bug 1551282.  The proposed fix is to
make these accessor properties with a no-op setter, which is exactly what
[LenientSetter] gives us.

The remaining question is what values the getters for the "register" and "sign"
properties should return.  To preserve the ability to do
u2f.register()/u2f.sign(), we want to return callable values, and we want the
call to apply Web IDL argument processing to the arguments.  The simplest way
to do this in implementation terms is to return IDL objects with a legacycaller
on them.  The other option would be to return actual JS functions defined via a
JSNative that manually implements the Web IDL argument semantics.  While this
is arguably closer to the spec for this, I doubt anyone really depends on these
objects actually being Function objects, and it would be a lot riskier to
backport that sort of handwritten binding code to beta, much less release, as I
expect we will need to do with this patch.

Back to Bug 1551282 Comment 14