Skip to content

Change from 0.10 => 1.2; enumerable of this.escape in vm.runInNewContext was false, now true #864

Description

@smikes

Here's the behavior from node 0.10:

$ node -p 'require("vm").runInNewContext("Object.getOwnPropertyDescriptor(this,\"escape\")", {})'
{ value: [Function: escape],
  writable: true,
  enumerable: false,
  configurable: true }

And in io.js@1.2.0:

$ nvm use 1.2
Now using io.js v1.2.0
$ node -p 'require("vm").runInNewContext("Object.getOwnPropertyDescriptor(this,\"escape\")", {})'
{ value: [Function: escape],
  writable: true,
  enumerable: true,
  configurable: true }

Is this an intentional change? Is it documented anywhere? FWIW this is present in node@0.11 as well

Activity

  1. anba commented on Feb 17, 2015

    @anba

    I guess this is related to https://code.google.com/p/v8/issues/detail?id=3861. GetOwnPropertyNames() is called here.

  2. smikes commented on Feb 17, 2015

    @smikes
    ContributorAuthor

    Testing with cloneProperty in the REPL correctly generates an escape with enumerable: false:

    > c = require('./cloneProperty')
    [Function: cloneProperty]
    > s = {}
    {}
    > c(global, "escape", s)
    undefined
    > s
    {}
    > Object.getOwnPropertyDescriptor(s, "escape")
    { value: [Function: escape],
      writable: true,
      enumerable: false,
      configurable: true }
    

    where cloneProperty.js is:

    function cloneProperty(source, key, target) {
                    if (key === 'Proxy') return;
                    try {
                      var desc = Object.getOwnPropertyDescriptor(source, key);
                      if (desc.value === source) desc.value = target;
                      Object.defineProperty(target, key, desc);
                    } catch (e) {
                     // Catch sealed properties errors
                    }
                  }
    
    module.exports = cloneProperty;
    
  3. bnoordhuis commented on Feb 17, 2015

    @bnoordhuis
    Member

    I suspect that's caused by the named property interceptor for the global object here.

    if (!in_sandbox || !in_proxy_global) {
      args.GetReturnValue().Set(None);
    }

    Not sure what the best way to fix it is. The interceptor needs to retrieve the actual property attributes somehow without causing infinite recursion.

  4. added
    vmIssues and PRs related to the vm subsystem.
    on Feb 17, 2015
  5. added a commit that references this issue on Feb 19, 2015
  6. smikes commented on Feb 19, 2015

    @smikes
    ContributorAuthor

    @boordhuis - Indeed, getting attributes for properties of the global is tricky. I have a PR (#885) for the sandbox side, which was easy.

    I tried something like this:

        Local<Context> context = PersistentToLocal(isolate, ctx->context_);
        attr = context->Global()->GetPropertyAttributes(property);
    

    But that set off an infinite recursion, as you predicted. Any suggestions?

  7. bnoordhuis commented on Feb 19, 2015

    @bnoordhuis
    Member

    @smikes I commented on that here. It looks like V8 needs to grow some new APIs to fix this issue. I have it on my radar but I'm stretched rather thin at the moment.

  8. bnoordhuis commented on Feb 20, 2015

    @bnoordhuis
    Member
  9. Fishrock123 commented on Mar 6, 2015

    @Fishrock123
    Contributor

    Looks like the v8 patch landed.

  10. domenic commented on Jun 5, 2015

    @domenic
    Contributor

    This can be closed as it's fixed in next.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions