Commit cfd41720 authored by cbruni's avatar cbruni Committed by Commit bot

[runtime-object]: part fix element key list on global object

BUG=v8:2764
LOG=N
R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/1378323003

Cr-Commit-Position: refs/heads/master@{#31099}
parent f3f940f4
...@@ -896,11 +896,23 @@ RUNTIME_FUNCTION(Runtime_GetOwnElementNames) { ...@@ -896,11 +896,23 @@ RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
if (!args[0]->IsJSObject()) { if (!args[0]->IsJSObject()) {
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
} }
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
// TODO(cbruni): implement proper prototype lookup like in GetOwnPropertyNames
if (object->IsJSGlobalProxy()) {
// All the elements are stored on the globa_object and not directly on the
// global object proxy.
PrototypeIterator iter(isolate, object,
PrototypeIterator::START_AT_PROTOTYPE);
if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
return *isolate->factory()->NewJSArray(0);
}
object = PrototypeIterator::GetCurrent<JSObject>(iter);
}
int n = obj->NumberOfOwnElements(NONE); int n = object->NumberOfOwnElements(NONE);
Handle<FixedArray> names = isolate->factory()->NewFixedArray(n); Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
obj->GetOwnElementKeys(*names, NONE); object->GetOwnElementKeys(*names, NONE);
return *isolate->factory()->NewJSArrayWithElements(names); return *isolate->factory()->NewJSArrayWithElements(names);
} }
......
...@@ -25,10 +25,15 @@ ...@@ -25,10 +25,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/api.h"
#include "src/v8.h" #include "src/v8.h"
#include "test/cctest/cctest.h" #include "test/cctest/cctest.h"
using ::v8::Array;
using ::v8::Context;
using ::v8::Local;
using ::v8::Value;
// This test fails if properties on the prototype of the global object appear // This test fails if properties on the prototype of the global object appear
// as declared globals. // as declared globals.
TEST(StrictUndeclaredGlobalVariable) { TEST(StrictUndeclaredGlobalVariable) {
...@@ -47,3 +52,48 @@ TEST(StrictUndeclaredGlobalVariable) { ...@@ -47,3 +52,48 @@ TEST(StrictUndeclaredGlobalVariable) {
v8::String::Utf8Value exception(try_catch.Exception()); v8::String::Utf8Value exception(try_catch.Exception());
CHECK_EQ(0, strcmp("ReferenceError: x is not defined", *exception)); CHECK_EQ(0, strcmp("ReferenceError: x is not defined", *exception));
} }
TEST(KeysGlobalObject_Regress2764) {
LocalContext env1;
v8::HandleScope scope(env1->GetIsolate());
// Create second environment.
v8::Handle<Context> env2 = Context::New(env1->GetIsolate());
Local<Value> token = v8_str("foo");
// Set same security token for env1 and env2.
env1->SetSecurityToken(token);
env2->SetSecurityToken(token);
// Create a reference to env2 global from env1 global.
env1->Global()->Set(v8_str("global2"), env2->Global());
// Set some global variables in global2
env2->Global()->Set(v8_str("a"), v8_str("a"));
env2->Global()->Set(v8_str("42"), v8_str("42"));
// List all entries from global2.
Local<Array> result;
result = Local<Array>::Cast(CompileRun("Object.keys(global2)"));
CHECK_EQ(2u, result->Length());
CHECK(v8_str("42")->Equals(result->Get(0)));
CHECK(v8_str("a")->Equals(result->Get(1)));
result =
Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)"));
CHECK_LT(2u, result->Length());
// Check that all elements are in the property names
ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('42')");
ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('a')");
// Hold on to global from env2 and detach global from env2.
env2->DetachGlobal();
// List again all entries from the detached global2.
result = Local<Array>::Cast(CompileRun("Object.keys(global2)"));
CHECK_EQ(0u, result->Length());
result =
Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)"));
CHECK_EQ(0u, result->Length());
}
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var global = this;
function testNamedProperty(key, value) {
global[key] = value;
assertTrue(global.hasOwnProperty(key));
assertTrue(-1 < Object.keys(global).indexOf(key));
assertTrue(-1 < Object.getOwnPropertyNames(global).indexOf(key));
assertTrue(-1 == Object.getOwnPropertySymbols(global).indexOf(key));
}
testNamedProperty('property0', 'value');
testNamedProperty('0property', 'value');
testNamedProperty('42', 'value');
function testNamedNonEnumerableProperty(key, value) {
Object.defineProperty(global, key, {
enumerable: false,
value: value
});
assertTrue(global.hasOwnProperty(key));
assertTrue(-1 == Object.keys(global).indexOf(key));
assertTrue(-1 < Object.getOwnPropertyNames(global).indexOf(key));
assertTrue(-1 == Object.getOwnPropertySymbols(global).indexOf(key));
}
testNamedNonEnumerableProperty('property1', 'value');
testNamedNonEnumerableProperty('1property', 'value');
testNamedNonEnumerableProperty('43', 'value');
function testSymbolProperty(key, value) {
key = Symbol(key);
global[key] = value;
assertTrue(global.hasOwnProperty(key));
assertTrue(-1 == Object.keys(global).indexOf(key));
assertTrue(-1 == Object.getOwnPropertyNames(global).indexOf(key));
assertTrue(-1 < Object.getOwnPropertySymbols(global).indexOf(key));
}
testSymbolProperty('property2', 'value');
testSymbolProperty('2property', 'value');
testSymbolProperty('43', 'value');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment