Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1309)

Unified Diff: test/cctest/test-api-interceptors.cc

Issue 2331223004: [api] Throw in defineProperty() when necessary. (Closed)
Patch Set: Fix formatting. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/cctest/test-api-interceptors.cc
diff --git a/test/cctest/test-api-interceptors.cc b/test/cctest/test-api-interceptors.cc
index ae96b1de4422a7cc125bd953f9699a7843c42a74..dd632e093e6ea6dc3d5ac8f3690a2d2db0c5568b 100644
--- a/test/cctest/test-api-interceptors.cc
+++ b/test/cctest/test-api-interceptors.cc
@@ -488,11 +488,6 @@ void GetterCallback(Local<Name> property,
get_was_called = true;
}
-void SetterCallback(Local<Name> property, Local<Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- set_was_called = true;
-}
-
} // namespace
// Check that get callback is called in defineProperty with accessor descriptor.
@@ -501,7 +496,7 @@ THREADED_TEST(DefinerCallbackAccessorInterceptor) {
v8::Local<v8::FunctionTemplate> templ =
v8::FunctionTemplate::New(CcTest::isolate());
templ->InstanceTemplate()->SetHandler(
- v8::NamedPropertyHandlerConfiguration(GetterCallback, SetterCallback));
+ v8::NamedPropertyHandlerConfiguration(GetterCallback));
LocalContext env;
env->Global()
->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
@@ -511,13 +506,11 @@ THREADED_TEST(DefinerCallbackAccessorInterceptor) {
.FromJust();
CHECK_EQ(get_was_called, false);
- CHECK_EQ(set_was_called, false);
v8_compile("Object.defineProperty(obj, 'x', {set: function() {return 17;}});")
->Run(env.local())
.ToLocalChecked();
CHECK_EQ(get_was_called, true);
- CHECK_EQ(set_was_called, false);
}
bool get_was_called_in_order = false;
@@ -547,7 +540,7 @@ THREADED_TEST(DefinerCallbackGetAndDefine) {
v8::Local<v8::FunctionTemplate> templ =
v8::FunctionTemplate::New(CcTest::isolate());
templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
- GetterCallbackOrder, SetterCallback, 0, 0, 0, DefinerCallbackOrder));
+ GetterCallbackOrder, 0, 0, 0, 0, DefinerCallbackOrder));
LocalContext env;
env->Global()
->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
@@ -1322,6 +1315,74 @@ THREADED_TEST(NamedPropertyHandlerGetter) {
.FromJust());
}
+// See https://bugs.chromium.org/p/chromium/issues/detail?id=645542
+THREADED_TEST(PropertySetterCallbackPresentDuringDefineProperty) {
+ { // defineProperty with a data descriptor is OK in presence of named
+ // setter callback.
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+ templ->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(0, EmptyInterceptorSetter));
+ env->Global()
+ ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
+ .ToLocalChecked()
+ ->NewInstance(env.local())
+ .ToLocalChecked())
+ .FromJust();
+ const char* code =
+ "Object.defineProperty(obj, 'x', {value: 42});"
+ "obj.x;";
+ CHECK_EQ(42, v8_compile(code)
+ ->Run(env.local())
+ .ToLocalChecked()
+ ->Int32Value(env.local())
+ .FromJust());
+ }
+
+ { // defineProperty with a descriptor that is not a data descriptor should
+ // throw if object has a
+ // named setter callback.
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+ templ->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(0, EmptyInterceptorSetter));
+ env->Global()
+ ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
+ .ToLocalChecked()
+ ->NewInstance(env.local())
+ .ToLocalChecked())
+ .FromJust();
+
+ v8::TryCatch try_catch(env->GetIsolate());
+ CompileRun("Object.defineProperty(obj, 'x', {get: function() {}});");
+ CHECK(try_catch.HasCaught());
+ }
+
+ { // defineProperty with a descriptor that is not a data descriptor, e.g.,
+ // empty descriptor, should throw if object has a named setter callback.
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+ templ->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(0, EmptyInterceptorSetter));
+ env->Global()
+ ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
+ .ToLocalChecked()
+ ->NewInstance(env.local())
+ .ToLocalChecked())
+ .FromJust();
+
+ v8::TryCatch try_catch(env->GetIsolate());
+ CompileRun("Object.defineProperty(obj, 'x', {});");
+ CHECK(try_catch.HasCaught());
+ }
+}
+
namespace {
void NotInterceptingPropertyDefineCallback(
Local<Name> name, const v8::PropertyDescriptor& desc,
@@ -2206,7 +2267,7 @@ THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) {
THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
v8::HandleScope scope(CcTest::isolate());
Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ AddInterceptor(templ, InterceptorGetter, nullptr);
LocalContext env;
env->Global()
->Set(env.local(), v8_str("Obj"),
@@ -2219,8 +2280,6 @@ THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
"function setAge(i) { obj.age = i; };"
"Object.defineProperty(obj, 'age', { get:getter, set:setter });"
"for(var i = 0; i <= 10000; i++) setAge(i);");
- // All i < 10000 go to the interceptor.
- ExpectInt32("obj.interceptor_age", 9999);
// The last i goes to the JavaScript accessor.
ExpectInt32("obj.accessor_age", 10000);
// The installed JavaScript getter is still intact.
@@ -2235,7 +2294,7 @@ THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
THREADED_TEST(SwitchFromJSAccessorToInterceptor) {
v8::HandleScope scope(CcTest::isolate());
Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ AddInterceptor(templ, InterceptorGetter, nullptr);
LocalContext env;
env->Global()
->Set(env.local(), v8_str("Obj"),
@@ -2248,14 +2307,8 @@ THREADED_TEST(SwitchFromJSAccessorToInterceptor) {
"function setAge(i) { obj.age = i; };"
"Object.defineProperty(obj, 'age', { get:getter, set:setter });"
"for(var i = 20000; i >= 9999; i--) setAge(i);");
- // All i >= 10000 go to the accessor.
- ExpectInt32("obj.accessor_age", 10000);
- // The last i goes to the interceptor.
- ExpectInt32("obj.interceptor_age", 9999);
- // The installed JavaScript getter is still intact.
- // This last part is a regression test for issue 1651 and relies on the fact
- // that both interceptor and accessor are being installed on the same object.
- ExpectInt32("obj.age", 10000);
+ ExpectInt32("obj.accessor_age", 9999);
+ ExpectInt32("obj.age", 9999);
ExpectBoolean("obj.hasOwnProperty('age')", true);
ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value");
}
@@ -2491,22 +2544,12 @@ static void IndexedPropertyGetter(
}
-static void IndexedPropertySetter(
- uint32_t index, Local<Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- ApiTestFuzzer::Fuzz();
- if (index == 39) {
- info.GetReturnValue().Set(value);
- }
-}
-
-
THREADED_TEST(IndexedInterceptorWithIndexedAccessor) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
- IndexedPropertyGetter, IndexedPropertySetter));
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IndexedPropertyGetter, nullptr));
LocalContext context;
context->Global()
->Set(context.local(), v8_str("obj"),
@@ -2518,17 +2561,11 @@ THREADED_TEST(IndexedInterceptorWithIndexedAccessor) {
"obj.__defineSetter__(\"17\", function(val){this.foo = val;});"
"obj[17] = 23;"
"obj.foo;");
- Local<Script> interceptor_setter_script = v8_compile(
- "obj.__defineSetter__(\"39\", function(val){this.foo = \"hit\";});"
- "obj[39] = 47;"
- "obj.foo;"); // This setter should not run, due to the interceptor.
Local<Script> interceptor_getter_script = v8_compile("obj[37];");
Local<Value> result = getter_script->Run(context.local()).ToLocalChecked();
CHECK(v8_num(5)->Equals(context.local(), result).FromJust());
result = setter_script->Run(context.local()).ToLocalChecked();
CHECK(v8_num(23)->Equals(context.local(), result).FromJust());
- result = interceptor_setter_script->Run(context.local()).ToLocalChecked();
- CHECK(v8_num(23)->Equals(context.local(), result).FromJust());
result = interceptor_getter_script->Run(context.local()).ToLocalChecked();
CHECK(v8_num(625)->Equals(context.local(), result).FromJust());
}
@@ -3964,7 +4001,7 @@ THREADED_TEST(CrankshaftInterceptorSetter) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope scope(CcTest::isolate());
Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate());
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ AddInterceptor(templ, InterceptorGetter, nullptr);
LocalContext env;
env->Global()
->Set(env.local(), v8_str("Obj"),
@@ -3984,9 +4021,8 @@ THREADED_TEST(CrankshaftInterceptorSetter) {
"setAge(3);"
"%OptimizeFunctionOnNextCall(setAge);"
"setAge(4);");
- // All stores went through the interceptor.
- ExpectInt32("obj.interceptor_age", 4);
- ExpectInt32("obj.accessor_age", 42);
+ ExpectUndefined("obj.interceptor_age");
+ ExpectInt32("obj.accessor_age", 4);
}

Powered by Google App Engine
This is Rietveld 408576698