Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Alex Vincent
    <script>
"use strict"
function A() {}
    </script>
    <script>
function B() {}
    </script>
    <script>
window.onload = function() {
    let a = Reflect.ownKeys(A);
    let b = Reflect.ownKeys(B);
    document.getElementById("output").value = (a.includes("arguments") === b.includes("arguments"));
}
    </script>

Mozilla Firefox reports true. Google Chrome and node.js report false.  Which one is correct?

I looked through Mozilla's Bugzilla, Google Chrome's Monorail, and the ES7 spec to try figuring this out.  The closest I could get was section 9.2.7 of the ES7 spec. [1]

Right now I have an inadvertent mix of strict code / non-strict code in my membrane, and this difference is causing my most recent patch to fail tests in nodejs and Google Chrome, and to pass in Mozilla Firefox.  In Chrome and nodejs, I get:

TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'

If it turns out Google & nodejs are correct, this could be an issue going forward:  I can't control whether my membrane library's users are running strict mode code or not... likewise, I don't know if my code should be consistently strict mode or consistently non-strict.  (I feel that a mix is not good, except for finding bugs like this...)

My apologies for treating this list as a help forum, but I'm just not sure where else to go...
--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Caitlin Potter

This forbids functions in strict code from having own properties "caller" or "arguments". Newer function kinds have these restrictions in sloppy mode.

AddRestricted... adds the accessor which makes getting/setting "caller" or "arguments" throw, but is per spec only performed on intrinsics (like %FunctionPrototype%).

So unfortunately, this is something your membrane would need to be aware of and work around. Mozilla's approach violates ECMAScript's forbidden extensions and can't be considered "correct"


Sent from my iPhone
On Sep 5, 2016, at 8:54 PM, Alex Vincent <[hidden email]> wrote:

    <script>
"use strict"
function A() {}
    </script>
    <script>
function B() {}
    </script>
    <script>
window.onload = function() {
    let a = Reflect.ownKeys(A);
    let b = Reflect.ownKeys(B);
    document.getElementById("output").value = (a.includes("arguments") === b.includes("arguments"));
}
    </script>

Mozilla Firefox reports true. Google Chrome and node.js report false.  Which one is correct?

I looked through Mozilla's Bugzilla, Google Chrome's Monorail, and the ES7 spec to try figuring this out.  The closest I could get was section 9.2.7 of the ES7 spec. [1]

Right now I have an inadvertent mix of strict code / non-strict code in my membrane, and this difference is causing my most recent patch to fail tests in nodejs and Google Chrome, and to pass in Mozilla Firefox.  In Chrome and nodejs, I get:

TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'

If it turns out Google & nodejs are correct, this could be an issue going forward:  I can't control whether my membrane library's users are running strict mode code or not... likewise, I don't know if my code should be consistently strict mode or consistently non-strict.  (I feel that a mix is not good, except for finding bugs like this...)

My apologies for treating this list as a help forum, but I'm just not sure where else to go...
--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Oriol _
> Mozilla's approach violates ECMAScript's forbidden extensions and can't be considered "correct"

Why? The spec forbids adding "caller" or "arguments" in strict mode. I think it does not enforce adding them in sloppy mode.

Chrome seems to add them only in sloppy mode, and Firefox to never add them. So I think both follow the spec.

- Oriol

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Mark S. Miller-2
In reply to this post by Caitlin Potter
Besides those two, the only other reference to AddRestrictedFunctionProperties is <http://www.ecma-international.org/ecma-262/7.0/#sec-createintrinsics> step 12:

12. Perform AddRestrictedFunctionProperties(funcProtorealmRec).

So .caller and .arguments must now exist as poisoned on (the intrinsic normally bound to) Function.prototype . So, besides Function.prototype, they may only appear on old-style sloppy functions; nowhere else.



On Mon, Sep 5, 2016 at 6:09 PM, Caitlin Potter <[hidden email]> wrote:

This forbids functions in strict code from having own properties "caller" or "arguments". Newer function kinds have these restrictions in sloppy mode.

AddRestricted... adds the accessor which makes getting/setting "caller" or "arguments" throw, but is per spec only performed on intrinsics (like %FunctionPrototype%).

So unfortunately, this is something your membrane would need to be aware of and work around. Mozilla's approach violates ECMAScript's forbidden extensions and can't be considered "correct"

This result by itself does not demonstrate that Mozilla or v8 are either conformant or non-conformant. By the spec, A must not have its own .caller and .arguments -- it must only inherit these from Function.prototype. B, being sloppy, may or may not.

 


Sent from my iPhone
On Sep 5, 2016, at 8:54 PM, Alex Vincent <[hidden email]> wrote:

    <script>
"use strict"
function A() {}
    </script>
    <script>
function B() {}
    </script>
    <script>
window.onload = function() {
    let a = Reflect.ownKeys(A);
    let b = Reflect.ownKeys(B);
    document.getElementById("output").value = (a.includes("arguments") === b.includes("arguments"));
}
    </script>

Mozilla Firefox reports true. Google Chrome and node.js report false.  Which one is correct?

I looked through Mozilla's Bugzilla, Google Chrome's Monorail, and the ES7 spec to try figuring this out.  The closest I could get was section 9.2.7 of the ES7 spec. [1]

Right now I have an inadvertent mix of strict code / non-strict code in my membrane, and this difference is causing my most recent patch to fail tests in nodejs and Google Chrome, and to pass in Mozilla Firefox.  In Chrome and nodejs, I get:

TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'

If it turns out Google & nodejs are correct, this could be an issue going forward:  I can't control whether my membrane library's users are running strict mode code or not... likewise, I don't know if my code should be consistently strict mode or consistently non-strict.  (I feel that a mix is not good, except for finding bugs like this...)

My apologies for treating this list as a help forum, but I'm just not sure where else to go...
--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Caitlin Potter
In reply to this post by Alex Vincent
Web compat enforces adding them in sloppy mode. My understanding of what he’s saying is that V8 “incorrectly” omits these own properties from strict functions, which is correct per spec.

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Caitlin Potter
In reply to this post by Oriol _
Ah, my bad, you’re right — they only expose the accessors on the prototype, so they’re in the clear. But yeah, there’s no requirement one way or the other (other than re: web compat) for the properties being there in sloppy mode.

On Sep 5, 2016, at 9:20 PM, Oriol Bugzilla <[hidden email]> wrote:

> Mozilla's approach violates ECMAScript's forbidden extensions and can't be considered "correct"

Why? The spec forbids adding "caller" or "arguments" in strict mode. I think it does not enforce adding them in sloppy mode.

Chrome seems to add them only in sloppy mode, and Firefox to never add them. So I think both follow the spec.

- Oriol
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

signature.asc (859 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Alex Vincent
In reply to this post by Mark S. Miller-2
Ugh!!  It's a trap!  (In the Star Wars sense, not the proxy sense.)

So if all my code is in strict mode, and I get a non-strict code function to shadow as Tom and I were talking about in another thread... how do I even test for that if my code is either consistently strict or consistently non-strict?

On Mon, Sep 5, 2016 at 6:21 PM, Mark S. Miller <[hidden email]> wrote:
Besides those two, the only other reference to AddRestrictedFunctionProperties is <http://www.ecma-international.org/ecma-262/7.0/#sec-createintrinsics> step 12:

12. Perform AddRestrictedFunctionProperties(funcProtorealmRec).

So .caller and .arguments must now exist as poisoned on (the intrinsic normally bound to) Function.prototype . So, besides Function.prototype, they may only appear on old-style sloppy functions; nowhere else.



On Mon, Sep 5, 2016 at 6:09 PM, Caitlin Potter <[hidden email]> wrote:

This forbids functions in strict code from having own properties "caller" or "arguments". Newer function kinds have these restrictions in sloppy mode.

AddRestricted... adds the accessor which makes getting/setting "caller" or "arguments" throw, but is per spec only performed on intrinsics (like %FunctionPrototype%).

So unfortunately, this is something your membrane would need to be aware of and work around. Mozilla's approach violates ECMAScript's forbidden extensions and can't be considered "correct"

This result by itself does not demonstrate that Mozilla or v8 are either conformant or non-conformant. By the spec, A must not have its own .caller and .arguments -- it must only inherit these from Function.prototype. B, being sloppy, may or may not.

 


Sent from my iPhone
On Sep 5, 2016, at 8:54 PM, Alex Vincent <[hidden email]> wrote:

    <script>
"use strict"
function A() {}
    </script>
    <script>
function B() {}
    </script>
    <script>
window.onload = function() {
    let a = Reflect.ownKeys(A);
    let b = Reflect.ownKeys(B);
    document.getElementById("output").value = (a.includes("arguments") === b.includes("arguments"));
}
    </script>

Mozilla Firefox reports true. Google Chrome and node.js report false.  Which one is correct?

I looked through Mozilla's Bugzilla, Google Chrome's Monorail, and the ES7 spec to try figuring this out.  The closest I could get was section 9.2.7 of the ES7 spec. [1]

Right now I have an inadvertent mix of strict code / non-strict code in my membrane, and this difference is causing my most recent patch to fail tests in nodejs and Google Chrome, and to pass in Mozilla Firefox.  In Chrome and nodejs, I get:

TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'

If it turns out Google & nodejs are correct, this could be an issue going forward:  I can't control whether my membrane library's users are running strict mode code or not... likewise, I don't know if my code should be consistently strict mode or consistently non-strict.  (I feel that a mix is not good, except for finding bugs like this...)

My apologies for treating this list as a help forum, but I'm just not sure where else to go...
--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




--
    Cheers,
    --MarkM



--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Oriol _
> So if all my code is in strict mode, and I get a non-strict code function to shadow as Tom and I were talking about in another thread... how do I even test for that if my code is either consistently strict or consistently non-strict?

Don't check that. The target could have other non-configurable properties added by the user anyway.

So just include the non-configurable own properties of the target in the property list returned by the trap.

Also consider using your own function as the target instead of the function provided by the user. This way you can be sure it will be a strict mode function, it will be extensible, and won't have any additional non-configurable own property. Then you will have less problems with proxy invariants.

-Oriol


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Bug: Reflect.ownKeys(function() {}) differs in V8 strict mode than other cases

Alex Vincent
In reply to this post by Mark S. Miller-2
Based on your feedback, I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1300793 .  Thanks for your help.

On Mon, Sep 5, 2016 at 6:21 PM, Mark S. Miller <[hidden email]> wrote:
Besides those two, the only other reference to AddRestrictedFunctionProperties is <http://www.ecma-international.org/ecma-262/7.0/#sec-createintrinsics> step 12:

--
"The first step in confirming there is a bug in someone else's work is confirming there are no bugs in your own."
-- Alexander J. Vincent, June 30, 2001

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss